From 2a1807f08df6cd4b7ca366b7c7e5168ad8e9a844 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=98=93=E8=89=AF?= <1204183885@qq.com> Date: Thu, 9 Jul 2026 19:10:44 +0800 Subject: [PATCH] fix(ci): detect silent triage failures with empty-response check (#6566) * fix(ci): detect silent triage failures with empty-response check The qwen-triage workflow relied on qwen-code-action to surface failures, but when the CLI exited 0 with empty output the step reported success with no triage comments posted. Add a post-step that checks the action's summary output and fails the job if it is empty, making silent failures visible in the Actions log. Defense-in-depth for QwenLM/qwen-code#6553 (primary fix in qwen-code-action). * ci: bump qwen-code-action pin to 6d08e91 Picks up the stderr visibility fix (QwenLM/qwen-code-action#12) that always emits stderr to the step log and warns on empty responses. Bumps all 5 workflows pinned to the action. * fix(ci): pass triage summary through env --- .../workflows/qwen-automated-issue-triage.yml | 2 +- .github/workflows/qwen-code-pr-review.yml | 2 +- .github/workflows/qwen-issue-followup-bot.yml | 2 +- .../workflows/qwen-scheduled-issue-triage.yml | 2 +- .github/workflows/qwen-triage.yml | 16 +++++++++++++++- scripts/tests/qwen-triage-workflow.test.js | 12 ++++++++++++ 6 files changed, 31 insertions(+), 5 deletions(-) diff --git a/.github/workflows/qwen-automated-issue-triage.yml b/.github/workflows/qwen-automated-issue-triage.yml index bdb9aee4d7..e154024a82 100644 --- a/.github/workflows/qwen-automated-issue-triage.yml +++ b/.github/workflows/qwen-automated-issue-triage.yml @@ -39,7 +39,7 @@ jobs: runs-on: 'ubuntu-latest' steps: - name: 'Run Qwen Issue Analysis' - uses: 'QwenLM/qwen-code-action@5fd6818d04d64e87d255ee4d5f77995e32fbf4c2' + uses: 'QwenLM/qwen-code-action@6d08e91aa807257b9c8af60edb5bb6bb2d7d951f' id: 'qwen_issue_analysis' env: GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}' diff --git a/.github/workflows/qwen-code-pr-review.yml b/.github/workflows/qwen-code-pr-review.yml index 141772e813..7dbf2caded 100644 --- a/.github/workflows/qwen-code-pr-review.yml +++ b/.github/workflows/qwen-code-pr-review.yml @@ -1037,7 +1037,7 @@ jobs: - name: 'Resolve conflicts' if: "steps.prepare.outputs.decision == 'run'" id: 'resolve_conflicts' - uses: 'QwenLM/qwen-code-action@5fd6818d04d64e87d255ee4d5f77995e32fbf4c2' + uses: 'QwenLM/qwen-code-action@6d08e91aa807257b9c8af60edb5bb6bb2d7d951f' env: PR_NUMBER: '${{ steps.resolve.outputs.pr_number }}' BASE_REF: '${{ steps.prepare.outputs.base_ref }}' diff --git a/.github/workflows/qwen-issue-followup-bot.yml b/.github/workflows/qwen-issue-followup-bot.yml index e861b84eaf..bbd0ccc5dc 100644 --- a/.github/workflows/qwen-issue-followup-bot.yml +++ b/.github/workflows/qwen-issue-followup-bot.yml @@ -292,7 +292,7 @@ jobs: echo "Issue follow-up state: event=${EVENT_NAME} dispatch_dry=${DISPATCH_DRY_RUN} issues_dry=${ISSUE_OPENED_DRY_RUN} schedule_dry=${SCHEDULE_DRY_RUN} resolved_dry_run=${dry_run} scheduled_limit=${SCHEDULED_LIMIT_INPUT}" - name: 'Run Qwen issue follow-up' - uses: 'QwenLM/qwen-code-action@5fd6818d04d64e87d255ee4d5f77995e32fbf4c2' + uses: 'QwenLM/qwen-code-action@6d08e91aa807257b9c8af60edb5bb6bb2d7d951f' env: GITHUB_TOKEN: '${{ env.BOT_GITHUB_TOKEN }}' GH_TOKEN: '${{ env.BOT_GITHUB_TOKEN }}' diff --git a/.github/workflows/qwen-scheduled-issue-triage.yml b/.github/workflows/qwen-scheduled-issue-triage.yml index 4281211833..4c1eb5233e 100644 --- a/.github/workflows/qwen-scheduled-issue-triage.yml +++ b/.github/workflows/qwen-scheduled-issue-triage.yml @@ -54,7 +54,7 @@ jobs: - name: 'Run Qwen Issue Triage' if: |- ${{ steps.find_issues.outputs.issues_to_triage != '[]' }} - uses: 'QwenLM/qwen-code-action@5fd6818d04d64e87d255ee4d5f77995e32fbf4c2' + uses: 'QwenLM/qwen-code-action@6d08e91aa807257b9c8af60edb5bb6bb2d7d951f' env: GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}' ISSUES_TO_TRIAGE: '${{ steps.find_issues.outputs.issues_to_triage }}' diff --git a/.github/workflows/qwen-triage.yml b/.github/workflows/qwen-triage.yml index 8329324e82..7494d5d89f 100644 --- a/.github/workflows/qwen-triage.yml +++ b/.github/workflows/qwen-triage.yml @@ -260,7 +260,8 @@ jobs: fi - name: 'Run Qwen Triage' - uses: 'QwenLM/qwen-code-action@5fd6818d04d64e87d255ee4d5f77995e32fbf4c2' + id: 'triage' + uses: 'QwenLM/qwen-code-action@6d08e91aa807257b9c8af60edb5bb6bb2d7d951f' env: GITHUB_TOKEN: '${{ secrets.QWEN_CODE_BOT_TOKEN || secrets.CI_BOT_PAT }}' GH_TOKEN: '${{ secrets.QWEN_CODE_BOT_TOKEN || secrets.CI_BOT_PAT }}' @@ -289,6 +290,19 @@ jobs: } prompt: '/triage ${{ steps.resolve.outputs.number }} --repo ${{ github.repository }}' + - name: 'Check triage response' + if: 'success() || failure()' + shell: 'bash' + env: + RESPONSE: '${{ steps.triage.outputs.summary }}' + run: |- + set -uo pipefail + if [[ -z "${RESPONSE}" || "${RESPONSE}" == "null" ]]; then + echo "::error title=Triage silent failure::Qwen Code exited without a response. Check the 'Run Qwen Triage' step stderr above for diagnostics." + exit 1 + fi + echo "Triage response received (${#RESPONSE} chars)." + # On-demand real-user testing: a write-permission user comments # `@qwen-code /tmux` on a PR to launch the changed app in a tmux TUI and # exercise the affected flow. EXECUTES untrusted PR code, so: gated on the PR diff --git a/scripts/tests/qwen-triage-workflow.test.js b/scripts/tests/qwen-triage-workflow.test.js index 30b3be98e2..67c1098340 100644 --- a/scripts/tests/qwen-triage-workflow.test.js +++ b/scripts/tests/qwen-triage-workflow.test.js @@ -112,6 +112,18 @@ describe('qwen-triage tmux workflow', () => { expect(runStep).toContain("QWEN_HOME: '${{ runner.temp }}/qwen-home'"); }); + it('passes triage output through env before bash reads it', () => { + const checkStep = step('Check triage response'); + + expect(checkStep).toContain( + "RESPONSE: '${{ steps.triage.outputs.summary }}'", + ); + expect(checkStep).not.toContain( + 'RESPONSE="${{ steps.triage.outputs.summary }}"', + ); + expect(checkStep).toContain('if [[ -z "${RESPONSE}"'); + }); + it('reports timeout and infra-error without claiming the flow was exercised', () => { const postStep = step('Post tmux result comment');