merge: 同步 origin/v0.3
This commit is contained in:
@@ -992,9 +992,9 @@ function envReuseDockerfile(baseImage, labels = [], recipe, service = null) {
|
||||
? `RUN ${downloadEnvPrefix}${goBuildEnvPrefix}set -eu; ${stepTimingHelpers}; mkdir -p ${shellQuote(normalizedRecipe.runtimeGoModCachePath)} ${shellQuote(normalizedRecipe.runtimeGoBuildCachePath)}; ${goDownloadRetryScript}; timed_stage "go-mod-download" retry_go_mod_download`
|
||||
: null;
|
||||
const goReadiness = goCacheEnabled
|
||||
? `; mkdir -p ${shellQuote(normalizedRecipe.runtimeGoModCachePath)} ${shellQuote(normalizedRecipe.runtimeGoBuildCachePath)}; command -v go >/dev/null; go version >/tmp/hwlab-env-go-version.txt`
|
||||
? `; mkdir -p ${shellQuote(normalizedRecipe.runtimeGoModCachePath)} ${shellQuote(normalizedRecipe.runtimeGoBuildCachePath)}; command -v go >/dev/null; command -v tini >/dev/null; go version >/tmp/hwlab-env-go-version.txt`
|
||||
: "";
|
||||
const baseOsPackages = uniquePreserveOrder(normalizedRecipe.osPackages);
|
||||
const baseOsPackages = uniquePreserveOrder([...normalizedRecipe.osPackages, "tini"]);
|
||||
const goOsPackages = goCacheEnabled ? uniquePreserveOrder(normalizedRecipe.goOsPackages) : [];
|
||||
const downloadDependencyScript = `set -eu; ${npmConfigScript}; if [ -f package-lock.json ]; then npm ci --omit=dev --include=optional --ignore-scripts; else npm install --omit=dev --include=optional --ignore-scripts; fi; if command -v bun >/dev/null 2>&1; then bun_path="$(command -v bun)"; if [ "$bun_path" != "/usr/local/bin/bun" ]; then ln -sf "$bun_path" /usr/local/bin/bun; fi; fi; if [ ! -x /usr/local/bin/bun ]; then bun_pkg=""; case "$(uname -m)" in x86_64|amd64) bun_pkg="${normalizedRecipe.downloadStack.bunPackages.x64}@${normalizedRecipe.bunVersion}" ;; aarch64|arm64) bun_pkg="${normalizedRecipe.downloadStack.bunPackages.arm64}@${normalizedRecipe.bunVersion}" ;; *) echo "unsupported bun architecture: $(uname -m)" >&2; false ;; esac; npm install --no-save --omit=dev --include=optional --ignore-scripts "$bun_pkg"; bun_bin="node_modules/\${bun_pkg%@*}/bin/bun"; test -x "$bun_bin"; ln -sf "${runtimeRoot}/$bun_bin" /usr/local/bin/bun; fi`;
|
||||
const aptRetryHelpers = `retry_apt_update() { attempts=6; n=1; while ! apt-get update -o Acquire::Retries=3; do if [ "$n" -ge "$attempts" ]; then return 1; fi; echo "apt-get update attempt $n/$attempts failed; retrying" >&2; n=$((n + 1)); rm -rf /var/lib/apt/lists/*; sleep 5; done; }; apt_packages_ready() { for pkg in "$@"; do dpkg-query -W -f='\${Status}' "$pkg" 2>/dev/null | grep -q 'install ok installed' || return 1; done; }; retry_apt_install() { attempts=8; n=1; while true; do apt-get install -o Acquire::Retries=3 -y --no-install-recommends --fix-missing "$@" || true; if apt_packages_ready "$@"; then return 0; fi; if [ "$n" -ge "$attempts" ]; then return 1; fi; echo "apt-get install attempt $n/$attempts incomplete; retrying" >&2; n=$((n + 1)); sleep 5; timed_stage "apt-update-retry" apt-get update -o Acquire::Retries=3 || true; done; }`;
|
||||
@@ -1009,12 +1009,12 @@ function envReuseDockerfile(baseImage, labels = [], recipe, service = null) {
|
||||
: `timed_skip "apt-install-go"`;
|
||||
const osPackageSections = [aptInstallSection("base", baseOsPackages), goPackageSection].filter(Boolean).join("; ");
|
||||
const osPackageScript = goBaseImageEnabled
|
||||
? `set -eu; ${stepTimingHelpers}; timed_skip "apt-update"; timed_skip "apt-install-base"; timed_skip "apt-install-go"`
|
||||
? `set -eu; export DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC; ${stepTimingHelpers}; ${aptRetryHelpers}; timed_skip "apt-install-base"; timed_skip "apt-install-go"; ${aptInstallSection("init", ["tini"])}; rm -rf /var/lib/apt/lists/*`
|
||||
: `set -eu; export DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC; ${stepTimingHelpers}; ${aptRetryHelpers}; ${osPackageSections}; rm -rf /var/lib/apt/lists/*`;
|
||||
const aliasScript = normalizedRecipe.hwpodAliases.map((alias) => `printf '%s\\n' '#!/usr/bin/env sh' 'exec node /workspace/hwlab-boot/repo/scripts/run-bun.mjs /workspace/hwlab-boot/repo/${alias.script} \"$@\"' > /usr/local/bin/${alias.command}; chmod 755 /usr/local/bin/${alias.command}`).join("; ");
|
||||
const readinessScript = goCacheEnabled
|
||||
? `set -eu; command -v node >/dev/null; command -v git >/dev/null; command -v sh >/dev/null${goReadiness}; test -f /usr/local/bin/hwlab-go-env-reuse-launcher.mjs`
|
||||
: `set -eu; command -v node >/dev/null; command -v npm >/dev/null; command -v git >/dev/null; command -v sh >/dev/null; test -d ${shellQuote(normalizedRecipe.runtimeNodeModulesPath)}; test -x /usr/local/bin/bun; /usr/local/bin/bun --version >/tmp/hwlab-env-bun-version.txt; ${aliasScript}`;
|
||||
: `set -eu; command -v node >/dev/null; command -v npm >/dev/null; command -v git >/dev/null; command -v sh >/dev/null; command -v tini >/dev/null; test -d ${shellQuote(normalizedRecipe.runtimeNodeModulesPath)}; test -x /usr/local/bin/bun; /usr/local/bin/bun --version >/tmp/hwlab-env-bun-version.txt; ${aliasScript}`;
|
||||
return [
|
||||
`FROM ${effectiveBaseImage}`,
|
||||
`WORKDIR ${runtimeRoot}`,
|
||||
@@ -1032,6 +1032,7 @@ function envReuseDockerfile(baseImage, labels = [], recipe, service = null) {
|
||||
...(goCacheEnabled ? [] : [`ENV HWLAB_RUNTIME_NODE_MODULES=${normalizedRecipe.runtimeNodeModulesPath}`]),
|
||||
...goEnv,
|
||||
"ENV PATH=/usr/local/bin:$PATH",
|
||||
"ENTRYPOINT [\"tini\", \"--\"]",
|
||||
goCacheEnabled
|
||||
? "CMD [\"node\", \"/usr/local/bin/hwlab-go-env-reuse-launcher.mjs\"]"
|
||||
: "CMD [\"/usr/local/bin/bun\", \"/usr/local/bin/hwlab-env-reuse-launcher.ts\"]",
|
||||
@@ -1397,7 +1398,7 @@ async function buildEnvReuseService({ args, repo, commitId, service, buildCreate
|
||||
}
|
||||
|
||||
function goEnvBaseDockerfile(baseImage, recipe) {
|
||||
const packages = uniquePreserveOrder([...recipe.osPackages, ...recipe.goOsPackages]).map(shellQuote).join(" ");
|
||||
const packages = uniquePreserveOrder([...recipe.osPackages, ...recipe.goOsPackages, "tini"]).map(shellQuote).join(" ");
|
||||
const stepTimingHelpers = `emit_hwlab_timing() { stage="$1"; status="$2"; duration_ms="$3"; node -e "console.error(JSON.stringify({event:'node-cicd-build-step-timing',stage:process.argv[1],status:process.argv[2],durationMs:Number(process.argv[3]),source:'dockerfile-run'}))" "$stage" "$status" "$duration_ms"; }; timed_stage() { label="$1"; shift; start="$(node -e "console.log(Date.now())")"; status=succeeded; "$@" || status=failed; end="$(node -e "console.log(Date.now())")"; elapsed=$((end - start)); emit_hwlab_timing "$label" "$status" "$elapsed"; test "$status" = succeeded; }; timed_skip() { emit_hwlab_timing "$1" skipped 0; }`;
|
||||
const aptHelpers = `retry_apt_update() { attempts=6; n=1; while ! apt-get update -o Acquire::Retries=3; do if [ "$n" -ge "$attempts" ]; then return 1; fi; echo "apt-get update attempt $n/$attempts failed; retrying" >&2; n=$((n + 1)); rm -rf /var/lib/apt/lists/*; sleep 5; done; }; apt_packages_ready() { for pkg in "$@"; do dpkg-query -W -f='\${Status}' "$pkg" 2>/dev/null | grep -q 'install ok installed' || return 1; done; }; retry_apt_install() { attempts=8; n=1; while true; do apt-get install -o Acquire::Retries=3 -y --no-install-recommends --fix-missing "$@" || true; if apt_packages_ready "$@"; then return 0; fi; if [ "$n" -ge "$attempts" ]; then return 1; fi; echo "apt-get install attempt $n/$attempts incomplete; retrying" >&2; n=$((n + 1)); sleep 5; timed_stage "go-base-apt-update-retry" apt-get update -o Acquire::Retries=3 || true; done; }`;
|
||||
const aptUpdateScript = `timed_stage "go-base-apt-update" retry_apt_update || (for f in /etc/apt/sources.list /etc/apt/sources.list.d/*.sources; do [ -f "$f" ] || continue; sed -i -e '/^[[:space:]]*deb .* bookworm-updates /d' -e 's/[[:space:]]bookworm-updates//g' -e 's/bookworm-updates[[:space:]]//g' "$f"; done; timed_stage "go-base-apt-update-fallback" retry_apt_update)`;
|
||||
|
||||
@@ -738,6 +738,10 @@ test("artifact reuse paths preserve catalog provenance instead of current planne
|
||||
assert.match(artifactPublish, /goCacheEnabled \? \[\] : \["COPY package\.json \.\/package\.json", "COPY package-lock\.json\* \.\/"\]/u);
|
||||
assert.match(artifactPublish, /goCacheEnabled \? \[\] : \[`RUN \$\{downloadEnvPrefix\}\$\{downloadDependencyScript\}`\]/u);
|
||||
assert.match(artifactPublish, /CMD \[\\"node\\", \\"\/usr\/local\/bin\/hwlab-go-env-reuse-launcher\.mjs\\"\]/u);
|
||||
assert.match(artifactPublish, /ENTRYPOINT \[\\"tini\\", \\"--\\"\]/u);
|
||||
assert.match(artifactPublish, /command -v tini >\/dev\/null/u);
|
||||
assert.match(artifactPublish, /\.\.\.recipe\.goOsPackages, "tini"/u);
|
||||
assert.match(artifactPublish, /aptInstallSection\("init", \["tini"\]\)/u);
|
||||
assert.match(artifactPublish, /ln -sf "\$\{runtimeRoot\}\/\$bun_bin" \/usr\/local\/bin\/bun/u);
|
||||
assert.doesNotMatch(artifactPublish, /RUN \$\{dependencyScript\}/u);
|
||||
assert.match(artifactPublish, /const catalogProvenance = serviceImageCatalogProvenance\(catalogService\);/u);
|
||||
|
||||
Reference in New Issue
Block a user