fix(ci): resolve link validation workflow false failures

- Fix GitHub Actions exit logic to only fail when broken links exist
- Improve Cypress test error handling with robust fallback mechanism
- Enhance Test Setup Validation to handle cache scenarios correctly

The workflow was incorrectly failing when generating success comments
with cache statistics, treating any comment generation as broken links.
Now properly distinguishes between success messages and actual failures.
pull/6260/head
Jason Stirnaman 2025-07-28 22:35:50 -05:00
parent a087906b83
commit 02efdb262b
3 changed files with 49 additions and 9 deletions

View File

@ -44,12 +44,18 @@ runs:
# Check if comment file was created and has content
if [[ -f comment.md && -s comment.md ]]; then
echo "has-broken-links=true" >> $GITHUB_OUTPUT
echo "comment-generated=true" >> $GITHUB_OUTPUT
# Count broken links by parsing the comment
broken_count=$(grep -o "Found [0-9]* broken link" comment.md | grep -o "[0-9]*" || echo "0")
echo "broken-link-count=$broken_count" >> $GITHUB_OUTPUT
echo "comment-generated=true" >> $GITHUB_OUTPUT
# Check if there are actually broken links (not just a success comment)
if [[ "$broken_count" -gt 0 ]]; then
echo "has-broken-links=true" >> $GITHUB_OUTPUT
else
echo "has-broken-links=false" >> $GITHUB_OUTPUT
fi
else
echo "has-broken-links=false" >> $GITHUB_OUTPUT
echo "broken-link-count=0" >> $GITHUB_OUTPUT

1
broken_links_report.json Normal file
View File

@ -0,0 +1 @@
[]

View File

@ -76,9 +76,25 @@ describe('Article', () => {
);
cy.log(' Check that all files exist and are readable');
Cypress.fail(
`Incremental validation task failed: ${error.message}. Check logs for details.`
// Instead of failing completely, fall back to testing all provided subjects
cy.log(
'🔄 Falling back to test all provided subjects without cache optimization'
);
// Reset validation strategy to indicate fallback mode
validationStrategy = {
fallback: true,
error: error.message,
unchanged: [],
changed: sourceFilePaths.map((filePath) => ({
filePath,
error: 'fallback',
})),
total: sourceFilePaths.length,
};
// Keep original subjects for testing (should come from test_subjects env var)
cy.log(`📋 Testing ${subjects.length} pages in fallback mode`);
});
});
@ -194,8 +210,19 @@ describe('Article', () => {
cy.log(` • Test subjects count: ${subjects.length}`);
cy.log(` • Validation strategy: ${validationStrategy || 'Not set'}`);
if (subjects.length === 0) {
cy.log('⚠️ No test subjects found - this may indicate:');
// Check if we're in fallback mode due to cache system issues
if (validationStrategy && validationStrategy.fallback) {
cy.log('⚠️ Running in fallback mode due to cache system error');
cy.log(` • Error: ${validationStrategy.error}`);
cy.log(' • All files will be tested without cache optimization');
// Ensure we have subjects to test in fallback mode
expect(subjects.length).to.be.greaterThan(
0,
'Should have test subjects in fallback mode'
);
} else if (subjects.length === 0) {
cy.log('⚠️ No test subjects found - analyzing cause:');
cy.log(' • All files were cached and skipped');
cy.log(' • No files matched the test criteria');
cy.log(' • File mapping failed during setup');
@ -203,11 +230,14 @@ describe('Article', () => {
// Don't fail if this is expected (cache hit scenario)
const testSubjectsData = Cypress.env('test_subjects_data');
if (testSubjectsData) {
cy.log(
' Test subjects data is available, cache optimization likely active'
);
cy.log('✅ Cache optimization active - this is expected');
cy.log(' Test subjects data is available, all files cached');
} else {
cy.log('❌ No test subjects data available - potential setup issue');
// Only fail if we have no data and no subjects - indicates a real problem
expect(testSubjectsData).to.not.be.empty(
'Should have test subjects data when no subjects to test'
);
}
} else {
cy.log(`✅ Ready to test ${subjects.length} pages`);
@ -216,6 +246,9 @@ describe('Article', () => {
cy.log(` ... and ${subjects.length - 5} more pages`);
}
}
// Always pass if we get to this point - the setup is valid
cy.log('✅ Test setup validation completed successfully');
});
subjects.forEach((subject) => {