From e0b6103458d3deab62e0e03d74c58b28edd35bbb Mon Sep 17 00:00:00 2001 From: Claude BM Date: Sun, 26 Apr 2026 13:19:49 +0000 Subject: [PATCH] Add suggestions section to CI failure HTML report + dark mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When CI fails, the HTML report now includes a "Suggestions" section that analyzes failure patterns and provides actionable fix hints: - Feature manifest path mismatches - Import/module errors → pip install - Auth failures → missing JWT cookie - Route 404s → endpoint moved/renamed - Test count regression → baseline drift - Package check failures → missing deps - Collection errors → broken conftest/syntax Also converted the report to dark mode per golden rule. Co-Authored-By: Claude Opus 4.6 (1M context) --- ci-runner.sh | 74 ++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 58 insertions(+), 16 deletions(-) diff --git a/ci-runner.sh b/ci-runner.sh index 9093396..ed40afa 100755 --- a/ci-runner.sh +++ b/ci-runner.sh @@ -202,6 +202,41 @@ for item in error_items: detail_block = html.escape(failure_details) if failure_details.strip() else 'No detailed output captured' pkg_block = html.escape(pkg_output) if pkg_output.strip() else '' ts = datetime.now(timezone.utc).strftime('%Y-%m-%d %H:%M UTC') +baseline = '$BASELINE' + +# Generate suggestions based on failure patterns +tips = [] +all_output = failure_details + ' ' + features + ' ' + pkg_output +if 'MISSING' in features and 'features verified' in features: + tips.append(('Feature Manifest', 'One or more feature patterns were not found in the expected files. This usually means code was moved or renamed during a refactor. Check .features/*.manifest and update the file paths to match where the code lives now.')) +if int(failed) > 0: + if 'ImportError' in all_output or 'ModuleNotFoundError' in all_output: + tips.append(('Import Error', 'A test failed because a module could not be imported. A file may have been renamed, moved, or a dependency is missing from the venv. Run: pip install -r requirements.txt')) + if 'AssertionError' in all_output or 'assert' in all_output: + tips.append(('Assertion Failure', 'A test assertion did not match expected values. Check if the API response shape changed, a default value was modified, or test fixtures are stale.')) + if '401' in all_output or 'Unauthorized' in all_output: + tips.append(('Auth Failure', 'A test got 401 Unauthorized. The endpoint may have been put behind authentication, or the test client is missing a JWT cookie.')) + if '404' in all_output: + tips.append(('Route Not Found', 'A test got 404. The endpoint may have been renamed, moved to a different router, or removed entirely.')) + if '500' in all_output or 'Internal Server Error' in all_output: + tips.append(('Server Error', 'A test triggered a 500 error. Check the backend logs for the full traceback: journalctl -u tsharp-scheduler --since \"5 minutes ago\"')) +if int(errors) > 0: + if 'fixture' in all_output.lower(): + tips.append(('Fixture Error', 'A test fixture failed during setup. A conftest.py fixture may be broken or a required package (pytest-mock, pytest-asyncio, pytest-timeout) may be missing.')) + if 'collection' in all_output.lower(): + tips.append(('Collection Error', 'pytest failed to collect tests. A test file may have a syntax error or a top-level import that crashes.')) +if baseline and int(passed) < int(baseline) and int(passed) > 0: + diff = int(baseline) - int(passed) + tips.append(('Test Count Regression', f'{diff} fewer tests passed than the baseline ({baseline}). Tests may have been deleted, moved out of backend/tests/, or a new skip/deselect was introduced without updating the baseline.')) +if 'FAIL' in pkg_output: + tips.append(('Missing Package', 'One or more required Python packages are not installed. Run: source .venv/bin/activate && pip install -r requirements.txt')) +if not tips: + tips.append(('Unknown', 'No specific pattern matched. Check the failure details above and the backend logs for more context.')) + +suggestions = '' report = f''' @@ -210,26 +245,28 @@ report = f''' CI Failure Report — {html.escape(branch)} ({html.escape(commit)}) @@ -262,6 +299,11 @@ report = f'''

Failure Details

{detail_block}
+

Suggestions

+
+{suggestions} +
+
Generated by TSHARPS CI Runner — {ts}
'''