Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
79433e5
fix(ci): route release pipeline Linux jobs to the ECS runner pool
yiliang114 Aug 25, 2026
225fbf5
fix(ci): restore ECS workspace before release checkout
yiliang114 Aug 25, 2026
5c80aad
fix(ci): record release workflow growth
yiliang114 Aug 25, 2026
b276384
fix(ci): isolate release jobs on shared runners
yiliang114 Aug 26, 2026
324809e
fix(ci): bound shared release runner work
yiliang114 Aug 26, 2026
7ce76af
Merge branch 'main' into fix/release-ecs-runners
wenshao Aug 26, 2026
c823f67
Merge commit '7ce76afe6124ad5803e94c954bae38c87c0b079c' into HEAD
yiliang114 Aug 26, 2026
e29c23e
fix(ci): harden the release wipe and pin the docker preflight fail-cl…
yiliang114 Aug 26, 2026
2775857
test(ci): pin the canonical release wipe byte-identical at index 0
yiliang114 Aug 26, 2026
d770f22
Merge branch 'main' into fix/release-ecs-runners
yiliang114 Aug 26, 2026
ecbc499
fix(ci): deduplicate release runner cleanup
yiliang114 Aug 26, 2026
680e794
fix(ci): keep the release failure notifier on hosted runners
yiliang114 Aug 26, 2026
860f4c8
fix(ci): pin the release lanes' conditional ECS runs-on
yiliang114 Aug 26, 2026
d14fb9f
fix(ci): keep release publishing on hosted runners
yiliang114 Aug 26, 2026
132b7cb
fix(ci): fail closed on release git scrub
yiliang114 Aug 26, 2026
dcbaa9a
fix(ci): scrub ambient GIT_CONFIG_GLOBAL from the release wipe test
yiliang114 Aug 26, 2026
cf9c27d
test(ci): add behavioral tests for workspace wipe guard branches
yiliang114 Aug 26, 2026
d22c1a5
Merge branch 'main' into fix/release-ecs-runners
qwen-code-dev-bot Aug 26, 2026
c647666
fix(test): gate wipe behavioral test on GNU realpath, fix '..' path a…
yiliang114 Aug 26, 2026
84559ee
fix(ci): guard chmod -R against symlinked workspace before validation
yiliang114 Aug 26, 2026
909688a
fix(ci): bump release.yml size baseline to accommodate ECS runner cha…
yiliang114 Aug 26, 2026
c8459ae
Merge branch 'main' into fix/release-ecs-runners
qwen-code-dev-bot Aug 27, 2026
30cdb66
fix(test): create the sub directory in the wipe '..' sub-case setup
Aug 27, 2026
3284ce4
Merge remote-tracking branch 'origin/main' into fix/release-ecs-runners
yiliang114 Aug 27, 2026
5c5071e
fix(ci): skip ECS cleanup on hosted release jobs
yiliang114 Aug 27, 2026
da5b977
fix(ci): isolate persistent release runner state
yiliang114 Aug 27, 2026
d03d94f
fix(ci): accept the pool's sibling tool cache in the release wipe
yiliang114 Aug 27, 2026
3f9da8d
fix(ci): refuse a symlinked runner workspace before the release wipe
yiliang114 Aug 27, 2026
ec694c0
fix(ci): isolate gh config from the persistent pool HOME
yiliang114 Aug 27, 2026
b45ba27
fix(ci): digest-pin the sandbox base image
yiliang114 Aug 27, 2026
581c917
fix(ci): ratchet the release.yml size baseline for the pool hardening
yiliang114 Aug 27, 2026
9533c96
fix(ci): reap cross-job processes and keep the pool tool cache in the…
yiliang114 Aug 27, 2026
2cf1799
fix(ci): keep the release wipe suite green and kill-free on the pool
yiliang114 Aug 27, 2026
c806030
fix(ci): keep concurrent registrations' jobs out of the release reap
yiliang114 Aug 28, 2026
6a2dd4f
fix(ci): stop the R1-1 reap probe from enumerating the pool host
yiliang114 Aug 28, 2026
52d57d3
fix(ci): keep the release wipe suite off the hosted Windows lane
yiliang114 Aug 28, 2026
11a6bb6
Merge origin/main into fix/release-ecs-runners
yiliang114 Aug 28, 2026
3c0ca80
fix(ci): remove unsafe shared-runner process reaping
yiliang114 Aug 28, 2026
d391bec
Merge branch 'main' into fix/release-ecs-runners
yiliang114 Aug 28, 2026
5222836
Merge branch 'fix/release-ecs-runners' of https://github.com/QwenLM/q…
qwen-code-dev-bot Aug 28, 2026
b37e9a4
Merge branch 'main' into fix/release-ecs-runners
qwen-code-dev-bot Aug 28, 2026
3dd2329
chore(ci): drop prettier reflow noise from teamHelpers.test.ts
yiliang114 Aug 28, 2026
1ae3588
fix(ci): re-arm the release.yml size ratchet at its true floor (#10036)
qwen-code-ci-bot Aug 28, 2026
d9ef8be
Merge remote-tracking branch 'origin/main' into fix/release-ecs-runners
yiliang114 Aug 28, 2026
88eea3f
fix(ci): strip RUNNER_WORKSPACE trailing slashes before the symlink r…
qwen-code-ci-bot Aug 28, 2026
c6bea8a
fix(ci): refuse symlinked components anywhere in the wipe path (#10036)
qwen-code-ci-bot Aug 28, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/.size-baseline
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
22037 release-sdk-python.yml
19094 release-sdk.yml
14546 release-vscode-companion.yml
39291 release.yml
45677 release.yml
43717 repo-hygiene.yml
1079 scorecard-monthly.yml
10691 sdk-java.yml
Expand Down
117 changes: 111 additions & 6 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,10 @@ on:
jobs:
prepare:
name: 'Prepare Release Metadata'
runs-on: 'ubuntu-latest'
# Route to the ECS self-hosted pool like the review/CI lanes; the
# MAINTAINER_ECS_RUNNER_DISABLED repo variable restores the hosted
# ubuntu-latest fallback without a code change.
runs-on: '${{ (github.repository == ''QwenLM/qwen-code'' && vars.MAINTAINER_ECS_RUNNER_DISABLED != ''true'') && fromJSON(''["self-hosted", "linux", "x64", "ecs-qwen"]'') || fromJSON(''["ubuntu-latest"]'') }}'
Comment thread
yiliang114 marked this conversation as resolved.
Resolved
Comment thread
yiliang114 marked this conversation as resolved.
Resolved
if: |-
${{ github.repository == 'QwenLM/qwen-code' }}
permissions:
Expand All @@ -56,6 +59,22 @@ jobs:
is_dry_run: '${{ steps.vars.outputs.is_dry_run }}'

steps:
# Shared ECS runners can retain root-owned files from an earlier
# containerized job. Restore the reusable workspace before checkout.
- name: 'Restore workspace ownership'
run: |-
set -uo pipefail
RUNNER_UID="$(id -u)"
RUNNER_GID="$(id -g)"
if [ "$RUNNER_UID" != "0" ]; then
chown -R "$RUNNER_UID:$RUNNER_GID" "$GITHUB_WORKSPACE" 2>/dev/null || sudo -n chown -R "$RUNNER_UID:$RUNNER_GID" "$GITHUB_WORKSPACE" || echo "::warning::could not restore workspace ownership; checkout may fail on leftover root-owned files"
fi
chmod -R u+rwX "$GITHUB_WORKSPACE" 2>/dev/null || sudo -n chmod -R u+rwX "$GITHUB_WORKSPACE" || echo "::warning::could not restore workspace write permissions; checkout may fail on leftover read-only files"
# Release jobs do not need cross-job workspace reuse. Remove every
# persisted entry, including planted .git config/hooks/attributes,
# before actions/checkout runs with release credentials.
find "$GITHUB_WORKSPACE" -mindepth 1 -maxdepth 1 -exec rm -rf -- {} +
Comment thread
yiliang114 marked this conversation as resolved.
Resolved

- name: 'Checkout'
uses: 'actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10' # v6.0.3
with:
Expand Down Expand Up @@ -145,7 +164,10 @@ jobs:

quality:
name: 'Quality Checks'
runs-on: 'ubuntu-latest'
# Route to the ECS self-hosted pool like the review/CI lanes; the
# MAINTAINER_ECS_RUNNER_DISABLED repo variable restores the hosted
Comment thread
yiliang114 marked this conversation as resolved.
Resolved
# ubuntu-latest fallback without a code change.
runs-on: '${{ (github.repository == ''QwenLM/qwen-code'' && vars.MAINTAINER_ECS_RUNNER_DISABLED != ''true'') && fromJSON(''["self-hosted", "linux", "x64", "ecs-qwen"]'') || fromJSON(''["ubuntu-latest"]'') }}'
needs: 'prepare'
if: |-
${{ github.event.inputs.force_skip_tests != 'true' }}
Expand All @@ -157,6 +179,22 @@ jobs:
OPENAI_MODEL: '${{ secrets.OPENAI_MODEL }}'

steps:
# Shared ECS runners can retain root-owned files from an earlier
# containerized job. Restore the reusable workspace before checkout.
- name: 'Restore workspace ownership'
run: |-
set -uo pipefail
RUNNER_UID="$(id -u)"
RUNNER_GID="$(id -g)"
if [ "$RUNNER_UID" != "0" ]; then
chown -R "$RUNNER_UID:$RUNNER_GID" "$GITHUB_WORKSPACE" 2>/dev/null || sudo -n chown -R "$RUNNER_UID:$RUNNER_GID" "$GITHUB_WORKSPACE" || echo "::warning::could not restore workspace ownership; checkout may fail on leftover root-owned files"
fi
chmod -R u+rwX "$GITHUB_WORKSPACE" 2>/dev/null || sudo -n chmod -R u+rwX "$GITHUB_WORKSPACE" || echo "::warning::could not restore workspace write permissions; checkout may fail on leftover read-only files"
# Release jobs do not need cross-job workspace reuse. Remove every
# persisted entry, including planted .git config/hooks/attributes,
# before actions/checkout runs with release credentials.
find "$GITHUB_WORKSPACE" -mindepth 1 -maxdepth 1 -exec rm -rf -- {} +
Comment thread
yiliang114 marked this conversation as resolved.
Resolved

- name: 'Checkout'
uses: 'actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10' # v6.0.3
with:
Expand Down Expand Up @@ -207,7 +245,10 @@ jobs:

integration_none:
name: 'Integration Tests (No Sandbox)'
runs-on: 'ubuntu-latest'
# Route to the ECS self-hosted pool like the review/CI lanes; the
# MAINTAINER_ECS_RUNNER_DISABLED repo variable restores the hosted
Comment thread
yiliang114 marked this conversation as resolved.
Resolved
# ubuntu-latest fallback without a code change.
runs-on: '${{ (github.repository == ''QwenLM/qwen-code'' && vars.MAINTAINER_ECS_RUNNER_DISABLED != ''true'') && fromJSON(''["self-hosted", "linux", "x64", "ecs-qwen"]'') || fromJSON(''["ubuntu-latest"]'') }}'
Comment thread
yiliang114 marked this conversation as resolved.
Resolved
needs: 'prepare'
if: |-
${{ github.event.inputs.force_skip_tests != 'true' }}
Expand All @@ -219,6 +260,22 @@ jobs:
OPENAI_MODEL: '${{ secrets.OPENAI_MODEL }}'

steps:
# Shared ECS runners can retain root-owned files from an earlier
# containerized job. Restore the reusable workspace before checkout.
- name: 'Restore workspace ownership'
run: |-
set -uo pipefail
RUNNER_UID="$(id -u)"
RUNNER_GID="$(id -g)"
if [ "$RUNNER_UID" != "0" ]; then
chown -R "$RUNNER_UID:$RUNNER_GID" "$GITHUB_WORKSPACE" 2>/dev/null || sudo -n chown -R "$RUNNER_UID:$RUNNER_GID" "$GITHUB_WORKSPACE" || echo "::warning::could not restore workspace ownership; checkout may fail on leftover root-owned files"
fi
chmod -R u+rwX "$GITHUB_WORKSPACE" 2>/dev/null || sudo -n chmod -R u+rwX "$GITHUB_WORKSPACE" || echo "::warning::could not restore workspace write permissions; checkout may fail on leftover read-only files"
# Release jobs do not need cross-job workspace reuse. Remove every
# persisted entry, including planted .git config/hooks/attributes,
# before actions/checkout runs with release credentials.
find "$GITHUB_WORKSPACE" -mindepth 1 -maxdepth 1 -exec rm -rf -- {} +

- name: 'Checkout'
uses: 'actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10' # v6.0.3
with:
Expand Down Expand Up @@ -258,7 +315,10 @@ jobs:

integration_docker:
name: 'Integration Tests (Docker)'
runs-on: 'ubuntu-latest'
# Route to the ECS self-hosted pool like the review/CI lanes; the
# MAINTAINER_ECS_RUNNER_DISABLED repo variable restores the hosted
Comment thread
yiliang114 marked this conversation as resolved.
Resolved
# ubuntu-latest fallback without a code change.
runs-on: '${{ (github.repository == ''QwenLM/qwen-code'' && vars.MAINTAINER_ECS_RUNNER_DISABLED != ''true'') && fromJSON(''["self-hosted", "linux", "x64", "ecs-qwen"]'') || fromJSON(''["ubuntu-latest"]'') }}'
Comment thread
yiliang114 marked this conversation as resolved.
Resolved
needs: 'prepare'
if: |-
${{ github.event.inputs.force_skip_tests != 'true' }}
Expand All @@ -270,6 +330,29 @@ jobs:
OPENAI_MODEL: '${{ secrets.OPENAI_MODEL }}'

steps:
# Shared ECS runners can retain root-owned files from an earlier
# containerized job. Restore the reusable workspace before checkout.
- name: 'Restore workspace ownership'
run: |-
set -uo pipefail
RUNNER_UID="$(id -u)"
RUNNER_GID="$(id -g)"
if [ "$RUNNER_UID" != "0" ]; then
chown -R "$RUNNER_UID:$RUNNER_GID" "$GITHUB_WORKSPACE" 2>/dev/null || sudo -n chown -R "$RUNNER_UID:$RUNNER_GID" "$GITHUB_WORKSPACE" || echo "::warning::could not restore workspace ownership; checkout may fail on leftover root-owned files"
fi
chmod -R u+rwX "$GITHUB_WORKSPACE" 2>/dev/null || sudo -n chmod -R u+rwX "$GITHUB_WORKSPACE" || echo "::warning::could not restore workspace write permissions; checkout may fail on leftover read-only files"
# Release jobs do not need cross-job workspace reuse. Remove every
# persisted entry, including planted .git config/hooks/attributes,
# before actions/checkout runs with release credentials.
find "$GITHUB_WORKSPACE" -mindepth 1 -maxdepth 1 -exec rm -rf -- {} +

- name: 'Check docker daemon'
run: |-
if ! docker info > /dev/null 2>&1; then
echo "::error::docker daemon is not reachable on this runner; docker integration tests cannot run."
Comment thread
yiliang114 marked this conversation as resolved.
Resolved
exit 1
fi

- name: 'Checkout'
uses: 'actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10' # v6.0.3
with:
Expand Down Expand Up @@ -327,7 +410,10 @@ jobs:

publish:
name: 'Publish Release'
runs-on: 'ubuntu-latest'
# Route to the ECS self-hosted pool like the review/CI lanes; the
# MAINTAINER_ECS_RUNNER_DISABLED repo variable restores the hosted
# ubuntu-latest fallback without a code change.
runs-on: '${{ (github.repository == ''QwenLM/qwen-code'' && vars.MAINTAINER_ECS_RUNNER_DISABLED != ''true'') && fromJSON(''["self-hosted", "linux", "x64", "ecs-qwen"]'') || fromJSON(''["ubuntu-latest"]'') }}'
Comment thread
yiliang114 marked this conversation as resolved.
Resolved
needs:
- 'prepare'
- 'quality'
Expand Down Expand Up @@ -384,6 +470,22 @@ jobs:
pull-requests: 'write'

steps:
# Shared ECS runners can retain root-owned files from an earlier
# containerized job. Restore the reusable workspace before checkout.
- name: 'Restore workspace ownership'
Comment thread
yiliang114 marked this conversation as resolved.
Resolved
run: |-
set -uo pipefail
RUNNER_UID="$(id -u)"
RUNNER_GID="$(id -g)"
if [ "$RUNNER_UID" != "0" ]; then
chown -R "$RUNNER_UID:$RUNNER_GID" "$GITHUB_WORKSPACE" 2>/dev/null || sudo -n chown -R "$RUNNER_UID:$RUNNER_GID" "$GITHUB_WORKSPACE" || echo "::warning::could not restore workspace ownership; checkout may fail on leftover root-owned files"
fi
chmod -R u+rwX "$GITHUB_WORKSPACE" 2>/dev/null || sudo -n chmod -R u+rwX "$GITHUB_WORKSPACE" || echo "::warning::could not restore workspace write permissions; checkout may fail on leftover read-only files"
# Release jobs do not need cross-job workspace reuse. Remove every
# persisted entry, including planted .git config/hooks/attributes,
# before actions/checkout runs with release credentials.
find "$GITHUB_WORKSPACE" -mindepth 1 -maxdepth 1 -exec rm -rf -- {} +

- name: 'Checkout'
uses: 'actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10' # v6.0.3
with:
Expand Down Expand Up @@ -747,7 +849,10 @@ jobs:

notify_failure:
name: 'Notify Release Failure'
runs-on: 'ubuntu-latest'
# Route to the ECS self-hosted pool like the review/CI lanes; the
Comment thread
yiliang114 marked this conversation as resolved.
Resolved
# MAINTAINER_ECS_RUNNER_DISABLED repo variable restores the hosted
# ubuntu-latest fallback without a code change.
runs-on: '${{ (github.repository == ''QwenLM/qwen-code'' && vars.MAINTAINER_ECS_RUNNER_DISABLED != ''true'') && fromJSON(''["self-hosted", "linux", "x64", "ecs-qwen"]'') || fromJSON(''["ubuntu-latest"]'') }}'
needs:
- 'prepare'
- 'quality'
Expand Down
50 changes: 50 additions & 0 deletions scripts/tests/release-workflow.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ import { mkdtempSync, readFileSync, writeFileSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import { describe, expect, it } from 'vitest';
import { parse } from 'yaml';

const workflow = readFileSync('.github/workflows/release.yml', 'utf8');
const releaseYaml = parse(workflow);
const cuaReleaseWorkflow = readFileSync(
'.github/workflows/cd-cua-driver.yml',
'utf8',
Expand Down Expand Up @@ -80,6 +82,54 @@ describe('CUA release workflow', () => {
});

describe('release workflow', () => {
it('cleans every shared ECS workspace before checkout', () => {
Comment thread
yiliang114 marked this conversation as resolved.
Resolved
const checkoutJobs = Object.entries(releaseYaml.jobs).filter(([, job]) =>
(job.steps ?? []).some((step) =>
String(step.uses ?? '').includes('actions/checkout'),
),
);
const cleanupCopies = [];

expect(checkoutJobs.map(([id]) => id)).toEqual([
'prepare',
'quality',
'integration_none',
'integration_docker',
'publish',
]);
for (const [id, job] of checkoutJobs) {
const checkoutIndex = job.steps.findIndex((step) =>
String(step.uses ?? '').includes('actions/checkout'),
);
const restoreIndex = job.steps.findIndex(
(step) => step.name === 'Restore workspace ownership',
);
const cleanup = job.steps[restoreIndex]?.run;
expect(restoreIndex, id).toBeGreaterThanOrEqual(0);
expect(restoreIndex, id).toBeLessThan(checkoutIndex);
expect(cleanup, id).toContain(
Comment thread
yiliang114 marked this conversation as resolved.
Resolved
'find "$GITHUB_WORKSPACE" -mindepth 1 -maxdepth 1 -exec rm -rf -- {} +',
);
cleanupCopies.push(cleanup);
}
for (const copy of cleanupCopies.slice(1)) {
expect(copy).toBe(cleanupCopies[0]);
}
});

it('checks docker availability before the docker checkout', () => {
const steps = releaseYaml.jobs.integration_docker.steps;
const preflightIndex = steps.findIndex(
(step) => step.name === 'Check docker daemon',
);
const checkoutIndex = steps.findIndex((step) =>
String(step.uses ?? '').includes('actions/checkout'),
);
expect(preflightIndex).toBeGreaterThanOrEqual(0);
expect(preflightIndex).toBeLessThan(checkoutIndex);
expect(steps[preflightIndex].run).toContain('docker info');
Comment thread
yiliang114 marked this conversation as resolved.
Resolved
});

it('fires the fleet-moving npm-published dispatch on stable releases only', () => {
// This gate is the sole protection keeping a nightly/preview/dry-run
// release from moving the ECS fleet; the triggered update workflow
Expand Down
Loading