Skip to content

fuck it yolo merge to mommy #10

fuck it yolo merge to mommy

fuck it yolo merge to mommy #10

name: HTML and CSS Validation
on:
pull_request:
paths:
- '**/*.html'
- '**/*.htm'
- '**/*.xhtml'
- '**/*.xht'
jobs:
validate-html:
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Get changed files
id: changed-files
run: |
FILES=$(git diff --name-only origin/${{ github.base_ref }} ${{ github.sha }} | grep -E '\.(html|htm|xhtml|xht|css)$' || true)
echo "$FILES" > changed_files.txt
if [ -s changed_files.txt ]; then
echo "has_changes=true" >> $GITHUB_OUTPUT
else
echo "has_changes=false" >> $GITHUB_OUTPUT
fi
- name: Set up Java
if: steps.changed-files.outputs.has_changes == 'true'
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '17'
- name: Download vnu.jar
if: steps.changed-files.outputs.has_changes == 'true'
run: |
wget -O vnu.jar https://github.com/validator/validator/releases/download/latest/vnu.jar
- name: Validate HTML and CSS
if: steps.changed-files.outputs.has_changes == 'true'
id: validation
continue-on-error: true
run: |
mkdir -p validation
echo '{"messages":[]}' > validation/errors.json
TEMP_LOG="validation/temp.json"
ALL_ERRORS="validation/errors.json"
while IFS= read -r file; do
if [ -f "$file" ]; then
echo "Validating file: $file"
# Validate single file
java -jar vnu.jar --format json --also-check-css "$file" > "$TEMP_LOG" 2>&1 || true
# Add the full file path to each message before merging
if [ -f "$TEMP_LOG" ] && [ -s "$TEMP_LOG" ]; then
jq --arg filepath "$file" '.messages = (.messages | map(. + {"filepath": $filepath}))' "$TEMP_LOG" > "validation/temp_with_path.json"
jq -s '.[0].messages + .[1].messages | {messages: .}' "$ALL_ERRORS" "validation/temp_with_path.json" > "validation/combined.json"
mv "validation/combined.json" "$ALL_ERRORS"
fi
fi
done < changed_files.txt
# Check if we have any actual errors or warnings (excluding pure info messages)
ISSUES=$(jq '[.messages[] | select(.type == "error" or (type == "info" and .subType == "warning"))] | length' "$ALL_ERRORS")
if [ "$ISSUES" -gt 0 ]; then
echo "has_errors=true" >> $GITHUB_OUTPUT
else
echo "has_errors=false" >> $GITHUB_OUTPUT
fi
- name: Post validation results
if: steps.changed-files.outputs.has_changes == 'true'
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const hasErrors = '${{ steps.validation.outputs.has_errors }}' === 'true';
let commentBody = '## HTML Validation Results\n\n';
if (hasErrors) {
try {
const data = JSON.parse(fs.readFileSync('validation/errors.json', 'utf8'));
// Filter messages to only include errors and warnings
const significantMessages = data.messages.filter(msg =>
msg.type === 'error' || (msg.type === 'info' && msg.subType === 'warning')
);
// Group messages by filepath
const groupedByFile = significantMessages.reduce((acc, msg) => {
const filepath = msg.filepath || msg.url.split('/').pop();
if (!acc[filepath]) acc[filepath] = [];
acc[filepath].push(msg);
return acc;
}, {});
if (Object.keys(groupedByFile).length > 0) {
commentBody += '❌ Validation found the following issues:\n\n';
for (const [filepath, messages] of Object.entries(groupedByFile)) {
if (messages.length === 0) continue; // Skip files with no significant messages
commentBody += `### ${filepath}\n\n`;
// Group similar errors within each file
const errorGroups = messages.reduce((groups, msg) => {
// Create a key based on just the error message
const key = msg.message;
if (!groups[key]) {
groups[key] = {
message: msg,
count: 0,
lines: new Set()
};
}
groups[key].count++;
groups[key].lines.add(msg.lastLine);
return groups;
}, {});
// Output grouped errors
for (const group of Object.values(errorGroups)) {
const type = group.message.type === 'error' ? '🔴' : '⚠️';
const lines = Array.from(group.lines).sort((a, b) => a - b);
const lineStr = lines.length === 1
? `Line ${lines[0]}`
: `Lines ${lines.join(', ')}`;
commentBody += `${type} **${lineStr}:** ${group.message.message}\n\n`;
}
}
commentBody += '\nPlease fix these issues before merging.';
} else {
commentBody += '✅ No significant issues found!';
}
} catch (e) {
commentBody += '⚠️ Error parsing validation results. Please check the workflow logs.\n';
console.error(e);
}
} else {
commentBody += '✅ All HTML and CSS validates successfully!';
}
const comments = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
});
const botComment = comments.data.find(comment =>
comment.user.type === 'Bot' &&
comment.body.includes('HTML Validation Results')
);
if (botComment) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: botComment.id,
body: commentBody
});
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: commentBody
});
}
- name: Exit with error if validation failed
if: steps.validation.outputs.has_errors == 'true'
run: |
if [ -f validation/errors.json ]; then
ERRORS=$(jq '[.messages[] | select(.type == "error")] | length' validation/errors.json)
if [ "$ERRORS" -gt 0 ]; then
exit 1
fi
fi