From ebe5421addeb5d7448fa997ab46e351eee4067d9 Mon Sep 17 00:00:00 2001 From: StackRox Automation Date: Thu, 21 May 2026 01:41:26 +0000 Subject: [PATCH 1/4] Add AI-powered test failure analysis with Claude Code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Automatically analyzes integration test failures using Claude AI and includes intelligent insights in Slack notifications to #team-acs-collector-oncall. Key features: - Claude has full source code access via claude-code-base-action - Analyzes JUnit XML reports, failing test source, and git history - Detects platform-specific patterns (arch/OS) - Provides file:line precision and actionable recommendations - Skill-based approach (.claude/commands/) for maintainability - Graceful fallback if analysis fails - Test with PR label without Slack spam Architecture: - Integration tests fail → collect-failures job identifies failures - analyze-and-notify reusable workflow runs Claude skill - Claude creates analysis-report.md with root cause analysis - notify job posts to Slack (skipped for PR label tests) Co-Authored-By: Claude Sonnet 4.5 --- .claude/commands/analyze-test-failures.md | 115 +++++++++++ .github/actionlint.yaml | 4 + .github/scripts/README.md | 232 ++++++++++++++++++++++ .github/workflows/analyze-and-notify.yml | 151 ++++++++++++++ .github/workflows/integration-tests.yml | 40 ++-- 5 files changed, 530 insertions(+), 12 deletions(-) create mode 100644 .claude/commands/analyze-test-failures.md create mode 100644 .github/actionlint.yaml create mode 100644 .github/scripts/README.md create mode 100644 .github/workflows/analyze-and-notify.yml diff --git a/.claude/commands/analyze-test-failures.md b/.claude/commands/analyze-test-failures.md new file mode 100644 index 0000000000..fd594749c0 --- /dev/null +++ b/.claude/commands/analyze-test-failures.md @@ -0,0 +1,115 @@ +--- +name: analyze-test-failures +description: Analyze test failure artifacts and generate root cause analysis report +--- + +# Test Failure Analysis + +Analyze test failures from CI artifacts and generate a concise root cause analysis for the oncall team. + +## Usage + +``` +/analyze-test-failures +``` + +**Arguments:** +- `artifacts-dir`: Directory containing test artifacts (default: test-artifacts/) +- `workflow-name`: Name of the workflow that failed (e.g., "Integration Tests") +- `failed-jobs`: Comma-separated list of failed job names + +**Example:** +``` +/analyze-test-failures test-artifacts/ "Integration Tests" "amd64-integration-tests,arm64-integration-tests" +``` + +## What This Does + +1. **Find test reports**: Searches for JUnit XML files (integration-test-report-*.xml, junit.xml) +2. **Parse failures**: Extracts test names, error messages, stack traces +3. **Investigate code**: Reads failing test source and implementation code +4. **Check git history**: Looks for recent changes that may have caused failures +5. **Identify patterns**: Detects platform-specific issues (arch/OS) +6. **Generate report**: Creates analysis-report.md with findings + +## Report Format + +The generated `analysis-report.md` contains: + +```markdown +**🤖 AI Analysis** + +**Root Cause**: [1-2 sentence summary with file:line references] + +**Evidence**: +• [Specific code observations] +• [Patterns across failures] +• [Recent changes correlation] + +**Affected Platforms**: [Architectures/OS if pattern found] + +**Recommendations**: +• [Specific file:line to fix with suggested change] +• [Additional investigation needed] +• [Prevention strategy] + +--- +**Statistics** +• Total Failures: [count] +• Total Errors: [count] +• Failed Jobs: [list] +``` + +## Implementation + +Start by finding and parsing test reports: + +```bash +# Find all XML test reports +find -name "*.xml" -type f +``` + +For each failure: +- Read the test source code to understand intent +- Examine the implementation being tested +- Check `git log --oneline -20` for recent changes +- Look for patterns across different platforms + +Generate the report focusing on **actionable insights** for the oncall engineer: +- File paths and line numbers for fixes +- Platform-specific patterns (endianness, timing, etc.) +- Links to similar past failures if found + +Keep the analysis **under 500 words** and emphasize: +- What broke +- Why it broke +- How to fix it + +## CRITICAL: File Creation Step + +You MUST execute this bash command to create the report file: + +```bash +cat > analysis-report.md <<'EOF' +**🤖 AI Analysis** + +**Root Cause**: [your analysis here] + +**Evidence**: +• [your findings] + +**Affected Platforms**: [platforms] + +**Recommendations**: +• [actionable fixes] + +--- +**Statistics** +• Total Failures: [count] +• Failed Jobs: [jobs] +EOF +``` + +DO NOT just summarize your findings - you MUST create the actual file using the bash command above. + +This is a required step. The workflow depends on analysis-report.md existing. diff --git a/.github/actionlint.yaml b/.github/actionlint.yaml new file mode 100644 index 0000000000..671ea49671 --- /dev/null +++ b/.github/actionlint.yaml @@ -0,0 +1,4 @@ +self-hosted-runner: + labels: + - ubuntu-24.04 + - ubuntu-24.04-arm diff --git a/.github/scripts/README.md b/.github/scripts/README.md new file mode 100644 index 0000000000..97ae7055ff --- /dev/null +++ b/.github/scripts/README.md @@ -0,0 +1,232 @@ +# Test Failure Analysis with Claude + +Automatically analyzes test failures using Claude AI and includes intelligent insights in Slack notifications. + +## Architecture + +``` +Integration Tests Run + ├── amd64-integration-tests (may fail) + ├── arm64-integration-tests (may fail) + ├── s390x-integration-tests (may fail) + ├── ppc64le-integration-tests (may fail) + │ + ├── collect-failures + │ └── Determine which jobs failed + │ + └── analyze-and-notify (reusable workflow) + ├── analyze-failures + │ ├── Download test artifacts + │ ├── Execute /analyze-test-failures skill + │ └── Upload analysis-report.md + │ + └── notify + ├── Download analysis-report.md + └── Post to Slack with AI insights +``` + +## How It Works + +### 1. Test Failures +Any integration test job fails (e.g., `rhcos-arm64`, `cos-logs`) + +### 2. Collect Failures +The `collect-failures` job identifies which jobs failed and outputs the list + +### 3. Analyze Failures (Claude Skill) +Uses `claude-code-base-action` to execute the `/analyze-test-failures` skill: + +**The skill (`.claude/commands/analyze-test-failures.md`):** +- Finds and parses JUnit XML test reports +- Reads failing test source code +- Examines implementation code being tested +- Checks git log for recent changes +- Identifies platform-specific patterns (arch/OS) +- Creates `analysis-report.md` with actionable insights + +**Claude has access to:** +- `Skill` - Load and execute the analysis skill +- `Read` - View source files +- `Grep` - Search codebase +- `Glob` - Find files +- `Bash` - Execute git commands, create reports + +### 4. Notify +Posts to Slack (#team-acs-collector-oncall) with: +- AI-generated root cause analysis +- Evidence from code and logs +- Platform-specific patterns detected +- Actionable recommendations with file:line references + +Falls back to simple notification if analysis fails. + +## Files + +### Workflows +- `.github/workflows/integration-tests.yml` - Main integration test workflow +- `.github/workflows/analyze-and-notify.yml` - Reusable analysis workflow + +### Skill +- `.claude/commands/analyze-test-failures.md` - Claude skill defining analysis logic + +## Example Output + +**Slack message with AI analysis:** +``` +@acs-collector-oncall + +🤖 AI Analysis + +**Root Cause**: NetworkSignalHandler.cpp:245 missing ntohs() call +causing UDP checksum failures on ARM64 platforms. + +**Evidence**: +• UDP test failures isolated to arm64 runners (rhcos-arm64, cos-arm64) +• Checksum comparison uses direct equality without byte order conversion +• Recent commit abc123f modified network packet handling +• Tests pass on amd64 where byte order matches + +**Affected Platforms**: arm64 (rhcos-arm64, cos-arm64, ubuntu-arm) + +**Recommendations**: +• Fix collector/lib/NetworkSignalHandler.cpp:245 - add ntohs() call +• Add endianness test to integration suite +• Review other protocol handlers for similar issues + +--- +**Statistics** +• Total Failures: 2 +• Failed Jobs: rhcos-arm64, cos-arm64 +``` + +## How It's Different from Manual Analysis + +**Before:** Generic notification +``` +@acs-collector-oncall +Integration tests failed. +``` + +**After:** Actionable analysis with Claude +- Specific file and line number to fix +- Root cause explanation based on code analysis +- Platform/architecture pattern detection +- Links recent git changes to failures +- Provides concrete next steps + +## Testing + +### Test on a PR + +Add the label `test-oncall-workflow` to any PR to trigger the workflow. + +**What happens:** +- Workflow runs with empty test artifacts +- Claude analyzes and generates a report +- Report is uploaded as artifact +- **Slack notification is skipped** (only runs on actual test failures) + +**Use case:** Verify Claude analysis executes without spamming Slack. + +**To verify it worked:** +1. Check the workflow run in Actions tab +2. Download the `failure-analysis` artifact to see the generated report + +### Test with Real Failures + +The best test is observing the workflow on actual test failures: +1. Wait for integration tests to fail naturally +2. Check #team-acs-collector-oncall for the AI analysis +3. Verify the analysis is helpful and actionable + +## Configuration + +### Vertex AI Region +Set in `.github/workflows/analyze-and-notify.yml`: +```yaml +env: + CLOUD_ML_REGION: us-east5 +``` + +### Required Secrets + +Already configured: +- `GCP_CLAUDE_SERVICE_ACCOUNT_KEY` - Service account JSON for Vertex AI +- `GCP_CLAUDE_PROJECT_ID` - GCP project ID +- `SLACK_COLLECTOR_ONCALL_WEBHOOK` - Slack webhook URL + +### Allowed Tools + +Claude has access to these tools for investigation: +```yaml +allowed_tools: "Skill,Read,Grep,Glob,Bash" +``` + +### Reusable Workflow Inputs + +The `analyze-and-notify.yml` workflow accepts: +- `failed-jobs` - Comma-separated list of failed job names +- `workflow-name` - Name of the workflow that failed + +## Troubleshooting + +### No Analysis Report Generated + +**Check:** +1. Claude action step logs - did it execute successfully? +2. "Check if analysis report was created" step - does file exist? +3. Skill file exists at `.claude/commands/analyze-test-failures.md` +4. `Skill` tool is in `allowed_tools` + +### Vertex AI Errors + +**Common issues:** +- Model not available in configured region +- Service account lacks `roles/aiplatform.user` permission +- `GCP_CLAUDE_PROJECT_ID` secret not set correctly + +**Solution:** +Check Claude action logs for specific error details. + +### No Slack Notification + +**Check:** +1. `SLACK_COLLECTOR_ONCALL_WEBHOOK` secret is set +2. Notify job logs show download step succeeded +3. Webhook URL is valid + +### Analysis Quality Issues + +**If Claude's analysis is not helpful:** +1. Check that test artifacts are being uploaded correctly +2. Verify JUnit XML format is valid +3. Update skill instructions in `.claude/commands/analyze-test-failures.md` +4. The skill can be iterated on independently of the workflow + +## Local Development + +### Test the Skill Locally + +```bash +# Requires Claude CLI installed +claude /analyze-test-failures test-artifacts/ "Integration Tests" "rhcos-arm64,cos" +``` + +### Update the Skill + +Edit `.claude/commands/analyze-test-failures.md` to: +- Change analysis instructions +- Update report format +- Add new investigation steps +- Modify recommendations structure + +Changes take effect on the next workflow run - no workflow YAML changes needed. + +## Future Enhancements + +- [ ] Correlate failures with specific PR/commit +- [ ] Track failure patterns over time +- [ ] Link to similar historical failures +- [ ] Auto-create issues for recurring failures +- [ ] Support for other test frameworks beyond JUnit XML +- [ ] Integration with test retries/flakiness detection diff --git a/.github/workflows/analyze-and-notify.yml b/.github/workflows/analyze-and-notify.yml new file mode 100644 index 0000000000..8fefbff78e --- /dev/null +++ b/.github/workflows/analyze-and-notify.yml @@ -0,0 +1,151 @@ +name: Analyze Test Failures and Notify + +on: + workflow_call: + inputs: + failed-jobs: + description: 'Comma-separated list of failed job names' + required: true + type: string + workflow-name: + description: 'Name of the workflow that failed' + required: true + type: string + pull_request: + types: [labeled] + +jobs: + analyze-failures: + runs-on: ubuntu-24.04 + if: | + always() && ( + github.event_name == 'workflow_call' || + (github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'test-oncall-workflow')) + ) + outputs: + workflow_name: ${{ steps.params.outputs.workflow_name }} + failed_jobs: ${{ steps.params.outputs.failed_jobs }} + steps: + - name: Set workflow parameters + id: params + run: | + if [ "${{ github.event_name }}" = "pull_request" ]; then + echo "failed_jobs=test-label-trigger" >> $GITHUB_OUTPUT + echo "workflow_name=Test Workflow (Label Trigger)" >> $GITHUB_OUTPUT + else + echo "failed_jobs=${{ inputs.failed-jobs }}" >> $GITHUB_OUTPUT + echo "workflow_name=${{ inputs.workflow-name }}" >> $GITHUB_OUTPUT + fi + + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Download all test artifacts + uses: actions/download-artifact@v4 + with: + path: test-artifacts + continue-on-error: true + + - name: Setup GCP authentication for Claude + uses: 'google-github-actions/auth@v2' + with: + credentials_json: '${{ secrets.GCP_CLAUDE_SERVICE_ACCOUNT_KEY }}' + continue-on-error: true + + - name: Analyze test failures with Claude + id: analyze + uses: anthropics/claude-code-base-action@beta + continue-on-error: true + env: + ANTHROPIC_VERTEX_PROJECT_ID: ${{ secrets.GCP_CLAUDE_PROJECT_ID }} + CLOUD_ML_REGION: us-east5 + with: + use_vertex: true + allowed_tools: "Skill,Read,Grep,Glob,Bash" + prompt: | + /analyze-test-failures test-artifacts/ "${{ steps.params.outputs.workflow_name }}" "${{ steps.params.outputs.failed_jobs }}" + + - name: Check if analysis report was created + id: check-report + if: always() + run: | + echo "Current directory: $(pwd)" + echo "Files in current directory:" + ls -la + + echo "" + echo "Searching for analysis-report.md anywhere in workspace:" + find . -name "analysis-report.md" -type f 2>/dev/null || echo "Not found anywhere" + + if [ -f analysis-report.md ]; then + echo "report_exists=true" >> $GITHUB_OUTPUT + echo "✓ Analysis report exists in current directory" + ls -lh analysis-report.md + echo "--- First 20 lines ---" + head -20 analysis-report.md + else + echo "report_exists=false" >> $GITHUB_OUTPUT + echo "✗ Analysis report not found in current directory" + fi + + - name: Upload analysis report + if: steps.check-report.outputs.report_exists == 'true' + uses: actions/upload-artifact@v4 + with: + name: failure-analysis + path: analysis-report.md + + notify: + runs-on: ubuntu-24.04 + needs: analyze-failures + if: always() && github.event_name != 'pull_request' + steps: + - name: Download analysis report + uses: actions/download-artifact@v4 + with: + name: failure-analysis + path: . + continue-on-error: true + + - name: Read analysis report + id: read-analysis + run: | + if [ -f analysis-report.md ]; then + ANALYSIS=$(cat analysis-report.md) + echo "analysis<> $GITHUB_OUTPUT + echo "$ANALYSIS" >> $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT + echo "has_analysis=true" >> $GITHUB_OUTPUT + else + echo "has_analysis=false" >> $GITHUB_OUTPUT + fi + + - name: Slack notification with AI analysis + if: steps.read-analysis.outputs.has_analysis == 'true' + uses: rtCamp/action-slack-notify@v2 + env: + SLACK_WEBHOOK: ${{ secrets.SLACK_COLLECTOR_ONCALL_WEBHOOK }} + SLACK_CHANNEL: team-acs-collector-oncall + SLACK_COLOR: failure + SLACK_LINK_NAMES: true + SLACK_TITLE: "${{ needs.analyze-failures.outputs.workflow_name }} failed" + MSG_MINIMAL: actions url,commit + SLACK_MESSAGE: | + @acs-collector-oncall + + ${{ steps.read-analysis.outputs.analysis }} + + - name: Slack notification (fallback) + if: steps.read-analysis.outputs.has_analysis != 'true' + uses: rtCamp/action-slack-notify@v2 + env: + SLACK_WEBHOOK: ${{ secrets.SLACK_COLLECTOR_ONCALL_WEBHOOK }} + SLACK_CHANNEL: team-acs-collector-oncall + SLACK_COLOR: failure + SLACK_LINK_NAMES: true + SLACK_TITLE: "${{ needs.analyze-failures.outputs.workflow_name }} failed" + MSG_MINIMAL: actions url,commit + SLACK_MESSAGE: | + @acs-collector-oncall + + AI analysis unavailable. Check workflow logs. diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 936bcbeeba..18ec3d06a7 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -130,7 +130,7 @@ jobs: collector-repo: ${{ inputs.collector-repo }} secrets: inherit - notify: + collect-failures: runs-on: ubuntu-24.04 if: always() && contains(join(needs.*.result, ','), 'failure') && github.event_name != 'pull_request' needs: @@ -138,15 +138,31 @@ jobs: - arm64-integration-tests - s390x-integration-tests - ppc64le-integration-tests + outputs: + failed_jobs: ${{ steps.collect.outputs.failed_jobs }} steps: - - name: Slack notification - uses: rtCamp/action-slack-notify@v2 - env: - SLACK_WEBHOOK: ${{ secrets.SLACK_COLLECTOR_ONCALL_WEBHOOK }} - SLACK_CHANNEL: team-acs-collector-oncall - SLACK_COLOR: failure - SLACK_LINK_NAMES: true - SLACK_TITLE: "Integration tests failed." - MSG_MINIMAL: actions url,commit - SLACK_MESSAGE: | - @acs-collector-oncall + - name: Collect failed job names + id: collect + run: | + FAILED_JOBS="" + if [[ "${{ needs.amd64-integration-tests.result }}" == "failure" ]]; then + FAILED_JOBS="amd64-integration-tests" + fi + if [[ "${{ needs.arm64-integration-tests.result }}" == "failure" ]]; then + FAILED_JOBS="${FAILED_JOBS:+$FAILED_JOBS,}arm64-integration-tests" + fi + if [[ "${{ needs.s390x-integration-tests.result }}" == "failure" ]]; then + FAILED_JOBS="${FAILED_JOBS:+$FAILED_JOBS,}s390x-integration-tests" + fi + if [[ "${{ needs.ppc64le-integration-tests.result }}" == "failure" ]]; then + FAILED_JOBS="${FAILED_JOBS:+$FAILED_JOBS,}ppc64le-integration-tests" + fi + echo "failed_jobs=$FAILED_JOBS" >> $GITHUB_OUTPUT + + analyze-and-notify: + needs: collect-failures + uses: ./.github/workflows/analyze-and-notify.yml + with: + failed-jobs: ${{ needs.collect-failures.outputs.failed_jobs }} + workflow-name: "Integration Tests" + secrets: inherit From 31cea3d6e9cb98a4f1d95807deae7e1e30294a39 Mon Sep 17 00:00:00 2001 From: StackRox Automation Date: Thu, 21 May 2026 02:07:34 +0000 Subject: [PATCH 2/4] Remove actionlint.yaml Co-Authored-By: Claude Sonnet 4.5 --- .github/actionlint.yaml | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 .github/actionlint.yaml diff --git a/.github/actionlint.yaml b/.github/actionlint.yaml deleted file mode 100644 index 671ea49671..0000000000 --- a/.github/actionlint.yaml +++ /dev/null @@ -1,4 +0,0 @@ -self-hosted-runner: - labels: - - ubuntu-24.04 - - ubuntu-24.04-arm From 37575cac9806e00386cdb796c6c7e8c213b74c2a Mon Sep 17 00:00:00 2001 From: StackRox Automation Date: Thu, 21 May 2026 03:50:03 +0000 Subject: [PATCH 3/4] Fix shellcheck warnings: quote $GITHUB_OUTPUT and group redirects Co-Authored-By: Claude Sonnet 4.5 --- .github/workflows/analyze-and-notify.yml | 24 +++++++++++++----------- .github/workflows/integration-tests.yml | 2 +- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/.github/workflows/analyze-and-notify.yml b/.github/workflows/analyze-and-notify.yml index 8fefbff78e..9a66be4416 100644 --- a/.github/workflows/analyze-and-notify.yml +++ b/.github/workflows/analyze-and-notify.yml @@ -30,11 +30,11 @@ jobs: id: params run: | if [ "${{ github.event_name }}" = "pull_request" ]; then - echo "failed_jobs=test-label-trigger" >> $GITHUB_OUTPUT - echo "workflow_name=Test Workflow (Label Trigger)" >> $GITHUB_OUTPUT + echo "failed_jobs=test-label-trigger" >> "$GITHUB_OUTPUT" + echo "workflow_name=Test Workflow (Label Trigger)" >> "$GITHUB_OUTPUT" else - echo "failed_jobs=${{ inputs.failed-jobs }}" >> $GITHUB_OUTPUT - echo "workflow_name=${{ inputs.workflow-name }}" >> $GITHUB_OUTPUT + echo "failed_jobs=${{ inputs.failed-jobs }}" >> "$GITHUB_OUTPUT" + echo "workflow_name=${{ inputs.workflow-name }}" >> "$GITHUB_OUTPUT" fi - name: Checkout repository @@ -78,13 +78,13 @@ jobs: find . -name "analysis-report.md" -type f 2>/dev/null || echo "Not found anywhere" if [ -f analysis-report.md ]; then - echo "report_exists=true" >> $GITHUB_OUTPUT + echo "report_exists=true" >> "$GITHUB_OUTPUT" echo "✓ Analysis report exists in current directory" ls -lh analysis-report.md echo "--- First 20 lines ---" head -20 analysis-report.md else - echo "report_exists=false" >> $GITHUB_OUTPUT + echo "report_exists=false" >> "$GITHUB_OUTPUT" echo "✗ Analysis report not found in current directory" fi @@ -112,12 +112,14 @@ jobs: run: | if [ -f analysis-report.md ]; then ANALYSIS=$(cat analysis-report.md) - echo "analysis<> $GITHUB_OUTPUT - echo "$ANALYSIS" >> $GITHUB_OUTPUT - echo "EOF" >> $GITHUB_OUTPUT - echo "has_analysis=true" >> $GITHUB_OUTPUT + { + echo "analysis<> "$GITHUB_OUTPUT" else - echo "has_analysis=false" >> $GITHUB_OUTPUT + echo "has_analysis=false" >> "$GITHUB_OUTPUT" fi - name: Slack notification with AI analysis diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 18ec3d06a7..a4ec62602c 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -157,7 +157,7 @@ jobs: if [[ "${{ needs.ppc64le-integration-tests.result }}" == "failure" ]]; then FAILED_JOBS="${FAILED_JOBS:+$FAILED_JOBS,}ppc64le-integration-tests" fi - echo "failed_jobs=$FAILED_JOBS" >> $GITHUB_OUTPUT + echo "failed_jobs=$FAILED_JOBS" >> "$GITHUB_OUTPUT" analyze-and-notify: needs: collect-failures From 4b9e0a0c88bd3920da1f8186ee41acaff6b26878 Mon Sep 17 00:00:00 2001 From: StackRox Automation Date: Thu, 21 May 2026 03:51:21 +0000 Subject: [PATCH 4/4] Consolidate Slack notification into single step with inline fallback Co-Authored-By: Claude Sonnet 4.5 --- .github/workflows/analyze-and-notify.yml | 31 ++++++------------------ 1 file changed, 7 insertions(+), 24 deletions(-) diff --git a/.github/workflows/analyze-and-notify.yml b/.github/workflows/analyze-and-notify.yml index 9a66be4416..d416979e42 100644 --- a/.github/workflows/analyze-and-notify.yml +++ b/.github/workflows/analyze-and-notify.yml @@ -112,18 +112,16 @@ jobs: run: | if [ -f analysis-report.md ]; then ANALYSIS=$(cat analysis-report.md) - { - echo "analysis<> "$GITHUB_OUTPUT" else - echo "has_analysis=false" >> "$GITHUB_OUTPUT" + ANALYSIS="AI analysis unavailable. Check workflow logs." fi + { + echo "analysis<> "$GITHUB_OUTPUT" - - name: Slack notification with AI analysis - if: steps.read-analysis.outputs.has_analysis == 'true' + - name: Slack notification uses: rtCamp/action-slack-notify@v2 env: SLACK_WEBHOOK: ${{ secrets.SLACK_COLLECTOR_ONCALL_WEBHOOK }} @@ -136,18 +134,3 @@ jobs: @acs-collector-oncall ${{ steps.read-analysis.outputs.analysis }} - - - name: Slack notification (fallback) - if: steps.read-analysis.outputs.has_analysis != 'true' - uses: rtCamp/action-slack-notify@v2 - env: - SLACK_WEBHOOK: ${{ secrets.SLACK_COLLECTOR_ONCALL_WEBHOOK }} - SLACK_CHANNEL: team-acs-collector-oncall - SLACK_COLOR: failure - SLACK_LINK_NAMES: true - SLACK_TITLE: "${{ needs.analyze-failures.outputs.workflow_name }} failed" - MSG_MINIMAL: actions url,commit - SLACK_MESSAGE: | - @acs-collector-oncall - - AI analysis unavailable. Check workflow logs.