fix(ci): refresh host assets on older PR checkouts (#16476)

* fix(ci): refresh host assets on older PR checkouts

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

* style(ci): format host asset regression cases

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-11-07 01:42:26 +08:00
1 parent ad83860092
commit 8660f75430
2 files changed
+74 -5

No files matched your search

+14 -5
View File
@@ -739,7 +739,7 @@ jobs:
# The key carries no runner.arch. The x64-labelled pool includes ARM64
# hosts, and every built path is JavaScript except the bundle's opentui
# native library, which `build` recopies for the host after restoring
# and every consumer recopies after unpacking (`host-assets`). Split
# and every consumer recopies after unpacking. Split
# by arch, each half of the pool restored the other half's misses.
- name: 'Restore the build cache'
id: 'build_cache'
@@ -1230,7 +1230,10 @@ jobs:
run: |-
tar -xzf "${RUNNER_TEMP}/unit-test-tree/unit-test-tree.tgz"
rm -rf "${RUNNER_TEMP}/unit-test-tree"
node scripts/ci-build-cache.mjs host-assets
# PR checkouts may predate the build-cache host-assets command.
if [ -f dist/cli.js ]; then
node --input-type=module -e 'import { copyOpenTuiAssets } from "./scripts/copy_bundle_assets.js"; copyOpenTuiAssets();'
fi
- name: 'Report npm cache usage (self-hosted)'
if: "${{ always() && needs.classify_pr.outputs.skip_ci != 'true' && steps.ci_profile.outputs.ci_profile == 'full' && runner.environment == 'self-hosted' }}"
@@ -2193,7 +2196,7 @@ jobs:
# used to rebuild every workspace (~10 minutes, four times per run):
# this lane's ARM64 cache was saved once and never refreshed, so it
# restored a stale build every time. The tree is JavaScript apart from
# the opentui native library, which `host-assets` recopies for ARM64.
# the opentui native library, which is recopied for ARM64 after unpacking.
# Drafts skip it, as they skip the no-AK integration gate.
needs:
- 'classify_pr'
@@ -2458,7 +2461,10 @@ jobs:
run: |-
tar -xzf "${RUNNER_TEMP}/unit-test-tree/unit-test-tree.tgz"
rm -rf "${RUNNER_TEMP}/unit-test-tree"
node scripts/ci-build-cache.mjs host-assets
# PR checkouts may predate the build-cache host-assets command.
if [ -f dist/cli.js ]; then
node --input-type=module -e 'import { copyOpenTuiAssets } from "./scripts/copy_bundle_assets.js"; copyOpenTuiAssets();'
fi
- name: 'Install Playwright Chromium and WebKit (hosted)'
if: "${{ runner.environment == 'github-hosted' }}"
@@ -3222,7 +3228,10 @@ jobs:
run: |-
tar -xzf "${RUNNER_TEMP}/unit-test-tree/unit-test-tree.tgz"
rm -rf "${RUNNER_TEMP}/unit-test-tree"
node scripts/ci-build-cache.mjs host-assets
# PR checkouts may predate the build-cache host-assets command.
if [ -f dist/cli.js ]; then
node --input-type=module -e 'import { copyOpenTuiAssets } from "./scripts/copy_bundle_assets.js"; copyOpenTuiAssets();'
fi
- name: 'Run required no-AK integration gate'
if: "${{ needs.test_build.result == 'success' && steps.ci_profile.outputs.ci_profile == 'full' }}"
+60
View File
@@ -443,6 +443,66 @@ it('pins the build-to-shard artifact handoff on both ends', () => {
);
});
it
.skipIf(process.platform === 'win32')
.each(['test', 'web_shell_e2e_smoke', 'integration_no_ak'])(
'refreshes host assets on older PR checkouts in %s',
(job) => {
const root = mkdtempSync(join(tmpdir(), 'ci-host-assets-'));
try {
mkdirSync(join(root, 'scripts'));
mkdirSync(join(root, 'dist', 'opentui-assets'), { recursive: true });
writeFileSync(join(root, 'package.json'), '{"type":"module"}');
writeFileSync(
join(root, 'scripts', 'ci-build-cache.mjs'),
'throw new Error("usage: ci-build-cache.mjs key | build <dir> | pack <dir> | paths");',
);
writeFileSync(
join(root, 'scripts', 'copy_bundle_assets.js'),
`import { copyFileSync } from 'node:fs';
export function copyOpenTuiAssets() {
copyFileSync('host-native.so', 'dist/opentui-assets/native.so');
}
`,
);
writeFileSync(join(root, 'host-native.so'), 'consumer-host');
writeFileSync(join(root, 'dist', 'cli.js'), 'built-bundle');
writeFileSync(
join(root, 'dist', 'opentui-assets', 'native.so'),
'build-host',
);
const runnerTemp = join(root, 'runner-temp');
const artifact = join(runnerTemp, 'unit-test-tree');
mkdirSync(artifact, { recursive: true });
execFileSync(
'tar',
['-czf', join(artifact, 'unit-test-tree.tgz'), 'dist'],
{
cwd: root,
},
);
rmSync(join(root, 'dist'), { recursive: true });
const unpack = ci.jobs[job].steps.find(
(step) => step.name === 'Unpack the built tree',
);
execFileSync('bash', ['-e', '-o', 'pipefail', '-c', unpack.run], {
cwd: root,
env: { ...process.env, RUNNER_TEMP: runnerTemp },
});
expect(readFileSync(join(root, 'dist', 'cli.js'), 'utf8')).toBe(
'built-bundle',
);
expect(
readFileSync(join(root, 'dist', 'opentui-assets', 'native.so'), 'utf8'),
).toBe('consumer-host');
} finally {
rmSync(root, { recursive: true, force: true });
}
},
);
it('keeps the no-AK gate above its dependency-install budget on ECS', () => {
expect(timeoutMinutesOn('integration_no_ak', ECS_RUNNER)).toBe(60);
});