Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1be2f0f072 | ||
|
|
7d8d9d8a2a |
@@ -16,9 +16,9 @@ on:
|
||||
default: 1
|
||||
verify-sha:
|
||||
required: false
|
||||
type: boolean
|
||||
default: true
|
||||
description: "Fail unless the checked-out HEAD equals the triggering commit"
|
||||
type: string
|
||||
default: "yes"
|
||||
description: "Empty disables; otherwise fail unless HEAD equals the triggering commit (boolean inputs are NOT reliable through workflow_call with:)"
|
||||
|
||||
jobs:
|
||||
checkout:
|
||||
@@ -32,7 +32,7 @@ jobs:
|
||||
fetch-depth: ${{ inputs.fetch-depth }}
|
||||
|
||||
- name: verify HEAD equals triggering commit
|
||||
if: inputs.verify-sha
|
||||
if: inputs.verify-sha != ''
|
||||
run: |
|
||||
set -eu
|
||||
test "$(git rev-parse HEAD)" = "${GITHUB_SHA}"
|
||||
|
||||
@@ -44,7 +44,27 @@ on:
|
||||
required: false
|
||||
type: string
|
||||
default: /data/cache/ci/quality
|
||||
description: "Persistent host-side cache dir (pnpm store, tools, browsers)"
|
||||
description: "Host-side cache dir (pnpm store, tools, browsers)"
|
||||
cache-mode:
|
||||
required: false
|
||||
type: string
|
||||
default: fixed
|
||||
description: "fixed: one shared persistent dir. per-run: fresh mktemp child per run + always() cleanup (for scripts with from-zero guards on commit-keyed tool caches)"
|
||||
mount-docker-socket:
|
||||
required: false
|
||||
type: string
|
||||
default: ""
|
||||
description: "Non-empty (e.g. 'yes') mounts /var/run/docker.sock into the toolchain containers (boolean inputs are NOT passed reliably through workflow_call with:)"
|
||||
commit-env-name:
|
||||
required: false
|
||||
type: string
|
||||
default: ""
|
||||
description: "Env var name that receives the triggering commit SHA inside the containers (e.g. EST_GIT_COMMIT); empty disables"
|
||||
extra-env:
|
||||
required: false
|
||||
type: string
|
||||
default: ""
|
||||
description: "Multiline KEY=VALUE extra env for the toolchain containers (values must not contain spaces; caller-side expressions are NOT evaluated)"
|
||||
secrets:
|
||||
REGISTRY_PASSWORD:
|
||||
required: false
|
||||
@@ -80,21 +100,51 @@ jobs:
|
||||
- name: prepare cache dir (dirs 0777, files untouched)
|
||||
run: |
|
||||
set -eu
|
||||
mkdir -p "${{ inputs.cache-dir }}"
|
||||
chmod 0777 "${{ inputs.cache-dir }}"
|
||||
find "${{ inputs.cache-dir }}" -mindepth 1 -maxdepth 1 -type d -exec chmod 0777 {} + 2>/dev/null || true
|
||||
cache_root="${{ inputs.cache-dir }}"
|
||||
mkdir -p "$cache_root"
|
||||
chmod 0777 "$cache_root"
|
||||
if [ "${{ inputs.cache-mode }}" = "per-run" ]; then
|
||||
cache_dir="$(mktemp -d "$cache_root/run-XXXXXXXX")"
|
||||
else
|
||||
cache_dir="$cache_root"
|
||||
fi
|
||||
chmod 0777 "$cache_dir"
|
||||
find "$cache_dir" -mindepth 1 -maxdepth 1 -type d -exec chmod 0777 {} + 2>/dev/null || true
|
||||
printf 'TOOL_CACHE_DIR=%s\n' "$cache_dir" >>"$GITHUB_ENV"
|
||||
|
||||
# install and quality run in ONE container: toolchains installed by the
|
||||
# install command (global pnpm, local bins) must still be on PATH for the
|
||||
# quality command — two `docker run --rm` invocations would not share
|
||||
# anything but the workspace and /cache mounts.
|
||||
- name: install and quality (containerized toolchain)
|
||||
env:
|
||||
COMMIT_ENV_NAME: ${{ inputs.commit-env-name }}
|
||||
run: |
|
||||
set -eu
|
||||
mount_args=""
|
||||
if [ -n "${{ inputs.mount-docker-socket }}" ]; then
|
||||
mount_args="-v /var/run/docker.sock:/var/run/docker.sock"
|
||||
fi
|
||||
env_args=""
|
||||
if [ -n "${COMMIT_ENV_NAME}" ]; then
|
||||
env_args="${env_args} -e ${COMMIT_ENV_NAME}=${GITHUB_SHA}"
|
||||
fi
|
||||
while IFS= read -r line; do
|
||||
[ -n "$line" ] && env_args="${env_args} -e $line"
|
||||
done <<EOF
|
||||
${{ inputs.extra-env }}
|
||||
EOF
|
||||
# shellcheck disable=SC2086
|
||||
docker run --rm --add-host npm.cache.est:172.17.0.1 \
|
||||
$mount_args \
|
||||
-v "$PWD:${{ inputs.workspace }}" -w "${{ inputs.workspace }}" \
|
||||
-v "${{ inputs.cache-dir }}:/cache" -e TMPDIR=/cache \
|
||||
-v "${TOOL_CACHE_DIR}:/cache" -e TMPDIR=/cache \
|
||||
-v /usr/local/share/ca-certificates/est-bundle.crt:/ca/est-bundle.crt:ro \
|
||||
-e SSL_CERT_FILE=/ca/est-bundle.crt \
|
||||
-e NODE_EXTRA_CA_CERTS=/ca/est-bundle.crt \
|
||||
$env_args \
|
||||
"${{ inputs.node-image }}" sh -euxc '${{ inputs.install-command }} && ${{ inputs.quality-command }}'
|
||||
|
||||
- name: cleanup per-run cache dir
|
||||
if: always() && inputs.cache-mode == 'per-run'
|
||||
run: rm -rf -- "${TOOL_CACHE_DIR:-}"
|
||||
|
||||
@@ -31,9 +31,10 @@ on:
|
||||
type: string
|
||||
description: "Digest-pinned helper image with node + docker CLI + verifier tooling"
|
||||
image-matrix:
|
||||
required: true
|
||||
required: false
|
||||
type: string
|
||||
description: "Multiline matrix: service|dockerfile|target per line"
|
||||
default: ""
|
||||
description: "Multiline matrix: service|dockerfile|target per line (required for the built-in loop; script mode uses it only for the digest summary)"
|
||||
platform:
|
||||
required: false
|
||||
type: string
|
||||
@@ -62,6 +63,41 @@ on:
|
||||
required: false
|
||||
type: string
|
||||
default: git.moneywood.site
|
||||
build-command:
|
||||
required: false
|
||||
type: string
|
||||
default: ""
|
||||
description: "Script mode: run this command inside the helper container (full mounts: sock/docker-config/buildx/CA/cache + envs) instead of the built-in matrix loop"
|
||||
install-command:
|
||||
required: false
|
||||
type: string
|
||||
default: ""
|
||||
description: "Script mode only: runs in the SAME container before build-command (toolchains installed here must survive to the build phase)"
|
||||
cache-dir:
|
||||
required: false
|
||||
type: string
|
||||
default: /data/cache/ci/build
|
||||
description: "Script mode: host-side cache dir mounted at /cache"
|
||||
cache-mode:
|
||||
required: false
|
||||
type: string
|
||||
default: fixed
|
||||
description: "fixed | per-run (per-run = fresh mktemp child + always() cleanup; for from-zero tool caches)"
|
||||
commit-env-name:
|
||||
required: false
|
||||
type: string
|
||||
default: ""
|
||||
description: "Script mode: env var receiving the commit SHA inside the container (e.g. EST_GIT_COMMIT)"
|
||||
extra-env:
|
||||
required: false
|
||||
type: string
|
||||
default: ""
|
||||
description: "Script mode: multiline KEY=VALUE extra env (no spaces in values; expressions NOT evaluated)"
|
||||
workspace:
|
||||
required: false
|
||||
type: string
|
||||
default: /workspace
|
||||
description: "Script mode: workspace mount point inside the container"
|
||||
secrets:
|
||||
REGISTRY_PASSWORD:
|
||||
required: true
|
||||
@@ -92,7 +128,60 @@ jobs:
|
||||
printf '%s' "${REGISTRY_PASSWORD}" \
|
||||
| docker login "${{ inputs.registry-host }}" -u "${{ github.actor }}" --password-stdin
|
||||
|
||||
- name: prepare script-mode cache dir
|
||||
if: inputs.build-command != ''
|
||||
run: |
|
||||
set -eu
|
||||
cache_root="${{ inputs.cache-dir }}"
|
||||
mkdir -p "$cache_root"
|
||||
chmod 0777 "$cache_root"
|
||||
if [ "${{ inputs.cache-mode }}" = "per-run" ]; then
|
||||
cache_dir="$(mktemp -d "$cache_root/run-XXXXXXXX")"
|
||||
else
|
||||
cache_dir="$cache_root"
|
||||
fi
|
||||
chmod 0777 "$cache_dir"
|
||||
find "$cache_dir" -mindepth 1 -maxdepth 1 -type d -exec chmod 0777 {} + 2>/dev/null || true
|
||||
printf 'TOOL_CACHE_DIR=%s\n' "$cache_dir" >>"$GITHUB_ENV"
|
||||
|
||||
- name: run build script (script mode)
|
||||
if: inputs.build-command != ''
|
||||
env:
|
||||
REGISTRY_AUTH_USER: ${{ github.actor }}
|
||||
REGISTRY_AUTH_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }}
|
||||
COMMIT_ENV_NAME: ${{ inputs.commit-env-name }}
|
||||
run: |
|
||||
set -eu
|
||||
mount_args="-v /var/run/docker.sock:/var/run/docker.sock"
|
||||
if [ -f "$HOME/.docker/config.json" ]; then
|
||||
mount_args="$mount_args -v $HOME/.docker/config.json:/root/.docker/config.json:ro"
|
||||
fi
|
||||
if [ -f /usr/libexec/docker/cli-plugins/docker-buildx ]; then
|
||||
mount_args="$mount_args -v /usr/libexec/docker/cli-plugins/docker-buildx:/root/.docker/cli-plugins/docker-buildx:ro"
|
||||
fi
|
||||
env_args=""
|
||||
if [ -n "${COMMIT_ENV_NAME}" ]; then
|
||||
env_args="${env_args} -e ${COMMIT_ENV_NAME}=${GITHUB_SHA}"
|
||||
fi
|
||||
env_args="${env_args} -e REGISTRY_AUTH_USER -e REGISTRY_AUTH_PASSWORD"
|
||||
while IFS= read -r line; do
|
||||
[ -n "$line" ] && env_args="${env_args} -e $line"
|
||||
done <<EOF
|
||||
${{ inputs.extra-env }}
|
||||
EOF
|
||||
# shellcheck disable=SC2086
|
||||
docker run --rm --add-host npm.cache.est:172.17.0.1 \
|
||||
$mount_args \
|
||||
-v "$PWD:${{ inputs.workspace }}" -w "${{ inputs.workspace }}" \
|
||||
-v "${TOOL_CACHE_DIR}:/cache" -e TMPDIR=/cache \
|
||||
-v /usr/local/share/ca-certificates/est-bundle.crt:/ca/est-bundle.crt:ro \
|
||||
-e SSL_CERT_FILE=/ca/est-bundle.crt \
|
||||
-e NODE_EXTRA_CA_CERTS=/ca/est-bundle.crt \
|
||||
$env_args \
|
||||
"${{ inputs.node-image }}" sh -euxc '${{ inputs.install-command }} && ${{ inputs.build-command }}'
|
||||
|
||||
- name: build push and verify image matrix
|
||||
if: inputs.build-command == ''
|
||||
env:
|
||||
REGISTRY_AUTH_USER: ${{ github.actor }}
|
||||
REGISTRY_AUTH_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }}
|
||||
@@ -102,6 +191,7 @@ jobs:
|
||||
VERIFY_COMMAND: ${{ inputs.verify-command }}
|
||||
CACHE_REGISTRY_REF: ${{ inputs.cache-registry-ref }}
|
||||
REVISION_ARG_NAME: ${{ inputs.revision-arg-name }}
|
||||
IMAGE_MATRIX: ${{ inputs.image-matrix }}
|
||||
run: |
|
||||
set -eu
|
||||
IMAGE_TAG="git-${GITHUB_SHA}"
|
||||
@@ -137,6 +227,10 @@ jobs:
|
||||
done <<EOF
|
||||
${{ inputs.build-args }}
|
||||
EOF
|
||||
if [ -z "${IMAGE_MATRIX:-}" ]; then
|
||||
echo "image-matrix is required for the built-in loop (or use build-command script mode)" >&2
|
||||
exit 64
|
||||
fi
|
||||
if [ -n "${REVISION_ARG_NAME}" ]; then
|
||||
build_args="${build_args} --build-arg ${REVISION_ARG_NAME}=${GITHUB_SHA}"
|
||||
fi
|
||||
@@ -185,3 +279,35 @@ jobs:
|
||||
echo '```'
|
||||
} >>"${GITHUB_STEP_SUMMARY:-/dev/stdout}"
|
||||
cat "$digest_file"
|
||||
|
||||
- name: digest summary (script mode)
|
||||
if: inputs.build-command != '' && inputs.image-matrix != ''
|
||||
env:
|
||||
IMAGE_ROOT: ${{ inputs.image-root }}
|
||||
run: |
|
||||
set -eu
|
||||
image_tag="git-${GITHUB_SHA}"
|
||||
digest_file=".tmp-ci/digests-script.txt"
|
||||
mkdir -p .tmp-ci
|
||||
: >"$digest_file"
|
||||
while IFS='|' read -r service dockerfile target; do
|
||||
[ -n "${service:-}" ] || continue
|
||||
index_digest=$(docker buildx imagetools inspect "${IMAGE_ROOT}/${service}:${image_tag}" | awk '/^Digest:/{print $2}')
|
||||
printf '%s|%s|%s\n' "$service" "$image_tag" "$index_digest" >>"$digest_file"
|
||||
done <<'IMAGES'
|
||||
${{ inputs.image-matrix }}
|
||||
IMAGES
|
||||
{
|
||||
echo "## V4 fresh image digests"
|
||||
echo
|
||||
echo "revision: ${GITHUB_SHA}"
|
||||
echo
|
||||
echo '```'
|
||||
cat "$digest_file"
|
||||
echo '```'
|
||||
} >>"${GITHUB_STEP_SUMMARY:-/dev/stdout}"
|
||||
cat "$digest_file"
|
||||
|
||||
- name: cleanup per-run cache dir
|
||||
if: always() && inputs.build-command != '' && inputs.cache-mode == 'per-run'
|
||||
run: rm -rf -- "${TOOL_CACHE_DIR:-}"
|
||||
|
||||
Reference in New Issue
Block a user