From 3561efa7da022982ca7c2c7f1b1312b08afc091c Mon Sep 17 00:00:00 2001 From: chengcheng Date: Tue, 21 Jul 2026 10:36:56 +0800 Subject: [PATCH] =?UTF-8?q?fix(ci):=20=E5=85=81=E8=AE=B8=E5=A4=8D=E7=94=A8?= =?UTF-8?q?=E5=9B=BA=E5=AE=9A=E6=91=98=E8=A6=81=E7=9A=84=20Runner=20?= =?UTF-8?q?=E9=95=9C=E5=83=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 本地已存在完全相同 digest 的 Runner 镜像时跳过外部拉取,继续执行二进制校验与隔离探针;仅在镜像缺失时访问仓库。 避免 Docker Hub 瞬时不可达导致专用 CI Runner 无法恢复。 --- docs/runbooks/production-ci-cd.md | 2 +- scripts/provision-ci-runner.sh | 4 +++- tests/ci/pipeline-test.sh | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/runbooks/production-ci-cd.md b/docs/runbooks/production-ci-cd.md index ad30679..794170f 100644 --- a/docs/runbooks/production-ci-cd.md +++ b/docs/runbooks/production-ci-cd.md @@ -16,7 +16,7 @@ 生产 CD 由部署仓的 root-owned dispatcher 执行。它在相同源码 SHA 上同时等待 `ci / verify (push)` 与本次新产生的 `release-ci / verify-tag (push)` 成功,然后只运行部署仓中固定的 BuildKit 构建、Trivy 镜像扫描、digest 发布、备份、迁移、健康检查和回滚命令;不得执行 Tag checkout 中的 `pnpm`、测试、shell 脚本或应用程序。 -provision 安装 checksum-pinned 的官方静态 ShellCheck `0.11.0`、Docker Compose `5.3.1`,并从固定 digest 的 Runner 镜像提取 Docker CLI `29.6.0` 后校验二进制 SHA-256;不会依赖宿主是否预装这些命令。所有工具都在精确 Node Job 镜像内实际执行版本检查。 +provision 安装 checksum-pinned 的官方静态 ShellCheck `0.11.0`、Docker Compose `5.3.1`,并从固定 digest 的 Runner 镜像提取 Docker CLI `29.6.0` 后校验二进制 SHA-256;不会依赖宿主是否预装这些命令。固定 digest 的 Runner 镜像已存在时可离线复用,缺失时才访问镜像仓库。所有工具都在精确 Node Job 镜像内实际执行版本检查。 ## 首次安装或修复 CI Runner diff --git a/scripts/provision-ci-runner.sh b/scripts/provision-ci-runner.sh index 8cf4848..eae66c7 100755 --- a/scripts/provision-ci-runner.sh +++ b/scripts/provision-ci-runner.sh @@ -192,7 +192,9 @@ GOBIN="$PREFIX/bin" GOPROXY="${GO_MODULE_PROXY:-https://goproxy.cn,direct}" \ "$PREFIX/toolchains/go/bin/go" install golang.org/x/vuln/cmd/govulncheck@v1.6.0 require_free_space "$MIN_FREE_GIB" "runner image pull" -docker pull "$RUNNER_IMAGE_SOURCE" +if ! docker image inspect "$RUNNER_IMAGE_SOURCE" >/dev/null 2>&1; then + docker pull "$RUNNER_IMAGE_SOURCE" +fi runner_runtime_image=$(docker image inspect --format '{{.Id}}' "$RUNNER_IMAGE_SOURCE") printf '%s\n' "$runner_runtime_image" | grep -Eq '^sha256:[0-9a-f]{64}$' || \ fail "pinned runner image did not resolve to an immutable local image ID" diff --git a/tests/ci/pipeline-test.sh b/tests/ci/pipeline-test.sh index a6edbe1..7a609fb 100755 --- a/tests/ci/pipeline-test.sh +++ b/tests/ci/pipeline-test.sh @@ -272,6 +272,7 @@ grep -Fq "RUNNER_IMAGE='$runner_image'" "$provision" grep -Fq 'RUNNER_IMAGE_SOURCE=${CI_RUNNER_IMAGE_SOURCE:-$RUNNER_IMAGE}' "$provision" grep -Fq 'runner_manifest_digest=${RUNNER_IMAGE##*@}' "$provision" grep -Fq 'CI_RUNNER_IMAGE_SOURCE must use the pinned runner manifest digest' "$provision" +grep -Fq 'if ! docker image inspect "$RUNNER_IMAGE_SOURCE"' "$provision" grep -Fq 'runner_runtime_image=$(docker image inspect' "$provision" grep -Fq 'RUNNER_IMAGE_REF="%s"' "$provision" grep -Fq "JOB_IMAGE='$job_image'" "$provision"