From 444c56b27f56e6ef9fa75c0b00402d3c9ad07630 Mon Sep 17 00:00:00 2001 From: yiliang114 Date: Sun, 19 Jul 2026 15:58:32 +0800 Subject: [PATCH 1/5] ci: add ECS runner qwen update workflow --- .github/workflows/update-ecs-runner-qwen.yml | 58 ++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 .github/workflows/update-ecs-runner-qwen.yml diff --git a/.github/workflows/update-ecs-runner-qwen.yml b/.github/workflows/update-ecs-runner-qwen.yml new file mode 100644 index 00000000000..2baf509784a --- /dev/null +++ b/.github/workflows/update-ecs-runner-qwen.yml @@ -0,0 +1,58 @@ +name: 'Update ECS Runner Qwen' + +on: + workflow_dispatch: + inputs: + version: + description: 'Optional. Empty means latest from npm.' + required: false + default: '' + type: 'string' + +permissions: + contents: 'read' + +concurrency: + group: 'update-ecs-runner-qwen-sg' + cancel-in-progress: false + +jobs: + update: + name: 'Update Qwen on Singapore ECS runner' + if: "${{ github.repository == 'QwenLM/qwen-code' }}" + runs-on: ['self-hosted', 'linux', 'x64', 'ecs-qwen-runner-sg'] + timeout-minutes: 10 + steps: + - name: 'Resolve version' + id: 'version' + env: + INPUT_VERSION: '${{ inputs.version }}' + run: |- + version="${INPUT_VERSION#v}" + if [[ -z "${version}" ]]; then + version="$(npm view @qwen-code/qwen-code version)" + fi + echo "version=${version}" >> "${GITHUB_OUTPUT}" + echo "Resolved qwen version: ${version}" + + - name: 'Update qwen' + env: + VERSION: '${{ steps.version.outputs.version }}' + run: |- + prefix="$(npm prefix -g)" + if [[ -w "${prefix}" ]]; then + npm install -g "@qwen-code/qwen-code@${VERSION}" + elif command -v sudo >/dev/null 2>&1 && sudo -n true; then + sudo npm install -g "@qwen-code/qwen-code@${VERSION}" + else + echo "::error::Global npm prefix ${prefix} is not writable and passwordless sudo is unavailable." + exit 1 + fi + + - name: 'Verify version' + env: + VERSION: '${{ steps.version.outputs.version }}' + run: |- + actual="$(qwen --version)" + echo "qwen version: ${actual}" + test "${actual}" = "${VERSION}" From 0e095147e2cd797f22e9f8d930f7404d0379adbd Mon Sep 17 00:00:00 2001 From: yiliang114 Date: Sun, 19 Jul 2026 16:09:03 +0800 Subject: [PATCH 2/5] ci: fix ecs runner qwen update target --- .github/workflows/update-ecs-runner-qwen.yml | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/.github/workflows/update-ecs-runner-qwen.yml b/.github/workflows/update-ecs-runner-qwen.yml index 2baf509784a..6d8896ddd02 100644 --- a/.github/workflows/update-ecs-runner-qwen.yml +++ b/.github/workflows/update-ecs-runner-qwen.yml @@ -20,7 +20,7 @@ jobs: update: name: 'Update Qwen on Singapore ECS runner' if: "${{ github.repository == 'QwenLM/qwen-code' }}" - runs-on: ['self-hosted', 'linux', 'x64', 'ecs-qwen-runner-sg'] + runs-on: ['self-hosted', 'linux', 'x64', 'ecs-qwen'] timeout-minutes: 10 steps: - name: 'Resolve version' @@ -28,9 +28,13 @@ jobs: env: INPUT_VERSION: '${{ inputs.version }}' run: |- - version="${INPUT_VERSION#v}" - if [[ -z "${version}" ]]; then - version="$(npm view @qwen-code/qwen-code version)" + specifier="@qwen-code/qwen-code@${INPUT_VERSION#v}" + if [[ "${specifier}" == '@qwen-code/qwen-code@' ]]; then + specifier='@qwen-code/qwen-code@latest' + fi + if ! version="$(npm view "${specifier}" version | tail -n 1)"; then + echo "::error::No published qwen version matches '${INPUT_VERSION:-latest}'." + exit 1 fi echo "version=${version}" >> "${GITHUB_OUTPUT}" echo "Resolved qwen version: ${version}" @@ -39,13 +43,14 @@ jobs: env: VERSION: '${{ steps.version.outputs.version }}' run: |- - prefix="$(npm prefix -g)" - if [[ -w "${prefix}" ]]; then + global_root="$(npm root -g)" + global_bin="$(npm prefix -g)/bin" + if [[ -w "${global_root}" && -w "${global_bin}" ]]; then npm install -g "@qwen-code/qwen-code@${VERSION}" elif command -v sudo >/dev/null 2>&1 && sudo -n true; then sudo npm install -g "@qwen-code/qwen-code@${VERSION}" else - echo "::error::Global npm prefix ${prefix} is not writable and passwordless sudo is unavailable." + echo "::error::Global npm install directories are not writable and passwordless sudo is unavailable." exit 1 fi From afde470c94b3e88a56331b8aa8ac4c45fd610aef Mon Sep 17 00:00:00 2001 From: yiliang114 Date: Sun, 19 Jul 2026 17:28:28 +0800 Subject: [PATCH 3/5] ci: use shallow checkout for review jobs --- .github/workflows/qwen-code-pr-review.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/qwen-code-pr-review.yml b/.github/workflows/qwen-code-pr-review.yml index b60b241390a..19f49227835 100644 --- a/.github/workflows/qwen-code-pr-review.yml +++ b/.github/workflows/qwen-code-pr-review.yml @@ -390,7 +390,7 @@ jobs: uses: 'actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10' # v6.0.3 with: ref: '${{ github.event.repository.default_branch }}' - fetch-depth: 0 + fetch-depth: 1 - name: 'Resolve PR context' id: 'context' @@ -898,7 +898,7 @@ jobs: uses: 'actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10' # v6.0.3 with: ref: '${{ github.event.repository.default_branch }}' - fetch-depth: 0 + fetch-depth: 1 persist-credentials: false - name: 'Set up Node.js' From dfa12a809fd4503501414b5c541fcc5930632496 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=98=93=E8=89=AF?= <1204183885@qq.com> Date: Sun, 19 Jul 2026 20:06:46 +0800 Subject: [PATCH 4/5] fix(ci): repair dead version guard and revert shallow-clone regression - update-ecs-runner-qwen: the `if ! version=$(npm view ... | tail)` guard never fired (a pipeline's exit status is tail's, always 0), so npm view's E404 was masked and an empty version reached `npm install -g @qwen-code/qwen-code@` -> resolves to latest and silently mutates the shared runner. Check for an empty result explicitly instead. - qwen-code-pr-review: revert fetch-depth 0->1 at both base checkouts; shallow clones break merge-base resolution for the /review and /resolve jobs (fetch-pr's merge-base returns null; merge-tree conflict detection degrades to 'unknown'). --- .github/workflows/qwen-code-pr-review.yml | 4 ++-- .github/workflows/update-ecs-runner-qwen.yml | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/qwen-code-pr-review.yml b/.github/workflows/qwen-code-pr-review.yml index 19f49227835..b60b241390a 100644 --- a/.github/workflows/qwen-code-pr-review.yml +++ b/.github/workflows/qwen-code-pr-review.yml @@ -390,7 +390,7 @@ jobs: uses: 'actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10' # v6.0.3 with: ref: '${{ github.event.repository.default_branch }}' - fetch-depth: 1 + fetch-depth: 0 - name: 'Resolve PR context' id: 'context' @@ -898,7 +898,7 @@ jobs: uses: 'actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10' # v6.0.3 with: ref: '${{ github.event.repository.default_branch }}' - fetch-depth: 1 + fetch-depth: 0 persist-credentials: false - name: 'Set up Node.js' diff --git a/.github/workflows/update-ecs-runner-qwen.yml b/.github/workflows/update-ecs-runner-qwen.yml index 6d8896ddd02..692886d98a4 100644 --- a/.github/workflows/update-ecs-runner-qwen.yml +++ b/.github/workflows/update-ecs-runner-qwen.yml @@ -32,7 +32,8 @@ jobs: if [[ "${specifier}" == '@qwen-code/qwen-code@' ]]; then specifier='@qwen-code/qwen-code@latest' fi - if ! version="$(npm view "${specifier}" version | tail -n 1)"; then + version="$(npm view "${specifier}" version | tail -n 1)" + if [[ -z "${version}" ]]; then echo "::error::No published qwen version matches '${INPUT_VERSION:-latest}'." exit 1 fi From a861e052e20613abc9b1553088718c8a5a41c974 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=98=93=E8=89=AF?= <1204183885@qq.com> Date: Sun, 19 Jul 2026 20:56:01 +0800 Subject: [PATCH 5/5] fix(ci): add pipefail to version guard so npm view 404 propagates The resolve step's `npm view ... | tail -n 1` pipeline masked npm's exit status (tail always exits 0). Without pipefail a typo'd or non-existent version produced an empty `version` variable silently; the existing `-z` guard caught it only by accident of empty stdout, not by design. Add `set -euo pipefail` to all three run blocks (matching the convention in qwen-code-pr-review.yml) and append `|| true` to the npm-view assignment so the script reaches the friendly ::error:: annotation instead of dying at the pipeline line. --- .github/workflows/update-ecs-runner-qwen.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/update-ecs-runner-qwen.yml b/.github/workflows/update-ecs-runner-qwen.yml index 692886d98a4..b5cbf99cf97 100644 --- a/.github/workflows/update-ecs-runner-qwen.yml +++ b/.github/workflows/update-ecs-runner-qwen.yml @@ -28,11 +28,12 @@ jobs: env: INPUT_VERSION: '${{ inputs.version }}' run: |- + set -euo pipefail specifier="@qwen-code/qwen-code@${INPUT_VERSION#v}" if [[ "${specifier}" == '@qwen-code/qwen-code@' ]]; then specifier='@qwen-code/qwen-code@latest' fi - version="$(npm view "${specifier}" version | tail -n 1)" + version="$(npm view "${specifier}" version | tail -n 1)" || true if [[ -z "${version}" ]]; then echo "::error::No published qwen version matches '${INPUT_VERSION:-latest}'." exit 1 @@ -44,6 +45,7 @@ jobs: env: VERSION: '${{ steps.version.outputs.version }}' run: |- + set -euo pipefail global_root="$(npm root -g)" global_bin="$(npm prefix -g)/bin" if [[ -w "${global_root}" && -w "${global_bin}" ]]; then @@ -59,6 +61,7 @@ jobs: env: VERSION: '${{ steps.version.outputs.version }}' run: |- + set -euo pipefail actual="$(qwen --version)" echo "qwen version: ${actual}" test "${actual}" = "${VERSION}"