diff --git a/TODO.md b/TODO.md index 1434757..20c8a60 100644 --- a/TODO.md +++ b/TODO.md @@ -21,6 +21,13 @@ fmt-check, and commit. # Completed Steps +- 2026-10-05: `script/cibuild`, `script/docker`, `script/lint` and `script/test` + now assign the image tag from `script/projectname` on its own line before the + `docker build` (issue 101), so `set -e` stops the script where + `script/projectname` fails instead of running `docker build` with a broken + tag. The comment above it in each script says why, and the snippets in + `REPO_POLICIES.md` show the same form. Repositories pick this up on their next + re-vendor. - 2026-10-04: Went through the fleet findings recorded on 2026-08-09 (issue 62) and added the two rules `REPO_POLICIES.md` did not yet state: a new or changed check is proven by planting a defect it must catch; and a change to a separate diff --git a/prompts/REPO_POLICIES.md b/prompts/REPO_POLICIES.md index 20382d1..7fa4bf4 100644 --- a/prompts/REPO_POLICIES.md +++ b/prompts/REPO_POLICIES.md @@ -118,8 +118,9 @@ style conventions are in separate documents: and nothing else: ```sh - docker build --no-cache --target lint -t "$(script/projectname)-lint" . - docker build --no-cache --target test -t "$(script/projectname)-test" . + tag="$(script/projectname)" + docker build --no-cache --target lint -t "$tag-lint" . + docker build --no-cache --target test -t "$tag-test" . ``` **A stage that is not the last one in the file is built only when the final @@ -132,7 +133,9 @@ style conventions are in separate documents: **Every `docker build` in `script/` is tagged**, here and in `script/cibuild` and `script/docker`. An untagged build leaves a dangling image behind on every invocation, on every developer host and every CI - runner; a tagged one replaces the previous image. + runner; a tagged one replaces the previous image. Each script assigns the + tag on its own line before the build, so `set -e` stops it where + `script/projectname` fails. Inside a phase the tool is invoked directly — `golangci-lint`, `go test`, `eslint`, `prettier` — never through `make lint` or `script/test`, which are @@ -434,13 +437,15 @@ style conventions are in separate documents: byte-identically across repos: ```sh - # Own line: a failing command substitution inside an argument does not - # trip `set -e`, so the inline form degrades to an empty constant. + # The version and the tag each get their own line: a failing command + # substitution inside an argument does not trip `set -e`, so the inline + # form degrades to an empty constant. version="$(git describe --tags --always --dirty 2>/dev/null || true)" [ -n "$version" ] || version="unknown" + tag="$(script/projectname)" docker build --no-cache \ --build-arg VERSION="$version" \ - -t "$(script/projectname)" . + -t "$tag" . ``` `--always` makes an untagged repo yield an abbreviated commit hash rather diff --git a/script/cibuild b/script/cibuild index d8d3200..f00646a 100755 --- a/script/cibuild +++ b/script/cibuild @@ -14,15 +14,17 @@ main() { cd "$ROOT" "$SCRIPT_DIR/bootstrap" "$SCRIPT_DIR/check" - # Own line: a failing command substitution inside an argument does - # not trip `set -e`, so the inline form degrades silently to an - # empty constant. The VERSION build argument takes precedence over - # the version a build stage derives from the .git in the context. + # The version and the tag each get their own line: a failing + # command substitution inside an argument does not trip `set -e`, + # so the inline form degrades silently to an empty constant. The + # VERSION build argument takes precedence over the version a build + # stage derives from the .git in the context. version="$(git describe --tags --always --dirty 2>/dev/null || true)" [ -n "$version" ] || version="unknown" + tag="$("$SCRIPT_DIR/projectname")" docker build --no-cache \ --build-arg VERSION="$version" \ - -t "$("$SCRIPT_DIR/projectname")" . + -t "$tag" . } main "$@" diff --git a/script/docker b/script/docker index 07b626c..5b7dda8 100755 --- a/script/docker +++ b/script/docker @@ -10,15 +10,17 @@ ROOT="$(cd "$SCRIPT_DIR/.." && pwd -P)" main() { cd "$ROOT" - # Own line: a failing command substitution inside an argument does - # not trip `set -e`, so the inline form degrades silently to an - # empty constant. The VERSION build argument takes precedence over - # the version a build stage derives from the .git in the context. + # The version and the tag each get their own line: a failing + # command substitution inside an argument does not trip `set -e`, + # so the inline form degrades silently to an empty constant. The + # VERSION build argument takes precedence over the version a build + # stage derives from the .git in the context. version="$(git describe --tags --always --dirty 2>/dev/null || true)" [ -n "$version" ] || version="unknown" + tag="$("$SCRIPT_DIR/projectname")" docker build --no-cache \ --build-arg VERSION="$version" \ - -t "$("$SCRIPT_DIR/projectname")" . + -t "$tag" . } main "$@" diff --git a/script/lint b/script/lint index 2d8b075..634d4a2 100755 --- a/script/lint +++ b/script/lint @@ -15,9 +15,13 @@ ROOT="$(cd "$SCRIPT_DIR/.." && pwd -P)" main() { cd "$ROOT" + # The tag gets its own line: a failing command substitution inside + # an argument does not trip `set -e`, so the inline form degrades + # silently to an empty constant. + tag="$("$SCRIPT_DIR/projectname")" docker build --no-cache \ --target lint \ - -t "$("$SCRIPT_DIR/projectname")-lint" . + -t "$tag-lint" . } main "$@" diff --git a/script/test b/script/test index cd239f2..38fa1b3 100755 --- a/script/test +++ b/script/test @@ -11,9 +11,13 @@ ROOT="$(cd "$SCRIPT_DIR/.." && pwd -P)" main() { cd "$ROOT" + # The tag gets its own line: a failing command substitution inside + # an argument does not trip `set -e`, so the inline form degrades + # silently to an empty constant. + tag="$("$SCRIPT_DIR/projectname")" docker build --no-cache \ --target test \ - -t "$("$SCRIPT_DIR/projectname")-test" . + -t "$tag-test" . } main "$@"