修复 Gitea CI 镜像构建并刷新到 1.98.1 工具链

- 将 AGC 本地路径依赖的 cocos/unity/godot 编辑器 bridge crate 纳入镜像构建上下文与 dockerignore,修复 cargo fetch --locked 找不到 cocos-editor-bridge 导致的镜像构建失败
- 将 Chrome pin 由已下架的 150.0.7871.181-1 更新为当前 stable 153.0.8010.52-1
- 固定 Node/npm 解析:用绝对路径 wrapper 覆盖 base 镜像的 /opt/acttoolcache bin,避免 npm ci 的 node_modules/.bin 与 toolcache 影子化固定工具链
- 为镜像预热的 npm ci 增加最多 5 次整命令级有界重试,处理 registry ECONNRESET
- 镜像 tag 与 LABEL 升为 20260920.2,并同步 deploy/container/README.md 与开发运维文档
- 在 scripts/project-ci-workflow.test.ts 中钉住 bridge crate 构建上下文与固定工具链 wrapper
This commit is contained in:
2026-09-21 01:00:11 +08:00
parent 485ed50b26
commit e35917ab69
6 changed files with 97 additions and 23 deletions
+8 -3
View File
@@ -4,7 +4,7 @@ set -euo pipefail
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)"
dockerfile_context_path="deploy/container/gitea-ci-job.Dockerfile"
image_tag="${GENARRATIVE_GITEA_CI_IMAGE_TAG:-genarrative/gitea-project-ci:20260920.1}"
image_tag="${GENARRATIVE_GITEA_CI_IMAGE_TAG:-genarrative/gitea-project-ci:20260920.2}"
runner_container="${GENARRATIVE_GITEA_RUNNER_CONTAINER:-gitea-runner}"
write_build_context_file_list() {
@@ -29,7 +29,10 @@ write_build_context_file_list() {
server-rs/Cargo.lock \
apps/desktop-shell/src-tauri/Cargo.toml \
apps/desktop-shell/src-tauri/Cargo.lock
find server-rs/crates -name Cargo.toml -print0 | sort -z
find server-rs/crates plugins/agc-*-editor/native/*-editor-bridge \
\( -name Cargo.toml -o -path 'plugins/agc-*-editor/native/*-editor-bridge/*' \) \
-type f -print0 \
| sort -z
}
usage() {
@@ -87,7 +90,9 @@ case "${command_name}" in
server-rs/Cargo.lock \
apps/desktop-shell/src-tauri/Cargo.toml \
apps/desktop-shell/src-tauri/Cargo.lock
find server-rs/crates -name Cargo.toml -print0 \
find server-rs/crates plugins/agc-*-editor/native/*-editor-bridge \
\( -name Cargo.toml -o -path 'plugins/agc-*-editor/native/*-editor-bridge/*' \) \
-type f -print0 \
| sort -z \
| xargs -0 -r sha256sum
} \
+25 -1
View File
@@ -182,8 +182,16 @@ describe('project CI workflow', () => {
/^ARG RUNNER_IMAGE=[^\s]+@sha256:[a-f0-9]{64}$/m,
);
expect(imageDockerfile).toContain('ARG NPM_VERSION=10.9.7');
// base runner 镜像把 /opt/acttoolcache 的 Node 放在 PATH 最前;固定 Node/npm
// 必须写成绝对路径 wrapper 并覆盖 toolcache bin,否则登录与否会解析到不同工具链。
expect(imageDockerfile).toContain(
'npm install --global "npm@${NPM_VERSION}" --no-audit --no-fund',
'rm -rf /opt/acttoolcache/node/24.18.0/x64/bin',
);
expect(imageDockerfile).toContain(
'exec /usr/local/lib/genarrative-node/bin/node /usr/local/lib/genarrative-node/lib/node_modules/npm/bin/npm-cli.js "$@"',
);
expect(imageDockerfile).toContain(
'npm install --global --prefix /usr/local/lib/genarrative-node',
);
expect(imageDockerfile).toContain(
'GENARRATIVE_GITEA_CI_NPM_VERSION=${NPM_VERSION}',
@@ -263,6 +271,22 @@ describe('project CI workflow', () => {
expect(imageDockerignore).toContain(`!${path}`);
}
// AGC 通过本地 path 依赖引用三个编辑器 bridge crate。镜像预热会对
// AGC manifest 执行 cargo fetch --locked,构建上下文与 dockerignore
// 必须同时放行这些 crate,否则镜像在 cargo fetch 阶段必然失败。
for (const bridgeDir of [
'plugins/agc-cocos-editor/native/cocos-editor-bridge',
'plugins/agc-unity-editor/native/unity-editor-bridge',
'plugins/agc-godot-editor/native/godot-editor-bridge',
]) {
expect(imageBuildScript.split(bridgeDir)).toHaveLength(1);
expect(imageDockerignore).toContain(`!${bridgeDir}/`);
expect(imageDockerignore).toContain('**');
expect(imageDockerfile).toContain(
`COPY ${bridgeDir} /tmp/genarrative-cargo-cache/${bridgeDir}`,
);
}
expect(imageBuildScript).toContain(
'--build-arg "AGC_RUST_LOCK_SHA256=${agc_rust_lock_sha256}"',
);