fix(ci): recover reused runner checkouts and Java lock waits (#14017)

* fix(ci): recover reused runner checkouts and Java lock waits

Co-authored-by: Qwen-Coder <[email protected]>

* fix(ci): refresh Git metadata across Linux validation lanes

Co-authored-by: Qwen-Coder <[email protected]>

* fix(ci): refresh checkout metadata for triage jobs

Co-authored-by: Qwen-Coder <[email protected]>

---------

Co-authored-by: Qwen-Coder <[email protected]>
This commit is contained in:
易良andQwen-Coder authored and GitHub committed 2026-10-13 06:12:21 +00:00
1 parent f7de8a3391
commit aceb7f1223
6 files changed
+162 -8

No files matched your search

+20
View File
@@ -530,6 +530,11 @@ jobs:
# Merge queue refs are ephemeral; check out the event head SHA directly so
# slow hosted runners do not fail after the queue branch is removed.
# Non-PR/non-queue events keep github.ref.
- name: 'Recreate runner Git metadata'
if: "${{ runner.environment == 'self-hosted' }}"
run: |-
rm -rf -- "$GITHUB_WORKSPACE/.git"
- name: 'Checkout'
id: 'checkout'
if: "${{ needs.classify_pr.outputs.skip_ci != 'true' }}"
@@ -1017,6 +1022,11 @@ jobs:
# Merge queue refs are ephemeral; check out the event head SHA directly so
# slow hosted runners do not fail after the queue branch is removed.
# Non-PR/non-queue events keep github.ref.
- name: 'Recreate runner Git metadata'
if: "${{ runner.environment == 'self-hosted' }}"
run: |-
rm -rf -- "$GITHUB_WORKSPACE/.git"
- name: 'Checkout'
id: 'checkout'
if: "${{ needs.classify_pr.outputs.skip_ci != 'true' }}"
@@ -2047,6 +2057,11 @@ jobs:
done || true
fi
- name: 'Recreate runner Git metadata'
if: "${{ runner.environment == 'self-hosted' }}"
run: |-
rm -rf -- "$GITHUB_WORKSPACE/.git"
- name: 'Checkout'
uses: 'actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10' # v6.0.3
with:
@@ -2278,6 +2293,11 @@ jobs:
done || true
fi
- name: 'Recreate runner Git metadata'
if: "${{ runner.environment == 'self-hosted' }}"
run: |-
rm -rf -- "$GITHUB_WORKSPACE/.git"
- name: 'Checkout'
uses: 'actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10' # v6.0.3
with:
+15
View File
@@ -768,6 +768,11 @@ jobs:
git config --local --unset-all core.hooksPath 2>/dev/null || true
fi
- name: 'Recreate runner Git metadata'
if: "${{ runner.environment == 'self-hosted' }}"
run: |-
rm -rf -- "$GITHUB_WORKSPACE/.git"
- name: 'Checkout'
uses: 'actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10' # v6.0.3
with:
@@ -3594,6 +3599,11 @@ jobs:
git config --local --unset-all core.hooksPath 2>/dev/null || true
fi
- name: 'Recreate runner Git metadata'
if: "${{ runner.environment == 'self-hosted' }}"
run: |-
rm -rf -- "$GITHUB_WORKSPACE/.git"
- name: 'Checkout trusted base'
uses: 'actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10' # v6.0.3
with:
@@ -3810,6 +3820,11 @@ jobs:
git config --local --unset-all core.hooksPath 2>/dev/null || true
fi
- name: 'Recreate runner Git metadata'
if: "${{ runner.environment == 'self-hosted' }}"
run: |-
rm -rf -- "$GITHUB_WORKSPACE/.git"
- name: 'Checkout trusted base'
uses: 'actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10' # v6.0.3
with:
+15
View File
@@ -610,6 +610,11 @@ jobs:
git worktree prune -v || true
echo "stale agent state cleaned"
- name: 'Recreate runner Git metadata'
if: "${{ runner.environment == 'self-hosted' }}"
run: |-
rm -rf -- "$GITHUB_WORKSPACE/.git"
- name: 'Checkout repo'
uses: 'actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10' # v6.0.3
with:
@@ -1323,6 +1328,11 @@ jobs:
fi
git worktree prune -v || true
- name: 'Recreate runner Git metadata'
if: "${{ runner.environment == 'self-hosted' }}"
run: |-
rm -rf -- "$GITHUB_WORKSPACE/.git"
- name: 'Checkout PR merge ref'
if: "steps.pr.outputs.decision == 'run'"
uses: 'actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10' # v6.0.3
@@ -2895,6 +2905,11 @@ jobs:
git worktree prune -v || true
echo "stale agent state cleaned"
- name: 'Recreate runner Git metadata'
if: "${{ runner.environment == 'self-hosted' }}"
run: |-
rm -rf -- "$GITHUB_WORKSPACE/.git"
- name: 'Checkout PR merge ref'
if: "steps.pr.outputs.decision == 'run'"
uses: 'actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10' # v6.0.3
+23 -3
View File
@@ -92,7 +92,7 @@ jobs:
test:
name: '${{ matrix.os }} / Java ${{ matrix.java }}'
runs-on: '${{ (matrix.os == ''ubuntu-latest'' && github.repository == ''QwenLM/qwen-code'' && vars.MAINTAINER_ECS_RUNNER_DISABLED != ''true'' && (github.event_name == ''push'' || github.event.pull_request.head.repo.full_name == github.repository || contains(fromJSON(''["OWNER","MEMBER","COLLABORATOR"]''), github.event.pull_request.author_association))) && fromJSON(''["self-hosted", "linux", "x64", "ecs-qwen"]'') || matrix.os }}'
timeout-minutes: 30
timeout-minutes: 60
strategy:
fail-fast: false
matrix:
@@ -215,6 +215,11 @@ jobs:
done || true
fi
- name: 'Recreate runner Git metadata'
if: "${{ runner.environment == 'self-hosted' }}"
run: |-
rm -rf -- "$GITHUB_WORKSPACE/.git"
- name: 'Checkout'
uses: 'actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10' # v6.0.3
with:
@@ -272,8 +277,8 @@ jobs:
run: |-
mkdir -p "${HOME}/.cache/qwen-code-ci"
exec 9>"${HOME}/.cache/qwen-code-ci/sdk-java-tests.lock"
if ! flock --wait 1200 9; then
echo "::error::sdk-java host lock not acquired within 20 minutes"
if ! flock --wait 2400 9; then
echo "::error::sdk-java host lock not acquired within 40 minutes"
exit 1
fi
mvn --batch-mode --no-transfer-progress clean test
@@ -444,6 +449,11 @@ jobs:
done || true
fi
- name: 'Recreate runner Git metadata'
if: "${{ runner.environment == 'self-hosted' }}"
run: |-
rm -rf -- "$GITHUB_WORKSPACE/.git"
- name: 'Checkout'
uses: 'actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10' # v6.0.3
@@ -623,6 +633,11 @@ jobs:
# gate certifies what merging would produce, cancel-in-progress
# re-runs a displaced head, and the pool queue is seconds short.
# Pinned in scripts/tests/sdk-java-workflow.test.js.
- name: 'Recreate runner Git metadata'
if: "${{ runner.environment == 'self-hosted' }}"
run: |-
rm -rf -- "$GITHUB_WORKSPACE/.git"
- name: 'Checkout'
uses: 'actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10' # v6.0.3
@@ -1010,6 +1025,11 @@ jobs:
done || true
fi
- name: 'Recreate runner Git metadata'
if: "${{ runner.environment == 'self-hosted' }}"
run: |-
rm -rf -- "$GITHUB_WORKSPACE/.git"
- name: 'Checkout'
uses: 'actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10' # v6.0.3
with:
@@ -0,0 +1,84 @@
import { execFileSync } from 'node:child_process';
import {
existsSync,
mkdirSync,
mkdtempSync,
readFileSync,
rmSync,
symlinkSync,
writeFileSync,
} from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import { parse } from 'yaml';
import { expect, it } from 'vitest';
const jobs = [
...['triage', 'tmux-testing', 'verify'].map((name) => ['qwen-triage', name]),
...['test', 'lint_and_static', 'integration_no_ak', 'integration_cli'].map(
(name) => ['ci', name],
),
...['test', 'flyway-migrations', 'mysql-integration', 'daemon-e2e'].map(
(name) => ['sdk-java', name],
),
...['issue-autofix', 'build-cli', 'review-address'].map((name) => [
'qwen-autofix',
name,
]),
];
it.each(jobs)(
'%s / %s replaces runner Git metadata before checkout without following links',
(workflow, name) => {
const { steps } = parse(
readFileSync(`.github/workflows/${workflow}.yml`, 'utf8'),
).jobs[name];
const index = steps.findIndex(
(step) => step.name === 'Recreate runner Git metadata',
);
expect(index).toBeGreaterThanOrEqual(0);
expect(steps[index].if).toBe("${{ runner.environment == 'self-hosted' }}");
expect(steps[index + 1].uses).toMatch(/^actions\/checkout@/);
const root = mkdtempSync(join(tmpdir(), 'qwen-checkout-'));
try {
const workspace = join(root, 'workspace');
const external = join(root, 'external');
mkdirSync(workspace);
mkdirSync(external);
const cached = join(workspace, 'node_modules');
const preserved = join(external, 'keep');
mkdirSync(cached);
writeFileSync(preserved, 'keep external repository');
const git = (...args) =>
execFileSync('git', args, { cwd: workspace, stdio: 'pipe' });
const recover = () =>
execFileSync('bash', ['-e', '-c', steps[index].run], {
cwd: workspace,
env: { ...process.env, GITHUB_WORKSPACE: workspace },
});
git('init', '--quiet');
writeFileSync(
join(workspace, '.git', 'shallow'),
'broken shallow boundary',
);
expect(() => git('rev-parse', '--is-shallow-repository')).toThrow();
recover();
expect(existsSync(join(workspace, '.git'))).toBe(false);
git('init', '--quiet');
expect(
git('rev-parse', '--is-shallow-repository').toString().trim(),
).toBe('false');
rmSync(join(workspace, '.git'), { recursive: true });
symlinkSync(external, join(workspace, '.git'));
recover();
expect(readFileSync(preserved, 'utf8')).toBe('keep external repository');
expect(existsSync(cached)).toBe(true);
recover();
} finally {
rmSync(root, { recursive: true, force: true });
}
},
);
+5 -5
View File
@@ -49,9 +49,9 @@ describe('SDK Java self-hosted workflow guards', () => {
expect(block).toContain(
'exec 9>"${HOME}/.cache/qwen-code-ci/sdk-java-tests.lock"',
);
expect(block).toContain('flock --wait 1200 9');
expect(block).toContain('flock --wait 2400 9');
expect(block).toContain(
'::error::sdk-java host lock not acquired within 20 minutes',
'::error::sdk-java host lock not acquired within 40 minutes',
);
expect(block).toContain(
'if: "${{ runner.environment == \'github-hosted\' }}"',
@@ -414,10 +414,10 @@ describe('SDK Java MariaDB lane on the ECS pool', () => {
).toBeGreaterThanOrEqual(mavenSteps.length * 2400 + 14 * 60);
// The sibling test job shares the same per-host lock: its ceiling must
// cover one full wait plus its own measured locked work (~5 minutes on
// the Java 21 leg of run 37743332082) — this job's holds now consume
// part of that wait budget, and nothing else asserts the headroom.
// the Java 21 leg of run 37743332082) and setup headroom. This job's holds
// now consume part of that wait budget.
expect(parsed.jobs.test['timeout-minutes'] * 60).toBeGreaterThanOrEqual(
1200 + 5 * 60,
2400 + 10 * 60,
);
});