Commit graph

354 commits

Author SHA1 Message Date
ermin.zem
5c82857fea
Add harness infrastructure for web-shell package (#6517)
Some checks are pending
E2E Tests / E2E Test (Linux) - sandbox:docker (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:none (push) Waiting to run
E2E Tests / E2E Test - macOS (push) Waiting to run
E2E Tests / web-shell Browser Regression (push) Waiting to run
* test(web-shell): add browser and lint harness

* test(web-shell): harden browser smoke harness

* fix(web-shell): guard mock daemon model state

* test(web-shell): remove unused scenario harness

* fix(web-shell): remove stale lint disables

* test(web-shell): make matchMedia stub writable

* fix(web-shell): exclude tests from package typecheck

* test(web-shell): tighten mock daemon route contract

* Update packages/web-shell/client/e2e/utils/mockDaemon.ts

Co-authored-by: qwen-code-ci-bot <qwen-code-ci@service.alibaba.com>

* test(web-shell): clear stale SSE connections

* ci(web-shell): gate smoke on full CI profile

---------

Co-authored-by: ermin.zem <ermin.zem@alibaba-inc.com>
Co-authored-by: qwen-code-ci-bot <qwen-code-ci@service.alibaba.com>
Co-authored-by: Shaojin Wen <shaojin.wensj@alibaba-inc.com>
Co-authored-by: 易良 <1204183885@qq.com>
2026-07-09 08:11:58 +00:00
易良
ba709c2c2c
ci(autofix): Add single-target scheduler (#6547)
* ci(autofix): add single-target scheduler

* ci(autofix): handle failed PR checks in scheduler

* ci(autofix): remove scheduler plan doc

* ci(autofix): watermark failed PR checks

* ci(autofix): harden failed check feedback

* ci(autofix): count review-address failures

* ci(autofix): include review-address failures in feedback
2026-07-09 01:05:02 +00:00
Shaojin Wen
e3e449fc4c
feat(autofix): extend review loop to all dev-bot PRs, add real-time triggers (#6528)
* feat(autofix): extend review loop to all dev-bot PRs, add real-time triggers

* fix(autofix): address review feedback — trusted checkout, sender gate, in-repo check, issue comments

* fix(autofix): address suggestion feedback — API warning, bot comment filter, branch prefix doc, test coverage

* fix(autofix): drop pull_request_review_comment trigger to avoid redundant runs
2026-07-08 14:18:17 +00:00
易良
010bedfc88
fix(autofix): report review handoff failures (#6415)
* fix(autofix): report review handoff failures

* fix(autofix): distinguish terminal review handoffs

* fix(autofix): harden review handoff reporting

* test(autofix): cover agent failure handoff marker

* fix(autofix): avoid hanging on destroyed log stream

* fix(autofix): harden handoff failure reporting

* fix(autofix): detect split loop guard output

* fix(autofix): kill timed-out qwen process group
2026-07-07 12:27:13 +00:00
Salman Chishti
df6be035e1
Upgrade GitHub Actions for Node 24 compatibility (#5157)
* Upgrade GitHub Actions for Node 24 compatibility

Signed-off-by: Salman Muin Kayser Chishti <13schishti@gmail.com>

* ci: update remaining checkout pins

---------

Signed-off-by: Salman Muin Kayser Chishti <13schishti@gmail.com>
Co-authored-by: qwen-code-dev-bot <qwen-code-dev-bot@users.noreply.github.com>
Co-authored-by: 易良 <1204183885@qq.com>
Co-authored-by: yiliang114 <effortyiliang@gmail.com>
2026-07-07 12:17:22 +00:00
易良
5f7b57f933
fix(autofix): improve review addressing and verification (#6382)
* fix(autofix): run verification before committing

* ci(autofix): trigger review addressing on feedback

* fix(autofix): narrow npm command allowlist

* fix(autofix): address review workflow guards

* fix(autofix): keep review addressing on scheduled sweep
2026-07-06 14:10:58 +00:00
易良
0c28ddc180
ci(autofix): move agent prompts into a project skill (#6306)
* ci(autofix): move agent prompts into project skill

* ci(autofix): avoid rewriting bot branch history

* fix(ci): address autofix skill review comments

* fix(ci): preserve autofix skill guardrails

* fix(ci): restore autofix review self-check

* test(ci): pin autofix review self-check

* fix(ci): tighten autofix skill guardrails

* fix(ci): restore autofix skill guardrails

* fix(ci): restore autofix merge verification guidance

* ci(autofix): add maintainer comment dry-run trigger

* fix(autofix): expand skill prompt in workflow

* fix(autofix): preserve qwen failure artifacts

* fix(autofix): move prompt runner into skill

* refactor(autofix): slim skill runner

* refactor(autofix): trim skill prompt

* fix(autofix): clarify verification handoff

* fix(autofix): skip issues with open bot PRs

* fix(autofix): expose existing PR context to skill

* fix(autofix): require strict null-safe TypeScript patches

* feat(autofix): formalize full pipeline phases in skill specification

Expand the autofix skill from 3 modes to an 8-phase pipeline definition
covering design, review-design, develop, verify, repair, cross-review,
and address-review. Adds bounded repair, scope creep self-check, and
structured failure classification. Future phases clearly marked.

* fix(autofix): keep skill scope to active modes

* fix(autofix): tighten manual command routing

* fix(autofix): harden comment-triggered runs

* fix(autofix): remove comment-triggered autofix route

* fix(autofix): restore review safety checks

* test(autofix): relax runner failure timeout

* fix(autofix): keep issue fixes in workflow checkout

* fix(autofix): harden review feedback handling

* fix(autofix): guard forced routing, improve runner observability (#6306)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(autofix): address workflow review feedback

* fix(autofix): tighten review feedback handling

* test(autofix): trim runner test boilerplate

---------

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-07-06 06:28:16 +00:00
易良
e3906392b5
perf(ci): optimize autofix pipeline — fast-track, skip duplicate build, scoped tests (#6315)
* perf(ci): optimize autofix pipeline — fast-track, skip duplicate build, scoped tests (#6196)

Three optimizations to reduce autofix wall-clock from ~48 min to ~28-35 min:

1. Fast-track decision: skip LLM assessment for trusted triggers
   (workflow_dispatch with explicit issue, issues:labeled event).
2. Skip duplicate build: set QWEN_SKIP_PREPARE=1 so npm ci does not
   re-run the prepare hook that builds+bundles before the explicit
   build step.
3. Scoped verification tests: run only changed-file tests via
   --changed instead of full per-package suites. Full regression
   is covered by regular CI on the PR.

Also hardens live test gating (require QWEN_CODE_RUN_LIVE_TESTS=1)
and increases crawler test timeout to 30s.

* refactor(ci): simplify verification gate package discovery

Replace 30-line inline Node script with the original one-liner
`grep -oE '^packages/[^/]+'`. The Node script checked for
package.json existence and test scripts, but `--if-present` already
handles missing test scripts and all workspace dirs have package.json.

Addresses design-review item #7.

* fix(ci): tighten autofix changed-test gate
2026-07-05 02:32:04 +00:00
易良
905c5c95a7
fix(ci): skip stale PR review runs (#6313)
* fix(ci): skip stale PR review runs

* test(ci): trigger review cancellation

* fix(ci): make PR review cancellation interruptible

* fix(ci): block stale review comment writes
2026-07-04 20:15:30 +00:00
易良
ba7561af49
fix(ci): Stop review bots for closed PRs (#6304)
* fix(ci): stop review bots for closed PRs

* test(ci): scope closed review workflow assertions

* test(ci): cover closed PR review guards
2026-07-04 14:16:47 +00:00
易良
e48999ddb2
fix(ci): require maintainer-applied autofix/approved label for tier-1 fast-path (#6276)
* fix(ci): require maintainer-applied `autofix/approved` label for tier-1 fast-path

The scheduled scan and `issues:labeled` event paths in `qwen-autofix.yml`
previously trusted the `status/ready-for-agent` label alone, which is
applied by an LLM reading untrusted issue text. An attacker could craft
issue content to trick the triage LLM into labeling it ready, bypassing
human review.

Introduce an `autofix/approved` label that only maintainers (write+
permission) can apply. Both the cron scan and event-triggered paths now
require this label alongside `status/ready-for-agent` before entering the
autonomous fix pipeline (dual-factor: LLM signal + human confirmation).

Also:
- `release.yml` automatically adds `autofix/approved` on workflow-created
  release-failure issues (trusted source, preserves existing automation)
- Forced-issue path (non-dispatch) also checks for the new label
- Claim step strips `autofix/approved` to keep processed issues clean

Closes #5634

* fix(ci): address autofix approval review

* fix(ci): address autofix approval follow-ups

* test(ci): cover autofix approval gate

* fix(ci): harden autofix approval revalidation

* fix(ci): avoid autofix approval retry loop

* fix(ci): harden autofix claim handling

* fix(ci): clarify autofix reapproval label

* fix(ci): make autofix claim label update non-destructive
2026-07-04 08:06:27 +00:00
Barry
18e2eed19e
Clarify macOS audio prebuild artifact naming (#6275)
The macOS audio prebuild job now packages both arm64 and x64 slices from the macos-14 runner, but the artifact name still advertised only arm64. Add a matrix suffix so that upload-artifact names the macOS bundle accurately while leaving other platform names unchanged.

Constraint: Existing collect job downloads prebuilds-* and should not need a pattern change
Confidence: high
Scope-risk: narrow
Tested: actionlint v1.7.7 .github/workflows/audio-capture-prebuilds.yml
Tested: node YAML parse for .github/workflows/audio-capture-prebuilds.yml
Tested: git diff --check
2026-07-04 01:55:17 +00:00
qwen-code-dev-bot
9f87c90a50
fix(autofix): unconditionally restore tracked files before branch checkout (#6281) (#6286)
git diff --quiet exits 0 when only CRLF normalization differs (content
is identical after filter), so the conditional git restore was skipped
even though the working tree was dirty. This caused git checkout -B to
fail on NOTICES.txt. Remove the conditional guard so restore always runs.

Co-authored-by: Qwen Autofix <qwen-autofix@alibaba-inc.com>
2026-07-03 20:11:42 +00:00
易良
e1fc45d508
ci(autofix): restore sandbox image flow (#6261)
* ci(autofix): restore sandbox image flow

* test(ci): update autofix workflow assertions

* ci(autofix): restore tracked output before review checkout

* test(ci): clarify autofix workspace assertion

* style(ci): format sandbox image resolver

* ci(autofix): address sandbox review feedback

* test(ci): cover sandbox image publish gating

* ci(autofix): validate sandbox image config

* ci(autofix): address workflow review comments
2026-07-03 15:30:58 +00:00
Shaojin Wen
081c46c5bc
fix(ci): add always() to delay-automatic-review and ack-review-request (#6260)
These jobs transitively depend on precheck-pr via authorize. precheck-pr
is intentionally skipped for same-repo PRs (only runs for forks). Without
always(), GitHub Actions' default behavior propagates the skipped upstream
job, causing delay-automatic-review to be skipped even when authorize
succeeds. This breaks the entire review chain for same-repo PRs on
opened/synchronize events.

Fixes PR #5629 review not triggering.
2026-07-03 11:47:28 +00:00
顾盼
5cd459ece3
fix(mobile-mcp): add production-release environment + scope to CD workflow for npm auth (#6258) 2026-07-03 10:28:30 +00:00
顾盼
9ea309961c
fix(mobile-mcp): align CD workflow with release.yml npm auth (add scope, drop provenance) (#6257) 2026-07-03 09:37:21 +00:00
顾盼
972cb044d1
fix(mobile-mcp): remove lint step from CD workflow (monorepo prettier conflicts with upstream eslint) (#6255) 2026-07-03 09:16:00 +00:00
顾盼
23c6c7032a
feat(mobile-mcp): vendor mobile-mcp with opt-in 0-1000 relative coordinates (#6235)
* Squashed 'packages/mobile-mcp/' content from commit c5d7d27fd

git-subtree-dir: packages/mobile-mcp
git-subtree-split: c5d7d27fd61e4762e15ae4b1c68b6c011be88bb7

* feat(mobile-mcp): vendor mobile-mcp with opt-in 0-1000 relative coordinates

Fork mobile-next/mobile-mcp (v0.0.61) into packages/mobile-mcp/ via git
subtree, renamed to @qwen-code/mobile-mcp with the following additions:

Relative coordinate shim (src/coord-norm.ts):
- MOBILE_MCP_COORDINATE_SPACE=1 enables 0-1000 normalized coordinates
- MOBILE_MCP_COORDINATE_SCALE configurable (default 1000, 999 for mobile_use)
- Input denormalization for click/double_tap/long_press/swipe
- Output normalization for list_elements and get_screen_size
- Tool description rewriting when enabled
- Default off = zero behavior change

Android enhancements:
- mobile_install_app: -r/-g/-d/-t install flags (Android only)
- mobile_ui_dump: full UIAutomator XML hierarchy dump
- mobile_adb_pull / mobile_adb_push: file transfer via ADB

Infrastructure:
- cd-mobile-mcp.yml: npm publish workflow (tag mobile-mcp-v*)
- scripts/sync-from-upstream.sh: git subtree pull for upstream sync
- .vendored-from / .vendored-patches.md: vendoring metadata
- Upstream telemetry disabled by default
- eslint.config.js: exclude packages/mobile-mcp from root lint

* chore(mobile-mcp): update package-lock.json for workspace dependencies

* fix(mobile-mcp): quote all YAML strings to pass yamllint

* fix(mobile-mcp): fix cd workflow yaml to pass both yamllint and actionlint

* fix(mobile-mcp): address review findings on our additions

- ensureScreenSize: log warning instead of silent failure (#4)
- invalidateScreenSize on orientation change (#5)
- adb_push: path.posix.resolve to prevent /sdcard/ traversal (#6)
- adb_pull: readOnlyHint → destructiveHint (writes local file) (#9)
- adb_push: remove validateOutputPath on read-source local_path (#11)
- normalizeElementResult: log error instead of bare catch (#16)
- rewriteDescription: remove dead duplicate regex (#17)
- cd workflow: add test step between build and publish (#19)

* fix(mobile-mcp): update server.json identity and fix package.json main entrypoint

---------

Co-authored-by: Shaojin Wen <shaojin.wensj@alibaba-inc.com>
2026-07-03 08:50:27 +00:00
易良
183ad54b11
ci: add lightweight PR profiles (#6186)
* ci: add lightweight PR profiles

* fix(ci): harden lightweight profile classification

* fix(ci): harden lightweight profile edge cases

* fix(ci): report classifier invocation failures

* fix(ci): tighten docs-only path matching

* ci: restrict light profiles to same-repo PRs

---------

Co-authored-by: Shaojin Wen <shaojin.wensj@alibaba-inc.com>
2026-07-03 07:40:25 +00:00
易良
e743f0e2e0
ci(autofix): run agents on dedicated ECS runners (#6207)
* ci(autofix): run agents on dedicated ECS runners

* ci(autofix): retry repository checkout

* ci(autofix): use local qwen bundle fallback

* ci(autofix): harden ECS runner failure handling

* ci(autofix): retry transient qwen runner failures

* fix(ci): proxy autofix model credentials

* fix(ci): limit ECS autofix to ready issues

* fix(ci): address autofix workflow review feedback

* fix(ci): restore autofix known bots

* chore(ci): trim autofix ECS scope

* fix(ci): consolidate autofix OpenAI proxy

* fix(ci): restrict autofix agent execution tools

---------

Co-authored-by: Shaojin Wen <shaojin.wensj@alibaba-inc.com>
2026-07-03 07:40:07 +00:00
易良
b16baf1ffc
ci(release): optimize validation steps (#6133)
* ci(release): optimize validation steps

* fix(ci): address release validation review comments

* fix(ci): document prepare skip contract

* test(ci): cover prepare failure exit

* fix(ci): prefix prepare error logs

* fix(ci): keep release quality build artifacts

* fix(ci): address release validation comments

* fix(ci): preserve release publish hooks

* test(ci): cover prepare failure paths

* fix(ci): disable release coverage safely
2026-07-02 23:53:08 +00:00
易良
89ddc701a9
fix(ci): limit fork PR precheck to safety signals (#6178)
* fix(ci): narrow fork PR precheck gating

* fix(ci): scan PR text for leaked secrets

* test(ci): avoid token-shaped precheck fixtures

* fix(ci): trust write-access fork authors in precheck

* fix(ci): address precheck review findings

* fix(ci): resolve precheck review findings

* fix(ci): catch multiline secret sink args
2026-07-02 20:56:41 +08:00
易良
e1e99f76ff
ci: add autofix PR preparation skill (#6184) 2026-07-02 10:40:36 +00:00
易良
262186cc18
fix(ci): diagnose autofix publish credentials (#6162)
* fix(ci): diagnose autofix publish credentials

* fix(ci): harden autofix credential diagnostics
2026-07-02 07:50:08 +00:00
Shaojin Wen
60c2a639ec
fix(ci): create precheck comments via REST (#6156) 2026-07-02 13:52:42 +08:00
易良
505430320f
fix(ci): fall back to latest autofix sandbox image (#6159)
* fix(ci): fall back to latest autofix sandbox image

* fix(ci): satisfy autofix workflow lint

---------

Co-authored-by: Shaojin Wen <shaojin.wensj@alibaba-inc.com>
2026-07-02 13:52:33 +08:00
易良
3026db3039
fix(ci): allow prechecked fork PR automation (#6160)
* fix(ci): allow triage for fork PRs that pass safety precheck

Fork PRs by non-write authors were blocked from triage even when the
safety precheck passed, because the authorize job gates on write
permission. Triage is read-only (checks out trusted base code, reads PR
via API), so precheck pass is sufficient to run it safely.

Split the pull_request_target and issue_comment authorization paths:
- pull_request_target: accept write permission OR precheck pass
- issue_comment /triage: still require write permission on the commenter

tmux-testing is unchanged — it executes PR code and must keep the write
permission gate.

* fix(ci): allow prechecked fork PR automation

* docs(ci): clarify PR review authorization routing

* test(ci): guard fork precheck authorization

* fix(ci): tighten fork precheck review guards

* test(ci): guard review-request authorization
2026-07-02 13:52:25 +08:00
易良
4537cc3c71
fix(ci): use CI_BOT_PAT for precheck comment on fork PRs (#6151)
Some checks are pending
E2E Tests / E2E Test (Linux) - sandbox:docker (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:none (push) Waiting to run
E2E Tests / E2E Test - macOS (push) Waiting to run
* fix(ci): use CI_BOT_PAT for precheck comment on fork PRs

The precheck workflow's "Upsert/Clear manual approval comment" steps
fail with HTTP 403 on fork PRs because `github.token` from
`pull_request_target` via `workflow_call` lacks sufficient permissions
to read/write issue comments.

- Use `secrets.CI_BOT_PAT || github.token` for the comment steps
- Add `secrets: inherit` to both caller workflows so the reusable
  workflow can access CI_BOT_PAT
- Drop the `.user.login == "github-actions[bot]"` filter from the jq
  query since the HTML comment marker is sufficient and the posting
  user may differ depending on which token is used

* fix(ci): scope precheck comment dedup to known bot users

Narrow the jq filter to match comments from github-actions[bot],
qwen-code-ci-bot, or any Bot-type user — prevents a manually posted
marker from hijacking the dedup logic.

* ci: pass only precheck bot token
2026-07-02 03:04:37 +00:00
Shaojin Wen
b1c5950606
fix(ci): list workflow comments with GET (#6148) 2026-07-02 02:14:45 +00:00
Shaojin Wen
fd76550924
fix(ci): grant PR review precheck permissions (#6147) 2026-07-02 00:14:09 +00:00
易良
9031d09af3
ci: persist npm cache on self-hosted runners (#6130) 2026-07-01 19:56:07 +00:00
易良
32d2f4674d
ci: add fork PR safety precheck (#5926)
* ci: add fork PR safety precheck

* fix(ci): lint PR safety precheck script
2026-07-01 19:31:25 +00:00
易良
1287ac10ca
ci: stabilize actionlint on self-hosted runners (#6113) 2026-07-01 09:25:42 +00:00
易良
66521d8a0e
ci(autofix): fix scheduled and labeled issue triggers (#6080)
* ci(autofix): fix scheduled and labeled issue triggers

* ci(autofix): harden issue label routing

* ci(autofix): scope manual forced routing

* ci(autofix): address routing review comments

* ci(autofix): clarify issue routing comments

* fix(ci): address autofix routing review

* fix(ci): reuse issue label trigger guard

* fix(ci): preserve manual autofix issue override

* fix(ci): guard autofix label routing

* fix(ci): check autofix label sender permission

* fix(ci): address autofix route review comments

* fix(ci): serialize autofix issue runs
2026-07-01 16:23:12 +08:00
Gaurav
fc184f20e5
fix(deps): clear critical runtime audit findings (#6065)
* fix(deps): clear critical runtime audit findings

* fix(core): allow intentional worktree hooks path setup
2026-07-01 05:28:32 +00:00
Shaojin Wen
52f875a875
ci(workflows): remind authors not to force-push active PRs (#6035)
* ci(workflows): remind authors not to force-push active PRs

Add a workflow that detects force-pushes (rebase/amend/reset) to open PRs
via the pull_request_target synchronize event and posts a one-time,
bilingual reminder that force-pushing invalidates existing review comments
and that the integration bots squash all changes into a single commit
automatically. A normal push (compare status "ahead") is ignored; the
reminder is posted at most once per PR, bot-initiated pushes are skipped,
and a failed compare is treated conservatively (no comment).

* ci(workflows): address review — add issues:write, serialize without cancel

- Add `issues: write`: the listComments/createComment calls go through the
  Issues API; declaring it matches the repo's other PR-commenting workflows
  and avoids any risk of a 403 making the workflow inert.
- Set `cancel-in-progress: false`: an in-flight run that already detected a
  force-push must finish and post. The concurrency group still serializes
  runs per PR, and the once-per-PR marker prevents duplicates, so later
  pushes queue and then no-op instead of cancelling (and silently dropping)
  a pending reminder.

* ci(workflows): harden force-push detection per review

- Marker dedup now requires the comment to be from github-actions[bot], so a
  user pasting the marker string into a comment can't suppress reminders.
- Skip known automation logins (qwen-code-dev-bot et al.) that push via PAT as
  sender.type 'User', not just GitHub App bots (mirrors qwen-autofix KNOWN_BOTS).
- Narrow the compare catch to 404 (orphaned old tip -> skip); rethrow other
  errors so auth/rate failures go red instead of silently no-op'ing.
- Wrap createComment with structured error logging + rethrow.

Kept 3-dot compare and base-repo owner: verified that 3-dot returns
diverged/behind for force-pushes and that the base repo resolves fork-PR
commits, while the suggested 2-dot syntax 404s in the REST API.

* test(ci): add structural test for the force-push reminder workflow

- Add scripts/tests/pr-force-push-reminder-workflow.test.js (runs under
  test:scripts, which CI chains into test:ci). It asserts the trigger, repo
  guard, permissions, serialized concurrency, KNOWN_AUTOMATION sync with
  qwen-autofix, the 3-dot compare on the base repo, 404-vs-rethrow, the marker
  author check, and the bilingual body — locking in the reviewed behaviors.
- Wrap the listComments paginate call in the same core.error + rethrow the
  other two API calls already use.
- Note that KNOWN_AUTOMATION must stay in sync with qwen-autofix.yml KNOWN_BOTS.

* ci(workflows): drop concurrency group, rely on marker for idempotency

A concurrency group keeps at most one pending run per group, so a burst of
pushes can cancel a still-pending force-push run before it reaches the script,
dropping the reminder this workflow exists to post. Remove the group entirely:
every synchronize event now runs independently and is always evaluated, and the
once-per-PR marker provides idempotency. A rare double-post on two
near-simultaneous first force-pushes is the acceptable cost of never silently
missing one. Update the structural test to assert there is no concurrency block.

The reviewer's suggested `queue: max` is not a valid GitHub Actions concurrency
key (only `group`/`cancel-in-progress` are allowed) and fails actionlint.

* test(ci): use Qwen Team header and assert the dedup skip path

- Switch the copyright header to the prevailing `Qwen Team` (14 of 17 sibling
  test files use it; this file had copied an older Google LLC header).
- Assert the idempotency skip log line so removing the marker guard fails a test.

* test(ci): mechanically enforce KNOWN_AUTOMATION sync with qwen-autofix

Read qwen-autofix.yml's KNOWN_BOTS and assert each login is also skipped here,
so adding a bot there without updating this workflow fails the test instead of
silently drifting. Replaces the hardcoded login list whose comment overclaimed
that the sync was verified.
2026-06-30 14:55:00 +00:00
易良
c5fb9fd1e7
fix(ci): create isolated home before tests (#6071)
Some checks are pending
E2E Tests / E2E Test (Linux) - sandbox:docker (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:none (push) Waiting to run
E2E Tests / E2E Test - macOS (push) Waiting to run
2026-06-30 12:42:44 +00:00
易良
7f34cdabe1
fix(ci): stabilize merge queue checks (#6056) 2026-06-30 10:27:15 +00:00
jinye
565e4bc437
fix(cli): Guard serve fast-path bundle closure (#5995)
* fix(cli): guard serve fast-path bundle closure

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* test(cli): tighten serve fast-path bundle guard

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#5995)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#5995)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* codex: address PR review feedback (#5995)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

---------

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-06-29 14:38:32 +00:00
qqqys
30c35781b3
ci(autofix): loosen issue candidate filters so the agent finds work (#5860)
* ci(autofix): loosen issue candidate filters so the agent finds work

The scheduled issue phase had been finding 0 candidates on every run. Tier-1
requires the rarely-applied status/ready-for-agent label, and tier-2's
"unattended = no human comment at all" rule fought its ">2 days old" age
gate: on a busy repo every aged bug already has a community reply, so the
funnel collapsed (128 aged bugs -> 0 survivors) purely on the comment rule.

- Unattended now keys off maintainer engagement (OWNER/MEMBER/COLLABORATOR
  comments, excluding our own bots), not any human comment. Community
  "+1"/"me too" no longer disqualifies an issue.
- Tier-1 and tier-2 are always both gathered (tier-1 prioritized, then
  de-duped by number) so a single weak ready-for-agent issue can't starve
  the run.
- Tier-2 scans a bounded age window via MIN_ISSUE_AGE_DAYS..MAX_ISSUE_AGE_DAYS
  (1..15) to focus on fresh, settled bugs instead of an unbounded set.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(ci): preserve autofix issue tier priority

* fix(ci): keep ready autofix issues in tier one

* fix(ci): reserve autofix tier two slots

* fix(ci): tolerate tier two autofix scan failures

* fix(ci): tolerate tier one autofix scan failures

* fix(ci): harden autofix candidate merging

* fix(ci): harden autofix issue scanning

* fix(ci): harden autofix diagnostics

* fix(ci): skip unsafe autofix comment fallbacks

* fix(ci): drop unused autofix comments payload

* test(ci): strengthen autofix comment refresh guard

* test(ci): satisfy autofix workflow lint

* test(ci): tighten autofix tier two assertion

* test(ci): cover autofix tier merge guards

* test(ci): cover autofix unattended filter

* fix(ci): summarize autofix comment refresh drops

* fix(ci): bound autofix tier-2 comment-refresh API calls

Cap the tier-2 issues fed into the comment-refresh loop to 15 (a margin
above the ~10 ever selected, since filter_unattended_candidates drops
attended issues afterward) and request full pages with per_page=100, to
avoid GitHub secondary rate limits. Add workflow tests asserting the
forced-issue skip/in-progress exclusion and the tier-2 ready-for-agent
label exclusion stay in place.

Co-Authored-By: Qwen-Coder <noreply@qwen.ai>

* fix(ci): refresh all scanned tier-2 autofix issues, not just first 15

The previous change capped comment-refresh to the first 15 tier-2 issues
before filter_unattended_candidates runs. The scan still fetches 30, so
valid unattended bugs at positions 16-30 were never refreshed nor
filterable: if the first 15 were all maintainer-attended/dropped, the run
could end with zero candidates again — the failure this PR set out to fix.

Drop the .[0:15] refresh cap and refresh the full scanned set (already
bounded by --limit 30 on the scan). per_page=100 stays as the
pages-per-issue rate-limit mitigation, and the drop summary total/counters
reflect the full refreshed set again. Top-N selection after filtering is
unchanged.

Co-Authored-By: Qwen-Coder <noreply@qwen.ai>

* fix(ci): order tier priority before recency in autofix assess prompt

The assess prompt gave two conflicting selection rules: the tier note says not to pick a tier-2 issue over a comparably actionable tier-1 one, while the recency tiebreaker says to prefer the most recently reported. Since tier-1 has no age bound and tier-2 is the recent (1-15 day) tier, these point in opposite directions for comparable confidence. Make recency apply only after the tier preference and only within the same tier, removing the contradiction. Prompt text only; no shell/jq change.

Co-Authored-By: Qwen-Coder <noreply@qwen.ai>

* fix(ci): guard forced-issue jq and derive autofix comment scratch path

Address two review suggestions on the autofix candidate scan step.

- Wrap the forced-issue candidate jq in the same error guard the other
  jq calls use (tier-1/tier-2 stamp, tier merge): on malformed
  forced-issue JSON it now emits a :⚠️: and falls back to an empty
  candidate list instead of silently producing an empty candidates.json
  with no diagnostic.
- Make refresh_issue_comments reuse-safe by deriving its NDJSON scratch
  path from the output_file parameter (${output_file%.json}.ndjson)
  instead of hardcoding tier2-with-comments.ndjson, so a second call or a
  different tier can't clobber a shared scratch file. Behavior for the
  current single call is unchanged.

Co-Authored-By: Qwen-Coder <noreply@qwen.ai>

---------

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Co-authored-by: Qwen-Coder <noreply@qwen.ai>
2026-06-28 23:00:13 +00:00
易良
f876f4a250
ci: allow longer PR review timeout retries (#5961) 2026-06-28 15:41:04 +00:00
Shaojin Wen
680f523853
ci(review): increase PR review timeout from 90 to 120 minutes (#5959)
Large PRs with extensive diffs across multiple packages can exceed
the 85-minute effective review window (90 - 5 buffer). The recent
run #28318973107 timed out on PR #5777 which touched acp-bridge,
serve, config, and chrome-extension packages.

Bump both the job timeout-minutes and the validation cap to 120 so
the review agent has enough headroom for complex multi-package PRs.
2026-06-28 12:53:48 +00:00
Salman Chishti
34678cfbd9
Upgrade GitHub Actions to latest versions (#3683)
Some checks are pending
E2E Tests / E2E Test (Linux) - sandbox:docker (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:none (push) Waiting to run
E2E Tests / E2E Test - macOS (push) Waiting to run
* Upgrade GitHub Actions to latest versions

Signed-off-by: Salman Muin Kayser Chishti <13schishti@gmail.com>

* ci: restore ratchet annotations on upgraded actions

The action version bumps had replaced '# ratchet:owner/repo@<ver>'
annotations with bare '# vX.Y.Z' comments, which silently breaks
ratchet's ability to track and update these SHA pins. Restore the
annotations on every changed line (updated to the new major), matching
each line's pre-existing convention on main.

---------

Signed-off-by: Salman Muin Kayser Chishti <13schishti@gmail.com>
Co-authored-by: qwen-code-dev-bot <qwen-code-dev-bot@users.noreply.github.com>
Co-authored-by: yiliang114 <effortyiliang@gmail.com>
2026-06-27 17:03:32 +00:00
易良
2583b5c7dd
feat(cli): add /model --vision for a fallback vision model (#5778)
* feat(cli): add /model --vision for a fallback vision model

Add `/model --vision <id>` and an interactive vision-model picker to
configure an image-capable model the vision bridge borrows when a
text-only main model receives an image, mirroring the `/model --fast`
pattern (flat `visionModel` setting + runtime `setVisionModel`). An
explicit vision model takes precedence over same-provider auto-select and
may cross providers; an unreachable pin falls back to auto-select rather
than firing the bridge at a model it can't reach.

Also fixes two vision-bridge issues surfaced while verifying #5126:

- The gate read stale modalities after a runtime model switch, so an
  @image sent right after switching to a multimodal model could still
  trigger the bridge. Refresh model-derived modalities on the qwen-oauth
  hot-update paths (setModel default-model + handleModelChange) so the
  gate reflects the current model.
- The transcription was appended after a now-empty "Content from <file>:"
  header, leading the primary model to re-read the image file and ignore
  the transcript. Stand the transcription in the image's slot and tell the
  model the image cannot be read by a tool.

Closes #5597

* fix(cli): add vision model description translations

* feat(cli): warn on non-image-capable /model --vision pin; cover modality refresh

Self-review follow-ups on the /model --vision work:

- Warn (but still honor) when /model --vision or the picker pins a model that
  isn't image-capable, reusing the vision bridge's isImageCapable so the
  explicit and auto-select paths agree on what counts as vision-capable.
  isImageCapable is now exported for the CLI to share.
- Exclude fastOnly models from --vision validation so it matches the
  completion filter.
- Add a Config-level test asserting handleModelChange refreshes modalities on
  the qwen-oauth hot path (the vision-bridge gate fix that lacked direct
  coverage).

* fix(cli): translate the non-image-capable vision model warning

Add zh/zh-TW/en entries for the /model --vision picker warning shown when a pinned model isn't image-capable, matching the existing vision-string translations.

* fix(vision-bridge): stop showing the image transcription twice

The vision bridge printed the full transcription in its notice AND fed it to
the primary model, which then re-stated it — so the user read the same image
description twice (once in the notice box, once in the answer).

- The notice now shows only the egress-disclosure header; the transcription is
  fed to the primary model and surfaced in its answer, so it is no longer
  duplicated. Removes the now-unused transcript truncation / control-char
  stripping helpers.
- The bridge model is instructed to transcribe/describe, not answer the user
  request (the user's intent is carried as a focus hint, not a question), so its
  output is context for the primary model rather than a second competing answer.

* fix(cli): register vision model i18n strings and cover /model --vision

- Register 'Vision Model' / 'Select Vision Model' in en/zh/zh-TW so the
  vision picker and confirmation aren't English-only for non-English users
  (mirrors the existing Voice Model entries).
- formatNonVisionModelWarning reuses the dialog's already-registered t()
  key instead of a plain English literal, keeping both paths i18n-consistent.
- Add the missing bare '/model --vision' tests (interactive dialog +
  non-interactive current-model report), mirroring the --voice coverage.

* refactor(vision-bridge): remove dead VisionBridgeResult.transcript field

The inline transcript display was dropped in 14de33333 (it duplicated the
description already fed to the primary model), leaving `transcript` set on
the result but never read in any production path. Remove the field and its
now-redundant test — the untrusted-wrapper assertion it carried is already
covered by 'converts images to an untrusted text block on success'.

* test(cli): cover vision-model branches; dedupe fast/vision helpers

Refactor (behavior-neutral):
- modelCommand.ts: fold identical formatUnavailableFast/VisionModelMessage
  bodies into formatUnavailableAuxModelMessage(label, hint).
- ModelDialog.tsx: extract the fast/vision selection-key parsing into
  encodeAuxModelSelector(); voice keeps using the model id directly.

Tests:
- config: malformed pin (catch branch) falls back instead of throwing;
  authType-qualified visionModel binds to the matching provider only;
  setVisionModel('')/undefined clears back to auto-select.
- modelCommand: authType-scoped vision rejection message.
- ModelDialog: non-image-capable pin emits the warning in history.

* test(cli): vision-mode coverage + register --vision completion i18n key

- i18n: register the `--vision` completion description key in en/zh/zh-TW
  (was wrapped in t() with no entry, so non-English showed English).
- useModelCommand: test vision mode opens + suppresses fast, resets on close.
- modelCommand: test --vision rejects fastOnly/voiceOnly models.

Also corrects the stale "30-minute" wait-timer comment in
qwen-code-pr-review.yml (actual env timer is 10m; point to repo settings).

* fix(core): exclude primary model from explicit vision bridge selection

resolveVisionModelSelection lacked the m.id !== primary guard that the
auto-select path (selectVisionBridgeModel) already has, so pinning the
text-only primary via /model --vision would fire the bridge at a model
that cannot read images. Mirror the auto-select guard.

* chore(core): log vision bridge transcription for traceability

The transcription is no longer surfaced to the user or carried on the
result; log it at debug so a wrong primary-model answer can be traced to
a misread image vs a downstream hallucination.

* test: cover vision model helpers and vision-model dialog dispatch

Add direct unit tests for encodeAuxModelSelector (3 key shapes) and
isImageCapable (isVision/modalities/name-fallback), and a dispatch test
for the /model --vision dialog case mirroring voice-model.

* fix(cli): render vision bridge notice as a dim tip, drop doubled marker

The success/cancelled vision-bridge notice was added as MessageType.INFO
(primary-color `●` gutter) while its text also led with `🔎`, producing a
doubled `● 🔎` marker. Route success/cancelled notices to a new dim
`vision_notice` variant (secondary color, single `🔎` gutter glyph) and
strip the baked-in glyphs from the notice text so the renderer owns the
prefix. Failures keep the prominent red `✕` ERROR variant (also
de-duplicated).

* test(cli): assert VISION_NOTICE type for mid-turn vision bridge notice

* test(cli): cover vision_notice classification and rendering

* fix(vision): harden vision-bridge model selection + UX

Address review feedback on #5778:
- config: provider-aware isCurrentPrimaryModel() so a cross-provider namesake
  (e.g. anthropic:shared-model vs an openai shared-model primary) stays an
  eligible vision pin; resolveVisionModelSelection now also filters fast/voice-
  only models (a settings.json pin bypasses the slash command) and warns on
  every silent-drop path so a stale pin is debuggable.
- modelCommand/ModelDialog: reject pinning the current primary as the vision
  model at set time (ignored at runtime) instead of persisting a dead pin.
- useModelCommand: vision mode suppresses voice so the dialog can't end up in
  two specialized modes at once.
- HistoryItemDisplay: vision_notice gets 0 top margin like its notice peers.
- vision-bridge-service: log transcription metadata only (model + length),
  never the raw text — screenshots carry tokens/PII and debug logs can be
  shared in support bundles.

PR #5778.

* fix(vision): fail-closed bridge routing, ambiguity guards, i18n, settings, tests

Address the remaining #5778 review feedback:
- baseLlmClient/sideQuery/vision-bridge: add an opt-in `failClosed` to the
  per-model resolve path; the vision bridge sets it so a missing cross-provider
  credential fails the conversion instead of silently routing image payloads at
  the text-only main generator (which BaseLlmClient otherwise falls back to).
- ModelDialog: reject a vision pin that maps to multiple same-provider endpoints
  (the persisted authType:modelId can't disambiguate base URLs), mirroring the
  voice-mode duplicate guard.
- modelCommand: wrap the non-interactive vision status message in t() with
  en/zh/zh-TW locale entries.
- SettingsDialog: wire the Vision Model row into the sub-dialog dispatch so Enter
  / Right-Arrow open the picker (like fastModel).
- image-part-utils: document the multi-image drop / "don't read_file" contract.
- tests: fail-closed resolve paths, primary-guard fallback, vision initialIndex,
  authType-qualified + malformed vision selectors, failure-path image removal.

PR #5778.

---------

Co-authored-by: Shaojin Wen <shaojin.wensj@alibaba-inc.com>
Co-authored-by: yiliang114 <effortyiliang@gmail.com>
2026-06-27 12:51:11 +00:00
易良
8189141160
[codex] test(ci): cover post-merge review follow-ups (#5899)
* test(ci): cover post-merge review follow-ups

* test(core): scope skill activation timeout override
2026-06-26 22:08:57 +00:00
顾盼
adc2bce414
feat(cua-driver): vendor qwen-cua-driver with opt-in 0–1000 relative coordinates (#5896)
* feat(cua-driver): vendor trycua/cua driver with 1000-normalized coordinate support

Vendor libs/cua-driver from trycua/cua into packages/cua-driver as the
basis for qwen-code's computer-use backend, adding an opt-in relative
(1000x1000 normalized) coordinate mode for Qwen-VL clients.

- coord_norm.rs: 0-1000 <-> pixel conversion, per-(pid,window_id) size
  cache, tools/list description rewrite (TDD, 27 tests)
- ToolRegistry: normalized field + invoke input/output hooks
- protocol.rs: system-instruction coordinate wording switched by mode
- serve.rs: daemon list path description rewrite (input_schema aware)
- main.rs: CUA_DRIVER_RS_COORDINATE_SPACE env seed

Default coordinate_space=pixels => zero behavior change for existing
pixel clients. Set CUA_DRIVER_RS_COORDINATE_SPACE=normalized_1000 to
enable. Excludes rust/target build output.

* feat(cua-driver): make normalized coordinate scale configurable

Add CUA_DRIVER_RS_COORDINATE_SCALE (default 1000) so the normalization
full-scale can absorb the Qwen 999-vs-1000 cookbook ambiguity without a
recompile. norm_to_px/px_to_norm now take an explicit scale; denormalize_args
reads the process-wide COORDINATE_SCALE seeded once at startup from env.

* ci(cua-driver): add cross-platform release workflow for vendored driver

Standalone GitHub Action that builds, signs, and releases the vendored
cua-driver under packages/cua-driver. Adapted from upstream trycua/cua
cd-rust-cua-driver.yml:

- macOS: universal binary (lipo arm64+x86_64), codesigned + notarized into
  CuaDriver.app using qwen-code's existing secrets (MAC_CSC_LINK cert +
  App Store Connect API key notarization); Developer ID identity is
  auto-discovered from the imported cert.
- Linux: x86_64 + arm64, built in debian:11 for a glibc 2.31 floor.
- Windows: x86_64 + arm64, unsigned (no EV cert, matches upstream).
- Release: softprops/action-gh-release on cua-driver-rs-v* tags or manual
  dispatch, prerelease.

Triggered by tag push (cua-driver-rs-v*) or workflow_dispatch.

* chore(cua-driver): rebrand vendored driver as qwen-cua-driver

Rename the vendored trycua/cua driver so the fork installs and runs
independently of any upstream trycua install:
- binary cua-driver -> qwen-cua-driver
- bundle CuaDriver.app -> QwenCuaDriver.app
- bundle id com.trycua.driver -> com.qwencode.cua-driver

Updates the cargo/uia manifests, Info.plist, bundle/proxy launch paths,
permission/health-report wording, the install/build scripts, and the
cross-platform release workflow.

* feat(cua-driver): finish relative-coordinate mode — toggle, scale, zoom/move_cursor

- CUA_DRIVER_RS_COORDINATE_SPACE is now a 1/0 toggle (via is_env_truthy);
  default off keeps pixel mode byte-identical to upstream.
- Thread CUA_DRIVER_RS_COORDINATE_SCALE through every coordinate surface
  (was hardcoded 1000): input denormalization already used it; now the
  rewritten screenshot dims, the tool/param descriptions, and the agent
  instructions track the configured scale too.
- Normalize zoom (window basis) and move_cursor (screen basis) inputs and
  rewrite their descriptions, alongside click/double_click/right_click/drag.
- Fix zoom on downscaled (Retina) windows: apply the get_window_state resize
  ratio so the crop lands on the region the agent saw. Normalized mode only;
  pixel-mode zoom unchanged.

All coordinate behavior stays gated on the normalized flag, so the default
(pixels) path is unchanged from upstream.

* chore(cua-driver): add upstream-sync script (git subtree unusable here)

`git subtree split --prefix=libs/cua-driver` hangs on a commit deep in
trycua/cua's history, so the subtree add/pull workflow isn't usable for
the vendored driver (and a pull would re-split + re-hang every time).

Add scripts/sync-from-upstream.sh instead: it git-diffs two upstream refs
(never walks the full history, so it dodges the hang), reprefixes the
libs/cua-driver delta to packages/cua-driver, and `git apply --reject`s it
on top of our local changes — conflicts land as *.rej for manual fixup.
Record the vendored version in .vendored-from and document the migration +
sync method in the design doc.

* chore(cua-driver): exclude vendored driver from qwen-code ESLint

The vendored packages/cua-driver tree carries upstream JS (e.g. the
test-harness Electron app) that doesn't follow qwen-code's lint rules and
fails CI. It is not a workspace package (no package.json) and is not
qwen-code TypeScript, so add it to eslint.config.js global ignores —
alongside packages/desktop/** — the standard treatment for vendored code.

* fix(cua-driver): let start_session revive an idle-reaped session

Ports the fix from upstream trycua/cua#2035 into the vendored driver.

When a session is reaped for idleness, a subsequent start_session with the
same id failed instead of resuming it. Revive the ended session in place so
the agent can continue rather than getting a hard error.

* fix(cua-driver): retry daemon socket writes on EAGAIN

Ports the fix from upstream trycua/cua#2036 into the vendored driver.

A non-blocking daemon socket can return EAGAIN/EWOULDBLOCK mid-write when the
peer's receive buffer is momentarily full. The driver treated that as fatal
and dropped the connection. Add a bounded retry/poll loop (mirror of the
read-side socket_io helper) so transient back-pressure no longer kills the
session; only a real timeout or hard error fails the write.

* fix(cua-driver/linux): stop reporting bare "Clicked" for X11 synthetic clicks

Ports the fix from upstream trycua/cua#2025 into the vendored driver.

On X11, clicks are delivered via XSendEvent synthetic events, which many
toolkits (GTK/SDL/Allegro) ignore because send_event is set. The driver still
reported a flat success ("Clicked"), masking that nothing happened. Report
the synthetic-delivery caveat honestly so the agent can fall back instead of
assuming the click landed.

(platform-linux crate is not built on macOS; verified by clean upstream apply
and covered by upstream + release-workflow Linux CI.)

* fix(cua-driver/windows): list empty-/null-title top-level windows

Ports the fix from upstream trycua/cua#2021 into the vendored driver.

list_windows filtered out any top-level window whose title was empty or null,
so legitimate targets (splash screens, some Electron/game windows, tool
windows) were invisible to the agent and unclickable. Include empty-title
windows, using class name / process as a fallback label.

(platform-windows crate is not built on macOS; verified by clean upstream
apply and covered by upstream + release-workflow Windows CI.)

* chore(cua-driver): track cherry-picked upstream PRs; fix vendored-from

The vendored copy is actually at cua-driver-rs-v0.6.7 (workspace version and
all 0.6.7->0.6.8 delta files confirm it), but .vendored-from had drifted to
0.6.8 during an earlier sync-script trial whose code delta was not kept. Left
as-is it would make a future sync diff 0.6.8->newer and silently skip the real
0.6.7->0.6.8 fixes. Correct it back to 0.6.7.

Also record the four not-yet-merged upstream PRs we carry as cherry-picks
(trycua/cua#2021/#2025/#2035/#2036) in .vendored-patches.md, and have
sync-from-upstream.sh point at it so the next sync reconciles them.

* ci(cua-driver): satisfy repo yamllint on the release workflow

The vendored-driver release workflow tripped 114 quoted-strings violations
under the repo's .yamllint (quote-type: single, required). Single-quote all
string scalars to match every other workflow in .github/workflows.

While reformatting, the release-notes body also got its paragraph blank lines
collapsed and still referenced the old CUA_DRIVER_RS_COORDINATE_SPACE=
normalized_1000 value — restore the blank lines and update it to the current
0/1 toggle (default 0 = off; optional CUA_DRIVER_RS_COORDINATE_SCALE=1000).

* chore(cua-driver): sync vendored driver to cua-driver-rs-v0.6.8

First real run of scripts/sync-from-upstream.sh: it 3-way-applied the upstream
0.6.7->0.6.8 delta onto our local fork. 10/12 files applied cleanly; the 2
rejects (install.ps1, _install-rust.sh) were already-applied baked-version
bumps (0.6.6->0.6.7, our copies were already at 0.6.7), i.e. no real conflict.

0.6.8 brings: Wayland input path (platform-linux), linux health_report +
overlay tweaks, a platform-macos build.rs step, and dependency bumps. Version
moved to 0.6.8 across the workspace.

Verified our work survived the sync untouched: the relative-coordinate shim
(coord_norm/protocol) and all four cherry-picked PRs (socket_io/session +
linux/windows) are intact — in particular the 0.6.8 edit to platform-linux
tools/impl_.rs landed alongside our #2025 change with no collision. macOS
cargo check + 132 core tests green. (platform-linux/windows + the binary
integration test build only on their own runners; upstream CI covers those.)

* ci(cua-driver): add a dry_run gate to the release workflow

Mirror the desktop-release / release dry-run pattern: a workflow_dispatch
dry_run boolean input (default true). The cross-platform build + package jobs
always run and upload their artifacts; the GitHub Release job now publishes
only on a tag push or an explicit dry_run=false dispatch.

Lets us rehearse the whole build/package pipeline (dry_run=true, notarize=false)
and inspect the produced artifacts without cutting a release. A branch push
(no tag, not a dispatch) likewise builds without releasing.
2026-06-26 13:06:43 +00:00
易良
91bf331cc6
ci: isolate per-run agent state for triage and PR review (#5885)
Both the triage job and the PR-review job run the qwen agent directly on
the persistent self-hosted ECS pool with no per-run isolation. $HOME,
/tmp and the workspace are reused between runs, so a prior run's agent
session/memory (default ~/.qwen) or leftover draft comments
(/tmp/stage-*.md, which survive git clean) can bleed into the next run.

This surfaced on #5874: its triage posted #5872's review verbatim
(wrong author, wrong approver, wrong diff), while the same run's internal
stage actually exercised #5874 — the PR id was correct, the agent state
was stale.

Point QWEN_HOME at a per-run $RUNNER_TEMP/qwen-home on the Qwen step and
reset it (plus /tmp/stage-*.md) in the pre-run cleanup, for both jobs.
QWEN_HOME relocates the entire global qwen dir (storage.ts), so this
isolates sessions/memory/temp without touching $HOME and disturbing
git/npm. The tmux-testing job is already container-isolated and unchanged.

Refs #5882
2026-06-26 07:09:27 +00:00
易良
096bba13d5
ci(qwen-resolve): support fork PRs and slim /resolve to conflict-only (#5870)
* ci(qwen-resolve): support fork PRs and slim /resolve to conflict-only

Closes the fork gap #5779/#5862 left for the maintainer /resolve command, so it
can clear merge conflicts on community (fork) PRs, and narrows the command to
exactly one job: resolve the conflict and push it back.

- Fork PRs: fetch the head via refs/pull/N/head and push the resolved branch
  back to the PR's head repository (via Allow edits by maintainers) instead of
  bailing as unsupported. Validated end-to-end against a fork PR.
- Conflict-only: drop the build/typecheck/lint/test gate and npm install/refresh;
  keep the structural checks (markers, index, merge-tree, default-merge, scope).
  Test fallout is left to the PR's own CI and follow-up tasks.
- Push-failure classification: workflow_scope (the merge carries the base's
  .github/workflows/** changes, which a token without the workflow scope cannot
  push), permission (403 / 404), and moved (stale force-with-lease) each get an
  actionable comment; the redacted git stderr is logged for diagnosis.

NOTE: the push bot's PAT (CI_DEV_BOT_PAT) needs the `workflow` scope, since
resolving merges the base in and that update touches workflow files.

Guard tests updated; 12/12 pass.

* ci(qwen-resolve): avoid PR head ref collisions

* ci(qwen-resolve): address review comments

- workflow_scope: anchor classification on GitHub's server phrase
  'refusing to allow ... workflow' instead of a loose workflow.*scope, which
  the attacker-controlled branch name in git's rejected-ref echo could trip.
- prepare: bail when the head repository was deleted (null headRepository →
  malformed push URL).
- moved: include the run-artifact link, consistent with the other cases.
- permission: drop 'could not read' (matched transient network errors).
2026-06-25 14:52:58 +00:00
易良
068ca279cf
ci(qwen-resolve): run the /resolve job on a hosted runner (#5862)
The conflict-resolution agent step runs with `sandbox: true`, which on
Linux needs docker or podman to launch the sandbox. The self-hosted ECS
pool ships no container runtime, so the job died at the agent step
(exit 44, "failed to determine command for sandbox") before it could
resolve anything — see run 28158417390.

Pin the job to ubuntu-latest, which ships docker and is ephemeral (a
good fit for running the untrusted PR's build/lint/test in the
verification gate). Update the cleanup and PAT-scrub comments that
assumed a reused self-hosted workspace; both steps stay as defensive
no-ops on hosted runners.
2026-06-25 11:07:18 +00:00