mirror of
https://github.com/block/buzz.git
synced 2026-11-01 06:51:17 +00:00
## Why Phase 1 of progressive delivery needs an explicit eligibility boundary before deployment automation can safely consume relay artifacts. Today the canonical Docker workflow can publish independently of the same-SHA CI result, the relay does not expose its source/build identity, and the Helm chart only renders mutable tags. The existing `ghcr.io/block/buzz-staging-dev` workflow in #6709 remains a manual pre-merge preview lane. It is deliberately not a canonical promotion input. ## What changed - Compile the full source SHA and GitHub Actions build identity into canonical relay binaries and expose it at `/_status`. - Gate creation of tagged multi-architecture manifests on the latest exact-SHA `CI` push run succeeding on `main` or `release`. - Preserve the signed SLSA provenance and add a signed, release-only deployment-eligibility predicate with source, build run, qualifying CI run, and exact compatible Buzz chart version. - Keep failed or pending builds untagged and without an eligibility predicate; preview-package artifacts are excluded by package and signer contract. - Add optional `image.digest` support to Buzz chart `0.1.8`, retaining the existing tag fallback. - Document verification and the intentional boundary between image/chart compatibility and backwards-compatible database migrations. ## Risk and rollout Canonical tag publication now waits for same-SHA CI and fails closed when the newest matching run fails. Per-architecture blobs may remain untagged after a failed qualification; they are not promotion inputs. Debug manifests are also CI-gated but do not receive the release eligibility predicate. There are no migration or schema-orchestration changes. The companion BuilderBot infrastructure PR will pin a separately verified canonical main digest and expose a read-only running-deployment inspection command. Signed eligibility is available only for artifacts published after this workflow lands. ## Verification - Blox: workflow contract fixtures, including stale-green rejection and predicate structure - Blox: `actionlint` for `ci.yml` and `docker.yml` - Blox: 46 Helm unit tests, chart lint, and production/quickstart render fixtures - Blox: relay status unit test, workspace Rust formatting, and workspace all-target clippy - Live evidence: exact-SHA CI selector chose successful run `32857345153` for source `9d1e4b257657f382d3111ce748f3da8d063b7671` - Existing canonical digest provenance verified with `gh attestation verify` ## References - #6709 — developer-preview precursor; intentionally separate from canonical eligibility - `docs/deployment-identity.md` *Generated with Codex* --------- Signed-off-by: Luke Tornquist <tornquist@squareup.com>
109 lines
4.1 KiB
Bash
Executable File
109 lines
4.1 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
repo_root=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
|
|
workflow="$repo_root/.github/workflows/docker.yml"
|
|
selector="$repo_root/scripts/select-qualified-ci-run.jq"
|
|
predicate_builder="$repo_root/scripts/create-deployment-eligibility-predicate.jq"
|
|
|
|
require_literal() {
|
|
local needle=$1
|
|
grep -Fq -- "$needle" "$workflow" || {
|
|
echo "relay image workflow is missing required delivery contract: $needle" >&2
|
|
exit 1
|
|
}
|
|
}
|
|
|
|
require_literal " qualify:"
|
|
require_literal "actions: read"
|
|
require_literal "actions/workflows/ci.yml/runs"
|
|
require_literal 'select-qualified-ci-run.jq'
|
|
require_literal "needs: [build, qualify]"
|
|
require_literal "https://buzz.block.xyz/attestations/deployment-eligibility/v1"
|
|
require_literal "actions/attest@1e69f48acb82d1966a394da916b4c1698aa569d6"
|
|
require_literal "if: matrix.variant == 'release'"
|
|
require_literal "BUZZ_SOURCE_SHA"
|
|
require_literal "BUZZ_BUILD_ID"
|
|
require_literal "BUZZ_BUILD_URL"
|
|
require_literal '- "deploy/charts/buzz/Chart.yaml"'
|
|
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"'
|
|
|
|
if grep -Fq "buzz-staging-dev" "$workflow"; then
|
|
echo "canonical relay image workflow references the preview-only image package" >&2
|
|
exit 1
|
|
fi
|
|
|
|
select_run() {
|
|
jq -r --arg source_sha aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -f "$selector" | jq -r '.id // empty'
|
|
}
|
|
|
|
selected=$(select_run <<'JSON'
|
|
{"workflow_runs":[
|
|
{"id":100,"run_attempt":1,"head_sha":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","head_branch":"main","event":"push","status":"completed","conclusion":"failure"},
|
|
{"id":101,"run_attempt":1,"head_sha":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","head_branch":"main","event":"push","status":"completed","conclusion":"success"}
|
|
]}
|
|
JSON
|
|
)
|
|
[[ "$selected" == "101" ]] || {
|
|
echo "latest successful same-SHA main run was not selected" >&2
|
|
exit 1
|
|
}
|
|
|
|
selected=$(select_run <<'JSON'
|
|
{"workflow_runs":[
|
|
{"id":100,"run_attempt":1,"head_sha":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","head_branch":"main","event":"push","status":"completed","conclusion":"success"},
|
|
{"id":101,"run_attempt":1,"head_sha":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","head_branch":"main","event":"push","status":"completed","conclusion":"failure"}
|
|
]}
|
|
JSON
|
|
)
|
|
[[ -z "$selected" ]] || {
|
|
echo "stale successful run remained eligible after a newer failure" >&2
|
|
exit 1
|
|
}
|
|
|
|
selected=$(select_run <<'JSON'
|
|
{"workflow_runs":[
|
|
{"id":102,"run_attempt":1,"head_sha":"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb","head_branch":"main","event":"push","status":"completed","conclusion":"success"},
|
|
{"id":103,"run_attempt":1,"head_sha":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","head_branch":"feature","event":"pull_request","status":"completed","conclusion":"success"}
|
|
]}
|
|
JSON
|
|
)
|
|
[[ -z "$selected" ]] || {
|
|
echo "wrong-SHA or pull-request CI run was accepted" >&2
|
|
exit 1
|
|
}
|
|
|
|
predicate=$(jq -n \
|
|
--arg source_repository "block/buzz" \
|
|
--arg source_ref "refs/heads/main" \
|
|
--arg source_sha "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \
|
|
--arg build_workflow ".github/workflows/docker.yml" \
|
|
--argjson build_run_id 200 \
|
|
--argjson build_run_attempt 2 \
|
|
--arg build_run_url "https://github.com/block/buzz/actions/runs/200/attempts/2" \
|
|
--arg qualification_workflow ".github/workflows/ci.yml" \
|
|
--argjson qualification_run_id 201 \
|
|
--argjson qualification_run_attempt 1 \
|
|
--arg qualification_run_url "https://github.com/block/buzz/actions/runs/201" \
|
|
--arg chart_version "0.1.8" \
|
|
-f "$predicate_builder")
|
|
|
|
jq -e '
|
|
.predicate_version == 1 and
|
|
.eligible == true and
|
|
.source.sha == "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" and
|
|
.build.run_id == 200 and
|
|
.qualification.run_id == 201 and
|
|
.qualification.conclusion == "success" and
|
|
.helm_chart == {"name":"buzz","compatible_version":"0.1.8"} and
|
|
(has("schema") | not) and
|
|
(.helm_chart | has("schema_compatibility") | not)
|
|
' <<<"$predicate" >/dev/null || {
|
|
echo "deployment eligibility predicate has an invalid contract" >&2
|
|
exit 1
|
|
}
|
|
|
|
echo "relay image eligibility workflow contract passed"
|