diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 233943268c..c53e3c95ae 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -17,7 +17,8 @@ name: Docker image # # Triggers: # - push to main → :main + :sha-<7> + :main--<7> -# + the matching :debug-* tags +# + the matching :debug-* tags, only when the +# push touches the image build context (below) # - push tags relay-v*.*.* → :{version} + :{major}.{minor} + :{major} # + matching :debug-* tags # (+ :latest/:debug-latest for stable releases) @@ -49,10 +50,26 @@ name: Docker image # semver, so relay-v0.3.0-rc.1 publishes :0.3.0-rc.1 without moving :latest, # and main pushes (no semver tag) never produce :latest. +# Main pushes skip paths that .dockerignore keeps out of the build context: +# they cannot change either image, and every published :main--<7> +# tag rolls staging through Kargo. .github/ is ignored by Docker too, but this +# workflow defines the build, so it is re-included. GitHub does not evaluate +# path filters for tag pushes, so relay-v* tags always publish. +# scripts/test-relay-image-eligibility-workflow.sh checks every exclusion +# against .dockerignore. on: push: branches: [main] tags: ["relay-v[0-9]*"] + paths: + - "**" + - "!desktop/**" + - "!mobile/**" + - "!docs/**" + - "!bin/**" + - "!sidecars/**" + - "!.github/**" + - ".github/workflows/docker.yml" pull_request: paths: - "Dockerfile" diff --git a/RELEASING.md b/RELEASING.md index e50ead2c08..bf3262d5d8 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -104,8 +104,11 @@ prior release's recorded squash commit; tag ancestry is deliberately irrelevant. `debug-0.3.0` and `debug-latest`) for native profiling. The ordinary tags remain stripped and are the default for deployments that do not need it. -Every push to `main` continues to publish the rolling relay `:main` and -`:sha-<7>` tags, plus matching `:debug-main` and `:debug-sha-<7>` variants. +Every push to `main` that changes the image build context continues to +publish the rolling relay `:main` and `:sha-<7>` tags, plus matching +`:debug-main` and `:debug-sha-<7>` variants. Pushes that only touch paths +`.dockerignore` excludes (such as `desktop/`, `mobile/` and `docs/`) publish +nothing. ### Mobile diff --git a/scripts/test-relay-image-eligibility-workflow.sh b/scripts/test-relay-image-eligibility-workflow.sh index f6adc4c6f3..6a2f22e898 100755 --- a/scripts/test-relay-image-eligibility-workflow.sh +++ b/scripts/test-relay-image-eligibility-workflow.sh @@ -30,6 +30,32 @@ require_literal '- "scripts/create-deployment-eligibility-predicate.jq"' require_literal '- "scripts/select-qualified-ci-run.jq"' require_literal '- "scripts/test-relay-image-eligibility-workflow.sh"' +# Main pushes may skip only paths Docker never sees. The push filter must be, in +# order: "**", then directory exclusions that .dockerignore also excludes, then +# the re-included image workflow. Any other entry, or another order, could stop +# a change that alters the published image from publishing it. +push_trigger=$(awk '/^ push:$/{f=1;next} f&&/^ [a-z_]+:/{exit} f' "$workflow") +push_paths=() +while IFS= read -r entry; do + push_paths+=("$entry") +done < <(awk '/^ paths:$/{f=1;next} f&&/^[[:space:]]*(#.*)?$/{next} f&&/^ - /{print;next} f{exit}' <<<"$push_trigger") +fail_push_paths() { + echo "main push path filter: $1" >&2 + exit 1 +} +(( ${#push_paths[@]} >= 3 )) || fail_push_paths "expected \"**\", directory exclusions, then the workflow" +[[ "${push_paths[0]}" == ' - "**"' ]] || fail_push_paths 'first entry must be "**"' +last=$(( ${#push_paths[@]} - 1 )) +[[ "${push_paths[$last]}" == ' - ".github/workflows/docker.yml"' ]] || + fail_push_paths "last entry must re-include .github/workflows/docker.yml" +for entry in "${push_paths[@]:1:last-1}"; do + [[ "$entry" =~ ^\ {6}-\ \"!([A-Za-z0-9._-]+)/\*\*\"$ ]] || + fail_push_paths "only \"!/**\" exclusions may sit between \"**\" and the workflow, found: ${entry# - }" + excluded=${BASH_REMATCH[1]} + grep -Fxq "$excluded/" "$repo_root/.dockerignore" || + fail_push_paths "skips $excluded/, which .dockerignore keeps in the image build context" +done + if grep -Fq "buzz-staging-dev" "$workflow"; then echo "canonical relay image workflow references the preview-only image package" >&2 exit 1