check / check (pull_request) Waiting to run
A plain `docker build .` stamped `dev`: `.dockerignore` left out `.git` and the Dockerfile defaulted VERSION to `dev`. `.dockerignore` now sends `.git` without `.git/config`. Given no build arguments, the builder stamps `git describe --tags --always` and the commit and date from git, and fails if `.git` is present but yields no version. The empty CHECK_EPOCH refusal is gone so the plain build succeeds. `script/version` now prints `git describe --tags --always --dirty`, so make, the scripts and a plain build agree. `vaultik version` treats the short commit, tag-N-gHASH forms and any version ending in `-dirty` as development builds, so they keep the development-build notice. Model: opus-5-5
79 lines
3.5 KiB
Bash
Executable File
79 lines
3.5 KiB
Bash
Executable File
#!/bin/sh
|
|
# script/cibuild: run the CI build. This is the full gate, and it is two
|
|
# builds, in this order:
|
|
#
|
|
# Dockerfile.lint the linter, as a build step (a clean build IS a
|
|
# clean lint)
|
|
# Dockerfile `make fmt-check` and `make test` in the builder
|
|
# stage, then the product image
|
|
#
|
|
# Either one failing fails this script. Note what follows from the
|
|
# split: script/docker builds only the product image and so no longer
|
|
# lints -- this script and script/check (which runs script/lint) are the
|
|
# things that decide whether the tree is clean.
|
|
#
|
|
# Generic apart from the two Dockerfiles: the Gitea workflow runs this
|
|
# on push.
|
|
set -eu
|
|
|
|
ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
|
|
|
|
main() {
|
|
cd "$ROOT"
|
|
# Both Dockerfiles key their check layers on CHECK_EPOCH, so a fresh
|
|
# value is what forces those layers to re-run: without it an
|
|
# unchanged tree replays them from cache, the checks never execute,
|
|
# and the build still exits 0. Each ARG sits immediately above the
|
|
# check RUNs, so dependency and module layers still cache.
|
|
# Dockerfile.lint also refuses to build at all when CHECK_EPOCH is
|
|
# empty, so a missing value fails its build loudly rather than passing
|
|
# quietly; the product Dockerfile does not, because a plain `docker
|
|
# build .` must succeed.
|
|
#
|
|
# The value must be unique per invocation, not per second. `date +%s`
|
|
# is second-granular, so two concurrent invocations in the same
|
|
# second get identical epochs and the later one can be served from
|
|
# cache -- the original defect in miniature. `%N` alone does not fix
|
|
# it: busybox silently drops %N, exits 0, and hands back second
|
|
# granularity with no warning. `$$` is what makes this correct
|
|
# regardless, since concurrent invocations have different pids.
|
|
#
|
|
# Assign the epoch on its own line rather than inline in the
|
|
# argument. Under `set -eu` a command substitution that fails
|
|
# inside an argument does NOT abort the script: CHECK_EPOCH would
|
|
# become an empty string, an empty string is a constant, and a
|
|
# constant CHECK_EPOCH is exactly the cached-check false green this
|
|
# script exists to prevent -- so the guard would disarm itself and
|
|
# still exit 0. As a bare assignment, `set -e` catches a failing
|
|
# `date` and no build starts.
|
|
#
|
|
# A separate value per build, because they are separate builds: one
|
|
# `date` shared between them would still be fresh, but reusing it
|
|
# invites the two to be collapsed into a single value that is
|
|
# computed somewhere else and passed in.
|
|
epoch="$(date +%s%N)$$"
|
|
# cacheonly for the lint build: its verdict is the exit status and
|
|
# the image is never run, so exporting it is pure cost. See
|
|
# script/lint.
|
|
docker build --output=type=cacheonly \
|
|
--build-arg CHECK_EPOCH="$epoch" -f Dockerfile.lint .
|
|
|
|
# Version, commit and build date are computed here on the host, the
|
|
# same way script/docker does, and passed into the product build,
|
|
# where they take precedence over what the build would derive from
|
|
# the .git in its context. VERSION comes from script/version, as in
|
|
# the Makefile.
|
|
version="$("$ROOT/script/version")"
|
|
commit="$(git rev-parse HEAD 2>/dev/null || echo unknown)"
|
|
commit_date="$(git show -s --format=%cs HEAD 2>/dev/null || echo unknown)"
|
|
|
|
epoch="$(date +%s%N)$$"
|
|
docker build --build-arg CHECK_EPOCH="$epoch" \
|
|
--build-arg VERSION="$version" \
|
|
--build-arg COMMIT="$commit" \
|
|
--build-arg COMMIT_DATE="$commit_date" \
|
|
.
|
|
}
|
|
|
|
main "$@"
|