qwen-code/.github/actionlint.yaml
易良 d0ba8534fa
feat(ci): on-demand tmux real-user testing for PRs (#5203)
* feat(ci): add on-demand tmux real-user testing to triage workflow

Add a tmux-testing stage to qwen-triage.yml: a write-permission user runs
`@qwen-code /tmux` on a PR (or dispatches with tmux_pr=N) to launch the
changed app in a real tmux TUI session and exercise the affected flow,
catching interactive regressions that diff-based review can't.

- Gated on the PR AUTHOR having write permission (whose code runs), reusing
  the authorize job; no separate fork check.
- Executes untrusted PR code with minimal blast radius: contents:read, no
  GitHub token in the agent env, persist-credentials:false.
- Proxy bypass for the model call only.
- A separate publish-tmux job (clean runner, write PAT, no PR-code checkout)
  posts the verdict back to the PR — keeping the write credential isolated
  from the code execution.

* fix(ci): address tmux-testing review findings

- Gate the workflow_dispatch tmux_pr path on the PR author's write
  permission via the authorize job, so dispatching never runs an
  unauthorized contributor's code on the self-hosted runner.
- Make workflow_dispatch triage vs tmux mutually exclusive (tmux_pr
  set skips the triage job), matching the documented input contract.
- Pin GITHUB_TOKEN/GH_TOKEN empty in the untrusted-code step so no
  inherited repo-scoped credential reaches the agent.
- Serialize concurrent tmux runs per PR; skip PRs whose merge ref is
  unavailable (CONFLICTING); clean the runner workspace on exit.
- publish-tmux now also reports infrastructure failures instead of
  staying silent, and the comment fence widens past any backtick run
  in untrusted output so it cannot break out and render markdown.
- Correct the proxy-bypass comment to describe actual behavior.

* refactor(ci): collapse tmux gating into one decision output

- Fold should_test + has_tui into a single tri-state `decision`
  (skip | na | run); the five repeated step guards become
  `decision == 'run'`, and the standalone `Mark not applicable`
  step is gone (the n/a verdict is set inline in the resolve step).
- Resolve PR state + file list in one `gh pr view` call instead of
  two.

No behavior change: skip stays silent, na posts n/a, run drives the app.

* fix(ci): wait out UNKNOWN mergeability before deciding

Right after a /tmux comment GitHub may not have computed PR
mergeability yet (mergeable=UNKNOWN), and refs/pull/N/merge is only
current once it has. Retry the resolve up to 5x (3s apart) until it
settles, so a freshly-pushed PR isn't checked out from a stale or
missing merge ref.

* fix(ci): harden tmux publish comment and mergeability/exit-code handling

- publish-tmux: render artifacts in HTML-escaped <pre> instead of a
  backtick fence; removes the grep crash on backtick-free content under
  set -euo pipefail and closes the </details>/fence-breakout injection
- tmux-testing: skip when mergeability stays UNKNOWN after retries
- classify exit 137/139 (OOM/segfault) as infra-error, not test fail
- upload-artifact: continue-on-error so a pre-write crash isn't masked

* ci: harden tmux testing workflow

* fix(ci): address tmux testing review follow-ups

* fix(ci): report tmux prepare failures

* fix(ci): use latest qwen CLI for tmux testing
2026-06-21 11:56:29 +08:00

5 lines
71 B
YAML

self-hosted-runner:
labels:
- 'ecs-qwen'
config-variables: null