mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-11-07 06:19:43 -10:00
feat(hooks): add FileChanged notifications for local sessions (#13969)
* feat(hooks): add FileChanged notifications for local sessions * fix(ci): preserve shell gate coverage and trim transcript data * fix(ci): flush debug prompts and isolate git fixtures * fix(hooks): respect ACP watcher ownership and skill registration * test: stabilize hosted recovery and failed spawn fixtures * fix(ci): budget the complete hosted integration fork * fix(runtime-broker): accept MariaDB CSI guard metadata * test: align schema baseline and hook dispatch waits * fix(ci): allow hosted shared fork to finish all classes * fix(hooks): preserve file watching across errors and cwd changes * fix(ci): isolate reference archive extraction per run * test(ci): keep reference archive checks dependency-free * fix(hooks): constrain recursive watches and repair CI * test(web-shell): synchronize verified connection return * fix(ci): correct runtime broker callback indentation * test(web-shell): match the managed workspace registration label Keep the remote workspace registration smoke checks in sync with the service label added by unified workspace navigation. Preserve exact text matching and all registration and replay assertions. * fix(ci): reduce standalone runtime fixture overhead * fix(hooks): ignore implicit atomic-write temporary files * test(managed-agent): recover initial node port conflicts * fix(hooks): observe parents before discovery anchors disappear * test(managed-agent): await stream cleanup before recovery teardown * test(managed-agent): align hosted shell fixture capabilities * test(managed-agent): let OS choose initial harness port * fix(ci): restore runner-local Java cache permissions * test(runtime-broker): use native execution profile paths * test(managed-agent): bind valid workspace upload probes * test(managed-agent): reuse the upload probe digest fixture * test(managed-agent): bind hook fault listeners to available ports * test(managed-agent): align the native profile path fixture * test(managed-agent): Wait for projection refusal retries * ci: Prepare daemon Java cache before Node preflight * test(managed-agent): check channel model calls after delivery * fix(hooks): observe explicitly registered symlink targets * test(managed-agent): separate consumption from relay snapshots * test(managed-agent): target tamper injection by resource key * test(managed-agent): exhaust attestation EOF retry in fault gates * fix(ci): bound RocketMQ release downloads * test(tui): await the restored assistant before capturing history * fix(ci): use a checksum-pinned RocketMQ mirror * fix(ci): provision missing browser test fonts * fix(ci): quote the font probe environment * fix(ci): prepare browser fonts without elevation * test(core): compare complete prune reports without ordering * fix(ci): repair only runner-local Java tool caches * test(managed-agent): qualify fixture JDBC templates * fix: isolate reconnect hooks and cancellation test fixtures Skip chat initialization so MCP reconnect cannot re-enable file hooks, and keep cancellation fixtures isolated from the background worktree scanner. * fix(ci): tolerate a missing Java cache helper on resumed releases Resuming an existing release checks out a tag that may predate the helper, which failed all five Java jobs before setup-java ran. * fix: finish the main merge for harness deadlines and workflow size Use the renamed settle-timeout accessor in the merged hosted-harness tests, and record sdk-java.yml's new size after the resumed-release cache guard. * style(managed-agent): restore import grouping in merged verification tests * test(managed-agent): require consumed child result mirrors * test(web-shell): center repository settings capture --------- Co-authored-by: yiliang114 <[email protected]> Co-authored-by: yungsen.hys <[email protected]> Co-authored-by: Shaojin Wen <[email protected]>
This commit is contained in:
90 files changed
+4678
-245
No files matched your search
@@ -117,6 +117,10 @@ for (const name of [
|
||||
while (ports[name] === undefined) {
|
||||
const port = await pick();
|
||||
if (port === null) continue;
|
||||
if (name === 'RMQ_BROKER_PORT' && (port < 3 || port > 65534)) {
|
||||
release(port);
|
||||
continue;
|
||||
}
|
||||
let kept = true;
|
||||
if (name === 'RMQ_BROKER_PORT') {
|
||||
// A companion can repeat a port an earlier role already parked: the
|
||||
|
||||
@@ -1330,6 +1330,21 @@ describe('trusted-PR lanes moved off the hosted queue (#13245)', () => {
|
||||
String(s.uses || '').startsWith('actions/setup-node'),
|
||||
);
|
||||
assert.equal(setupNode.if, "${{ runner.environment == 'github-hosted' }}");
|
||||
const setupJava = build.steps.find((s) =>
|
||||
String(s.uses || '').startsWith('actions/setup-java'),
|
||||
);
|
||||
const cache = setupJava.with.cache;
|
||||
for (const [environment, expected] of [
|
||||
['github-hosted', 'maven'],
|
||||
['self-hosted', ''],
|
||||
]) {
|
||||
const actual = cache.startsWith('${{')
|
||||
? new Function('runner', `return (${cache.slice(3, -2)});`)({
|
||||
environment,
|
||||
})
|
||||
: cache;
|
||||
assert.equal(actual, expected, environment);
|
||||
}
|
||||
});
|
||||
|
||||
it('tui-parity keeps setup-node and the pnpm cache off the pool', () => {
|
||||
|
||||
@@ -154,11 +154,22 @@ bash .github/scripts/ecs-runner/check-font-baseline.sh
|
||||
bash .github/scripts/ecs-runner/check-font-baseline.sh --with-metrics
|
||||
```
|
||||
|
||||
The web-shell smoke lane runs the L0 half as `Check host font baseline
|
||||
(self-hosted)` before installing dependencies, so a drifted host fails in
|
||||
seconds with an actionable message instead of failing two layout assertions
|
||||
26 minutes into the suite. L1 stays a manual/host-provisioning check because
|
||||
it needs a Chromium that the lane has not installed yet at that point.
|
||||
The web-shell smoke lane is pinned to `ubuntu-latest` to isolate its browsers
|
||||
from shared-host network changes (run 40915920935 failed before app startup
|
||||
with `ERR_NETWORK_CHANGED` on ARM64). Its retained `Check host font baseline
|
||||
(self-hosted)` step is dormant on that routing; should the lane return to a
|
||||
shared host, that step runs the L0 half before installing dependencies, so a
|
||||
drifted host fails in seconds with an actionable message instead of failing two
|
||||
layout assertions 26 minutes into the suite. When L0 fails there, it downloads
|
||||
the two DejaVu packages using private APT lists, extracts only their font data
|
||||
into `${XDG_DATA_HOME:-$HOME/.local/share}/fonts/qwen-ci`, refreshes the
|
||||
runner's font cache, and verifies L0 again. This runs at the runner's existing
|
||||
privilege level: CI does not elevate or execute the host-provisioning
|
||||
installer. Healthy hosts require no download or extraction; acquisition
|
||||
failures and remaining runner-user drift still fail the gate. Before moving
|
||||
browser jobs back to a shared host, provide network isolation as well as this
|
||||
font baseline; matching fonts alone does not prevent interrupted module loads.
|
||||
L1 remains a manual/host-provisioning check requiring an installed Chromium.
|
||||
|
||||
## Regression check
|
||||
|
||||
|
||||
@@ -26,6 +26,13 @@ function makeCase({
|
||||
installed = true,
|
||||
metrics = BASELINE,
|
||||
browser = true,
|
||||
uid = '1000',
|
||||
repairFamily = false,
|
||||
rootFamily,
|
||||
sudoStatus = '0',
|
||||
aptStatus = '0',
|
||||
extractStatus = '0',
|
||||
customDataHome = false,
|
||||
} = {}) {
|
||||
const dir = mkdtempSync(join(tmpdir(), 'qwen-font-baseline-test-'));
|
||||
const bin = join(dir, 'bin');
|
||||
@@ -33,14 +40,45 @@ function makeCase({
|
||||
const write = (name, body) =>
|
||||
writeFileSync(join(bin, name), body, { mode: 0o755 });
|
||||
|
||||
write('fc-match', '#!/usr/bin/env bash\nprintf "%s" "$CASE_FAMILY"\n');
|
||||
write(
|
||||
'fc-match',
|
||||
'#!/usr/bin/env bash\nif [ "${CASE_AS_ROOT:-0}" = 1 ] && [ -n "${CASE_ROOT_FAMILY:-}" ]; then printf "%s" "$CASE_ROOT_FAMILY"; elif [ -f "$CASE_DIR/repaired" ]; then printf "DejaVu Sans"; else printf "%s" "$CASE_FAMILY"; fi\n',
|
||||
);
|
||||
write(
|
||||
'fc-cache',
|
||||
'#!/usr/bin/env bash\nprintf "fc-cache %s\\n" "$*" >> "$CASE_DIR/calls"\n',
|
||||
'#!/usr/bin/env bash\nprintf "fc-cache %s\\n" "$*" >> "$CASE_DIR/calls"\nif [ "$CASE_REPAIR_FAMILY" = 1 ] && [ -f "${XDG_DATA_HOME:-$HOME/.local/share}/fonts/qwen-ci/truetype/dejavu/DejaVuSans.ttf" ]; then touch "$CASE_DIR/repaired"; fi\n',
|
||||
);
|
||||
write(
|
||||
'apt-get',
|
||||
'#!/usr/bin/env bash\nprintf "apt-get %s\\n" "$*" >> "$CASE_DIR/calls"\n',
|
||||
[
|
||||
'#!/usr/bin/env bash',
|
||||
'printf "apt-get %s\\n" "$*" >> "$CASE_DIR/calls"',
|
||||
'[ "$CASE_APT_STATUS" = 0 ] || exit "$CASE_APT_STATUS"',
|
||||
'if [ "$1" = -o ]; then shift 2; fi',
|
||||
'if [ "$1" = download ]; then touch fonts-dejavu-core_1_all.deb fonts-dejavu-mono_1_all.deb; fi',
|
||||
'if [ "$1" = install ] && [ "$CASE_REPAIR_FAMILY" = 1 ]; then touch "$CASE_DIR/repaired"; fi',
|
||||
'',
|
||||
].join('\n'),
|
||||
);
|
||||
write(
|
||||
'dpkg-deb',
|
||||
[
|
||||
'#!/usr/bin/env bash',
|
||||
'printf "dpkg-deb %s\\n" "$*" >> "$CASE_DIR/calls"',
|
||||
'[ "$CASE_EXTRACT_STATUS" = 0 ] || exit "$CASE_EXTRACT_STATUS"',
|
||||
'[ "$1" = --extract ] || exit 2',
|
||||
'mkdir -p "$3/usr/share/fonts/truetype/dejavu"',
|
||||
'printf fixture-font > "$3/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf"',
|
||||
'',
|
||||
].join('\n'),
|
||||
);
|
||||
write(
|
||||
'id',
|
||||
'#!/usr/bin/env bash\nif [ "${CASE_AS_ROOT:-0}" = 1 ]; then printf "0\\n"; else printf "%s\\n" "$CASE_UID"; fi\n',
|
||||
);
|
||||
write(
|
||||
'sudo',
|
||||
'#!/usr/bin/env bash\nprintf "sudo %s\\n" "$*" >> "$CASE_DIR/calls"\nif [ "$CASE_SUDO_STATUS" != 0 ]; then exit "$CASE_SUDO_STATUS"; fi\n[ "$1" = -n ] || exit 2\nshift\nCASE_AS_ROOT=1 exec "$@"\n',
|
||||
);
|
||||
write(
|
||||
'dpkg-query',
|
||||
@@ -64,10 +102,18 @@ function makeCase({
|
||||
CASE_DIR: dir,
|
||||
CASE_FAMILY: family,
|
||||
CASE_INSTALLED: installed ? '1' : '0',
|
||||
CASE_UID: uid,
|
||||
CASE_REPAIR_FAMILY: repairFamily ? '1' : '0',
|
||||
CASE_ROOT_FAMILY: rootFamily ?? '',
|
||||
CASE_SUDO_STATUS: sudoStatus,
|
||||
CASE_APT_STATUS: aptStatus,
|
||||
CASE_EXTRACT_STATUS: extractStatus,
|
||||
CASE_METRICS: JSON.stringify(metrics),
|
||||
GITHUB_ACTIONS: '',
|
||||
HOME: join(dir, 'home'),
|
||||
TMPDIR: join(dir, 'tmp'),
|
||||
RUNNER_TEMP: join(dir, 'tmp'),
|
||||
XDG_DATA_HOME: customDataHome ? join(dir, 'xdg-data') : '',
|
||||
CHROMIUM_BIN: browser
|
||||
? join(bin, 'chromium')
|
||||
: join(dir, 'no-such-browser'),
|
||||
@@ -76,9 +122,10 @@ function makeCase({
|
||||
return { dir, env };
|
||||
}
|
||||
|
||||
function run(script, args, env) {
|
||||
function run(script, args, env, cwd = join(scriptDir, '../../..')) {
|
||||
const result = spawnSync('bash', [script, ...args], {
|
||||
env,
|
||||
cwd,
|
||||
encoding: 'utf8',
|
||||
timeout: 60_000,
|
||||
});
|
||||
@@ -169,8 +216,6 @@ test('installer refuses to run as non-root', () => {
|
||||
...env,
|
||||
QWEN_FONT_BASELINE_TEST_ALLOW_NON_ROOT: '0',
|
||||
});
|
||||
// The test suite itself may not run as root; when it does, skip the guard.
|
||||
if (process.getuid?.() === 0) return;
|
||||
assert.equal(result.status, 1);
|
||||
assert.match(result.stderr, /as root/);
|
||||
});
|
||||
@@ -218,3 +263,142 @@ test('installer fails when the host still resolves the wrong family', () => {
|
||||
assert.match(result.stderr, /fonts-dejavu-core/);
|
||||
});
|
||||
});
|
||||
|
||||
function runCiFontStep(env, { installer, checker } = {}) {
|
||||
const workflow = readFileSync(
|
||||
join(scriptDir, '../../workflows/ci.yml'),
|
||||
'utf8',
|
||||
);
|
||||
const step = workflow.match(
|
||||
/- name: 'Check host font baseline \(self-hosted\)'[\s\S]*?run: \|-\n([\s\S]*?)(?=\n {6}- name:)/,
|
||||
);
|
||||
assert.ok(step, 'the actual CI font step must be present');
|
||||
const checkout = join(env.CASE_DIR, 'checkout');
|
||||
const fontScripts = join(checkout, '.github/scripts/ecs-runner');
|
||||
mkdirSync(fontScripts, { recursive: true });
|
||||
writeFileSync(
|
||||
join(fontScripts, 'install-qwen-font-baseline.sh'),
|
||||
installer ?? readFileSync(installScript),
|
||||
);
|
||||
writeFileSync(
|
||||
join(fontScripts, 'check-font-baseline.sh'),
|
||||
checker ?? readFileSync(checkScript),
|
||||
);
|
||||
const script = join(env.CASE_DIR, 'ci-font-step.sh');
|
||||
writeFileSync(script, `set -eo pipefail\n${step[1].replace(/^ {10}/gm, '')}`);
|
||||
return run(script, [], { ...env, GITHUB_ACTIONS: 'true' }, checkout);
|
||||
}
|
||||
|
||||
test('CI leaves a healthy runner unmodified', () => {
|
||||
withCase({}, (env) => {
|
||||
const result = runCiFontStep(env);
|
||||
assert.equal(result.status, 0, result.stderr);
|
||||
assert.equal(result.calls, '');
|
||||
assert.match(result.stdout, /default sans-serif = DejaVu Sans/);
|
||||
});
|
||||
});
|
||||
|
||||
for (const uid of ['0', '1000']) {
|
||||
test(`CI prepares user fonts without elevation for runner uid ${uid}`, () => {
|
||||
withCase(
|
||||
{
|
||||
uid,
|
||||
installed: false,
|
||||
family: 'WenQuanYi Zen Hei',
|
||||
repairFamily: true,
|
||||
},
|
||||
(env) => {
|
||||
const result = runCiFontStep(env);
|
||||
assert.equal(result.status, 0, result.stderr);
|
||||
assert.match(
|
||||
result.calls,
|
||||
/apt-get .* download fonts-dejavu-core fonts-dejavu-mono/,
|
||||
);
|
||||
assert.match(
|
||||
result.calls,
|
||||
/Dir::State::lists=.*\/qwen-fonts\.[^/]+\/lists/,
|
||||
);
|
||||
assert.match(result.calls, /dpkg-deb --extract/);
|
||||
assert.equal(
|
||||
readFileSync(
|
||||
join(
|
||||
env.HOME,
|
||||
'.local/share/fonts/qwen-ci/truetype/dejavu/DejaVuSans.ttf',
|
||||
),
|
||||
'utf8',
|
||||
),
|
||||
'fixture-font',
|
||||
);
|
||||
assert.match(result.stdout, /default sans-serif = DejaVu Sans/);
|
||||
assert.doesNotMatch(result.stdout, /::error::/);
|
||||
assert.doesNotMatch(result.calls, /sudo|apt-get install/);
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
test('CI rejects runner font drift after extracting user fonts', () => {
|
||||
withCase(
|
||||
{ family: 'WenQuanYi Zen Hei', rootFamily: 'DejaVu Sans' },
|
||||
(env) => {
|
||||
const result = runCiFontStep(env);
|
||||
assert.equal(result.status, 1);
|
||||
assert.match(result.calls, /dpkg-deb --extract/);
|
||||
assert.doesNotMatch(result.calls, /sudo/);
|
||||
assert.match(result.stdout, /::error::default sans-serif is 'WenQuanYi/);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
for (const failure of ['aptStatus', 'extractStatus']) {
|
||||
test(`CI fails closed when ${failure} fails`, () => {
|
||||
withCase({ family: 'WenQuanYi Zen Hei', [failure]: '1' }, (env) => {
|
||||
const result = runCiFontStep(env);
|
||||
assert.equal(result.status, 1);
|
||||
assert.doesNotMatch(result.calls, /sudo|apt-get install/);
|
||||
assert.doesNotMatch(result.stdout, /default sans-serif = DejaVu Sans/);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
test('CI keeps fonts in the configured XDG data directory', () => {
|
||||
withCase(
|
||||
{ family: 'WenQuanYi Zen Hei', repairFamily: true, customDataHome: true },
|
||||
(env) => {
|
||||
const result = runCiFontStep(env);
|
||||
assert.equal(result.status, 0, result.stderr);
|
||||
assert.equal(
|
||||
readFileSync(
|
||||
join(
|
||||
env.XDG_DATA_HOME,
|
||||
'fonts/qwen-ci/truetype/dejavu/DejaVuSans.ttf',
|
||||
),
|
||||
'utf8',
|
||||
),
|
||||
'fixture-font',
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
test('CI never executes a PR-provided installer', () => {
|
||||
withCase({ family: 'WenQuanYi Zen Hei', repairFamily: true }, (env) => {
|
||||
const result = runCiFontStep(env, {
|
||||
installer: 'printf "head-installer\\n" >> "$CASE_DIR/calls"\nexit 0\n',
|
||||
});
|
||||
assert.equal(result.status, 0, result.stderr);
|
||||
assert.doesNotMatch(result.calls, /head-installer|sudo/);
|
||||
});
|
||||
});
|
||||
|
||||
test('CI never elevates a PR-provided checker', () => {
|
||||
withCase({ family: 'WenQuanYi Zen Hei', repairFamily: true }, (env) => {
|
||||
const result = runCiFontStep(env, {
|
||||
checker:
|
||||
'if [ "${CASE_AS_ROOT:-0}" = 1 ]; then printf "privileged-checker\\n" >> "$CASE_DIR/calls"; fi\n' +
|
||||
readFileSync(checkScript, 'utf8'),
|
||||
});
|
||||
assert.equal(result.status, 0, result.stderr);
|
||||
assert.doesNotMatch(result.calls, /privileged-checker|sudo/);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,27 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Only the runner's own cache can be repaired; a configured shared cache
|
||||
# requires runner provisioning rather than a job changing its permissions.
|
||||
cache_path="${RUNNER_TOOL_CACHE:?}"
|
||||
if [ ! -e "$cache_path" ] && [ ! -L "$cache_path" ]; then
|
||||
exit 0
|
||||
fi
|
||||
tool_cache="$(cd -P -- "$cache_path" && pwd -P)"
|
||||
runner_work="$(cd -P -- "${RUNNER_TEMP:?}" && cd .. && pwd -P)"
|
||||
if [ "$tool_cache" != "$runner_work/_tool" ]; then
|
||||
echo "::error::Refusing to change Java cache outside this runner's work directory: $tool_cache"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
java_cache="$tool_cache/Java_Temurin-Hotspot_jdk"
|
||||
if [ -L "$java_cache" ] || { [ -e "$java_cache" ] && [ ! -d "$java_cache" ]; }; then
|
||||
echo "::error::Refusing to change a redirected or non-directory Java cache: $java_cache"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
trap 'echo "::error::Could not restore the runner-local Java cache; the runner needs permission repair: $java_cache"' ERR
|
||||
owner="$(id -u):$(id -g)"
|
||||
mkdir -p -- "$java_cache" 2>/dev/null || sudo -n mkdir -p -- "$java_cache"
|
||||
chown -hR -- "$owner" "$java_cache" 2>/dev/null || sudo -n chown -hR -- "$owner" "$java_cache"
|
||||
chmod -R u+rwX "$java_cache" 2>/dev/null || sudo -n chmod -R u+rwX "$java_cache"
|
||||
@@ -60,7 +60,7 @@
|
||||
1079 scorecard-monthly.yml
|
||||
9751 sdk-java-contract-open-prs.yml
|
||||
9555 sdk-java-flyway-open-prs.yml
|
||||
155888 sdk-java.yml
|
||||
159831 sdk-java.yml
|
||||
3886 sdk-python.yml
|
||||
5595 security-checks.yml
|
||||
6777 serve-ab-publish.yml
|
||||
|
||||
@@ -695,7 +695,7 @@ jobs:
|
||||
# runners, so such state persists. Start the shard-owned cache
|
||||
# empty — and only that exact path, so a runner-exported shared
|
||||
# cache and lint's already-warmed run-unique home stay untouched.
|
||||
if [ "${COREPACK_HOME:-}" = "${RUNNER_TEMP:-}/qwen-ci-corepack" ]; then
|
||||
if [ -n "${RUNNER_TEMP:-}" ] && [ "${COREPACK_HOME:-}" = "${RUNNER_TEMP:-}/qwen-ci-corepack" ]; then
|
||||
rm -rf -- "${COREPACK_HOME}"
|
||||
fi
|
||||
corepack pnpm install --frozen-lockfile --prefer-offline --reporter=append-only
|
||||
@@ -1194,7 +1194,7 @@ jobs:
|
||||
# runners, so such state persists. Start the shard-owned cache
|
||||
# empty — and only that exact path, so a runner-exported shared
|
||||
# cache and lint's already-warmed run-unique home stay untouched.
|
||||
if [ "${COREPACK_HOME:-}" = "${RUNNER_TEMP:-}/qwen-ci-corepack" ]; then
|
||||
if [ -n "${RUNNER_TEMP:-}" ] && [ "${COREPACK_HOME:-}" = "${RUNNER_TEMP:-}/qwen-ci-corepack" ]; then
|
||||
rm -rf -- "${COREPACK_HOME}"
|
||||
fi
|
||||
corepack pnpm install --frozen-lockfile --prefer-offline --reporter=append-only
|
||||
@@ -1992,7 +1992,7 @@ jobs:
|
||||
# runners, so such state persists. Start the shard-owned cache
|
||||
# empty — and only that exact path, so a runner-exported shared
|
||||
# cache and lint's already-warmed run-unique home stay untouched.
|
||||
if [ "${COREPACK_HOME:-}" = "${RUNNER_TEMP:-}/qwen-ci-corepack" ]; then
|
||||
if [ -n "${RUNNER_TEMP:-}" ] && [ "${COREPACK_HOME:-}" = "${RUNNER_TEMP:-}/qwen-ci-corepack" ]; then
|
||||
rm -rf -- "${COREPACK_HOME}"
|
||||
fi
|
||||
corepack pnpm install --frozen-lockfile --prefer-offline --reporter=append-only
|
||||
@@ -2407,6 +2407,26 @@ jobs:
|
||||
echo 'font baseline check: skipped (script not present in this checkout)'
|
||||
exit 0
|
||||
fi
|
||||
# A recoverable setup gap should not emit a failure annotation.
|
||||
if GITHUB_ACTIONS='' bash .github/scripts/ecs-runner/check-font-baseline.sh; then
|
||||
exit 0
|
||||
fi
|
||||
# Keep PR-supplied code at the runner's existing privilege level.
|
||||
font_stage="$(mktemp -d "${RUNNER_TEMP:-/tmp}/qwen-fonts.XXXXXX")"
|
||||
trap 'rm -rf -- "${font_stage}"' EXIT
|
||||
mkdir -p "${font_stage}/lists/partial" "${font_stage}/packages"
|
||||
apt-get -o "Dir::State::lists=${font_stage}/lists" update -qq
|
||||
(
|
||||
cd "${font_stage}/packages"
|
||||
apt-get -o "Dir::State::lists=${font_stage}/lists" download fonts-dejavu-core fonts-dejavu-mono
|
||||
)
|
||||
for archive in "${font_stage}"/packages/*.deb; do
|
||||
dpkg-deb --extract "${archive}" "${font_stage}/extracted"
|
||||
done
|
||||
font_dir="${XDG_DATA_HOME:-${HOME}/.local/share}/fonts/qwen-ci"
|
||||
mkdir -p "${font_dir}"
|
||||
cp -R "${font_stage}/extracted/usr/share/fonts/." "${font_dir}/"
|
||||
fc-cache -f "${font_dir}"
|
||||
bash .github/scripts/ecs-runner/check-font-baseline.sh
|
||||
|
||||
# The build comes from test_build's tree below, not from `prepare`.
|
||||
|
||||
@@ -356,6 +356,13 @@ jobs:
|
||||
if [[ "${RUN_ATTEMPT}" == '1' ]]; then
|
||||
total=0
|
||||
infra=0
|
||||
# The gate workflow's reporter job is always() and fails with
|
||||
# only the tier-result error, which carries no infrastructure
|
||||
# signature; excluding it by its failing step keeps a lane's
|
||||
# infra death classifiable. Filtering the step rather than the
|
||||
# job keeps the legitimate rerun: when the reporter's own
|
||||
# runner dies no step has failed, so the job still counts and
|
||||
# its GitHub-generated annotation still matches.
|
||||
while IFS=$'\t' read -r job_id check_run_id; do
|
||||
total=$((total + 1))
|
||||
annotations=''
|
||||
|
||||
@@ -362,9 +362,9 @@ jobs:
|
||||
release="${RUNNER_TEMP}/managed-agent-reference"
|
||||
cd "${release}"
|
||||
sha256sum --check SHA256SUMS.txt
|
||||
mkdir extracted
|
||||
tar -xzf "qwen-managed-agent-reference-${RELEASE_VERSION}.tar.gz" -C extracted
|
||||
bundle="${release}/extracted/qwen-managed-agent-reference-${RELEASE_VERSION}"
|
||||
extracted="$(mktemp -d "${release}/extracted.XXXXXX")"
|
||||
tar -xzf "qwen-managed-agent-reference-${RELEASE_VERSION}.tar.gz" -C "${extracted}"
|
||||
bundle="${extracted}/qwen-managed-agent-reference-${RELEASE_VERSION}"
|
||||
cd "${bundle}"
|
||||
sha256sum --check SHA256SUMS
|
||||
# The upgrade command compares these scripts across releases, so it
|
||||
|
||||
@@ -207,6 +207,18 @@ jobs:
|
||||
# and the post-job save tars that whole shared repository — 14 to 37
|
||||
# minutes per job on 2026-10-16 — only to lose the reservation race to
|
||||
# a parallel job and discard the archive.
|
||||
# Only default _tool caches are candidates for permission repair; the
|
||||
# helper still checks their canonical runner-local path. Shared caches
|
||||
# keep their provisioned permissions and use normal setup-java.
|
||||
- name: 'Restore runner-local Java tool cache'
|
||||
if: "${{ runner.environment == 'self-hosted' && endsWith(runner.tool_cache, '/_tool') }}"
|
||||
run: |-
|
||||
if [ -f .github/scripts/restore-java-tool-cache.sh ]; then
|
||||
bash .github/scripts/restore-java-tool-cache.sh
|
||||
else
|
||||
echo '::warning::this ref predates restore-java-tool-cache.sh; the runner-local Java cache is left as provisioned'
|
||||
fi
|
||||
|
||||
- name: 'Set up Java'
|
||||
uses: 'actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654' # v5.2.0
|
||||
with:
|
||||
@@ -809,6 +821,15 @@ jobs:
|
||||
if: "${{ runner.environment == 'self-hosted' }}"
|
||||
run: 'bash .github/scripts/check-disk-floor.sh "${GITHUB_WORKSPACE}" "${RUNNER_TEMP:-/tmp}"'
|
||||
|
||||
- name: 'Restore runner-local Java tool cache'
|
||||
if: "${{ runner.environment == 'self-hosted' && endsWith(runner.tool_cache, '/_tool') }}"
|
||||
run: |-
|
||||
if [ -f .github/scripts/restore-java-tool-cache.sh ]; then
|
||||
bash .github/scripts/restore-java-tool-cache.sh
|
||||
else
|
||||
echo '::warning::this ref predates restore-java-tool-cache.sh; the runner-local Java cache is left as provisioned'
|
||||
fi
|
||||
|
||||
- name: 'Set up Java'
|
||||
uses: 'actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654' # v5.2.0
|
||||
with:
|
||||
@@ -1818,6 +1839,15 @@ jobs:
|
||||
if: "${{ runner.environment == 'self-hosted' }}"
|
||||
run: 'bash .github/scripts/check-disk-floor.sh "${GITHUB_WORKSPACE}" "${RUNNER_TEMP:-/tmp}"'
|
||||
|
||||
- name: 'Restore runner-local Java tool cache'
|
||||
if: "${{ runner.environment == 'self-hosted' && endsWith(runner.tool_cache, '/_tool') }}"
|
||||
run: |-
|
||||
if [ -f .github/scripts/restore-java-tool-cache.sh ]; then
|
||||
bash .github/scripts/restore-java-tool-cache.sh
|
||||
else
|
||||
echo '::warning::this ref predates restore-java-tool-cache.sh; the runner-local Java cache is left as provisioned'
|
||||
fi
|
||||
|
||||
- name: 'Set up Java'
|
||||
uses: 'actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654' # v5.2.0
|
||||
with:
|
||||
@@ -2102,6 +2132,15 @@ jobs:
|
||||
if: "${{ runner.environment == 'self-hosted' }}"
|
||||
run: 'bash .github/scripts/check-disk-floor.sh "${GITHUB_WORKSPACE}" "${RUNNER_TEMP:-/tmp}"'
|
||||
|
||||
- name: 'Restore runner-local Java tool cache'
|
||||
if: "${{ runner.environment == 'self-hosted' && endsWith(runner.tool_cache, '/_tool') }}"
|
||||
run: |-
|
||||
if [ -f .github/scripts/restore-java-tool-cache.sh ]; then
|
||||
bash .github/scripts/restore-java-tool-cache.sh
|
||||
else
|
||||
echo '::warning::this ref predates restore-java-tool-cache.sh; the runner-local Java cache is left as provisioned'
|
||||
fi
|
||||
|
||||
- name: 'Set up Java'
|
||||
uses: 'actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654' # v5.2.0
|
||||
with:
|
||||
@@ -2493,6 +2532,15 @@ jobs:
|
||||
node-version: '22'
|
||||
package-manager-cache: false
|
||||
|
||||
- name: 'Restore runner-local Java tool cache'
|
||||
if: "${{ runner.environment == 'self-hosted' && endsWith(runner.tool_cache, '/_tool') }}"
|
||||
run: |-
|
||||
if [ -f .github/scripts/restore-java-tool-cache.sh ]; then
|
||||
bash .github/scripts/restore-java-tool-cache.sh
|
||||
else
|
||||
echo '::warning::this ref predates restore-java-tool-cache.sh; the runner-local Java cache is left as provisioned'
|
||||
fi
|
||||
|
||||
- name: 'Use pre-installed Node.js (self-hosted)'
|
||||
if: "${{ runner.environment == 'self-hosted' }}"
|
||||
run: |-
|
||||
|
||||
Reference in new issue
Block a user