mirror of
https://github.com/block/buzz.git
synced 2026-10-27 04:30:52 +00:00
Add staging dev relay image workflow (#6709)
## Summary Adds a manual, collaborator-triggered workflow for publishing pre-merge Buzz relay runtime images for bb-block staging. - Resolves a canonical `block/buzz` branch or tag to an immutable commit SHA before checkout. - Builds the relay runtime image for `linux/amd64` and `linux/arm64` and publishes a single OCI index. - Tags each publication uniquely as `dev-sha-<full SHA>-run-<run_id>-<run_attempt>` so no tag is ever reused against the immutable-tag utility ECR pull-through cache (rebuilds of the same SHA aren't byte-identical, given mutable base tags and `apt-get update`). - Uses the staging-only `ghcr.io/block/buzz-staging-dev` namespace, which maps to a distinct utility ECR pull-through path. - Restricts dispatch to `block/buzz` on `refs/heads/main`; job permissions are narrowly scoped to `contents: read` plus `packages: write`. - Emits a deployment summary with the exact BPCI `repository` and unique `tag` values, plus the merged manifest digest. - Keeps the existing production/release image workflow unchanged. The first real workflow run must confirm GHCR package creation/access and utility ECR pull-through import for the new package. --------- Signed-off-by: Brad Seiler <seiler@squareup.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: tornquist <tornquist@squareup.com> Co-authored-by: coder 0 <d97ebdbb198c7237c94f84ea8bb8a73583ea067407eebd0062abbb3962527fb1@buzz.block.builderlab.xyz> Co-authored-by: Duncan <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@buzz.block.builderlab.xyz> Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Co-authored-by: tornquist <tornquist@squareup.com>
This commit is contained in:
276
.github/workflows/staging-dev-relay-image.yml
vendored
Normal file
276
.github/workflows/staging-dev-relay-image.yml
vendored
Normal file
@@ -0,0 +1,276 @@
|
||||
name: Staging dev relay image
|
||||
|
||||
# Publishes pre-merge relay runtime images for bb-block staging only.
|
||||
#
|
||||
# Operators run this workflow from the default branch and provide a target ref in
|
||||
# this repository. GitHub's workflow_dispatch permission model limits triggering
|
||||
# to collaborators who can run repository workflows; no actor allowlist is kept
|
||||
# here. The target ref is resolved to an immutable commit SHA before checkout,
|
||||
# and the published tag is derived from that full SHA.
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
target_ref:
|
||||
description: "Branch, tag, refs/heads/*, or refs/tags/* in block/buzz to publish for bb-block staging"
|
||||
required: true
|
||||
type: string
|
||||
|
||||
permissions: {}
|
||||
|
||||
env:
|
||||
IMAGE_NAME: ghcr.io/block/buzz-staging-dev
|
||||
ECR_REPOSITORY: 929862310821.dkr.ecr.us-west-2.amazonaws.com/ghcr.io/block/buzz-staging-dev
|
||||
|
||||
jobs:
|
||||
resolve:
|
||||
name: Resolve target ref
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 5
|
||||
permissions:
|
||||
contents: read
|
||||
outputs:
|
||||
target_sha: ${{ steps.resolve.outputs.target_sha }}
|
||||
image_tag: ${{ steps.resolve.outputs.image_tag }}
|
||||
steps:
|
||||
- name: Require reviewed workflow from main in canonical repository
|
||||
env:
|
||||
DISPATCH_REF: ${{ github.ref }}
|
||||
REPOSITORY: ${{ github.repository }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
if [ "$REPOSITORY" != "block/buzz" ]; then
|
||||
echo "::error::Staging dev relay image publication is restricted to block/buzz"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$DISPATCH_REF" != "refs/heads/main" ]; then
|
||||
echo "::error::Dispatch this workflow from main, not $DISPATCH_REF"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Resolve target ref in this repository
|
||||
id: resolve
|
||||
env:
|
||||
TARGET_REF_INPUT: ${{ inputs.target_ref }}
|
||||
GITHUB_REPOSITORY: ${{ github.repository }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
target_ref=$(printf '%s' "$TARGET_REF_INPUT" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
|
||||
|
||||
if [ -z "$target_ref" ]; then
|
||||
echo "target_ref must not be empty" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ${#target_ref} -gt 255 ]; then
|
||||
echo "target_ref is too long" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! "$target_ref" =~ ^[A-Za-z0-9._/@-]+$ ]]; then
|
||||
echo "target_ref contains unsupported characters; use a branch, tag, or full refs/heads/* or refs/tags/* name" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
case "$target_ref" in
|
||||
-*|*..*|*.lock|refs/pull/*|pull/*|*/pull/*)
|
||||
echo "target_ref is not an allowed repository branch/tag/ref" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
workdir=$(mktemp -d)
|
||||
trap 'rm -rf "$workdir"' EXIT
|
||||
git -C "$workdir" init --quiet
|
||||
git -C "$workdir" remote add origin "https://github.com/${GITHUB_REPOSITORY}.git"
|
||||
|
||||
fetch_commit() {
|
||||
local ref=$1
|
||||
git -C "$workdir" fetch --no-tags --depth=1 origin "$ref" >/dev/null 2>&1
|
||||
git -C "$workdir" rev-parse --verify "FETCH_HEAD^{commit}"
|
||||
}
|
||||
|
||||
target_sha=""
|
||||
if [[ "$target_ref" == refs/heads/* || "$target_ref" == refs/tags/* ]]; then
|
||||
target_sha=$(fetch_commit "$target_ref") || {
|
||||
echo "target_ref did not resolve in ${GITHUB_REPOSITORY}: $target_ref" >&2
|
||||
exit 1
|
||||
}
|
||||
else
|
||||
if target_sha=$(fetch_commit "refs/heads/${target_ref}"); then
|
||||
:
|
||||
elif target_sha=$(fetch_commit "refs/tags/${target_ref}"); then
|
||||
:
|
||||
else
|
||||
echo "target_ref did not resolve as a branch or tag in ${GITHUB_REPOSITORY}: $target_ref" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
target_sha=$(printf '%s' "$target_sha" | tr '[:upper:]' '[:lower:]')
|
||||
if [[ ! "$target_sha" =~ ^[0-9a-f]{40}$ ]]; then
|
||||
echo "resolved target SHA is invalid: $target_sha" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
image_tag="dev-sha-${target_sha}-run-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}"
|
||||
{
|
||||
echo "target_sha=${target_sha}"
|
||||
echo "image_tag=${image_tag}"
|
||||
} >> "$GITHUB_OUTPUT"
|
||||
|
||||
printf "Resolved \`%s\` to \`%s\`; image tag \`%s\`.\n" "$target_ref" "$target_sha" "$image_tag" >> "$GITHUB_STEP_SUMMARY"
|
||||
|
||||
build:
|
||||
name: Build staging relay runtime (${{ matrix.platform }})
|
||||
runs-on: ${{ matrix.runner }}
|
||||
needs: resolve
|
||||
timeout-minutes: 60
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- platform: linux/amd64
|
||||
runner: ubuntu-24.04
|
||||
arch: amd64
|
||||
- platform: linux/arm64
|
||||
runner: ubuntu-24.04-arm
|
||||
arch: arm64
|
||||
steps:
|
||||
- name: Checkout resolved target
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
ref: ${{ needs.resolve.outputs.target_sha }}
|
||||
fetch-depth: 1
|
||||
persist-credentials: false
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0
|
||||
with:
|
||||
buildkitd-config-inline: |
|
||||
[worker.oci]
|
||||
max-parallelism = 2
|
||||
|
||||
- name: Log in to GHCR
|
||||
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Extract metadata
|
||||
id: meta
|
||||
uses: docker/metadata-action@80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9 # v6.1.0
|
||||
with:
|
||||
images: ${{ env.IMAGE_NAME }}
|
||||
labels: |
|
||||
org.opencontainers.image.title=Buzz staging dev relay
|
||||
org.opencontainers.image.description=Pre-merge Buzz relay runtime image for bb-block staging only
|
||||
org.opencontainers.image.licenses=Apache-2.0
|
||||
org.opencontainers.image.revision=${{ needs.resolve.outputs.target_sha }}
|
||||
|
||||
- name: Build and push runtime image by digest
|
||||
id: build
|
||||
uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7.2.0
|
||||
with:
|
||||
context: .
|
||||
file: ./Dockerfile
|
||||
target: runtime
|
||||
platforms: ${{ matrix.platform }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
outputs: type=image,name=${{ env.IMAGE_NAME }},push-by-digest=true,name-canonical=true,push=true
|
||||
cache-from: |
|
||||
type=registry,ref=${{ env.IMAGE_NAME }}-buildcache:${{ matrix.arch }}
|
||||
cache-to: |
|
||||
type=registry,ref=${{ env.IMAGE_NAME }}-buildcache:${{ matrix.arch }},mode=max,compression=zstd
|
||||
|
||||
- name: Export digest
|
||||
env:
|
||||
DIGEST: ${{ steps.build.outputs.digest }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
mkdir -p /tmp/digests-release
|
||||
touch "/tmp/digests-release/${DIGEST#sha256:}"
|
||||
|
||||
- name: Upload digest
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
with:
|
||||
name: staging-dev-relay-digests-${{ matrix.arch }}
|
||||
path: /tmp/digests-release/*
|
||||
if-no-files-found: error
|
||||
retention-days: 1
|
||||
|
||||
merge:
|
||||
name: Publish staging relay runtime manifest
|
||||
runs-on: ubuntu-24.04
|
||||
needs:
|
||||
- resolve
|
||||
- build
|
||||
timeout-minutes: 15
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
steps:
|
||||
- name: Download per-arch digests
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||
with:
|
||||
path: /tmp/digests
|
||||
pattern: staging-dev-relay-digests-*
|
||||
merge-multiple: true
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0
|
||||
|
||||
- name: Log in to GHCR
|
||||
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Create and push manifest list
|
||||
id: manifest
|
||||
working-directory: /tmp/digests
|
||||
env:
|
||||
IMAGE_NAME: ${{ env.IMAGE_NAME }}
|
||||
IMAGE_TAG: ${{ needs.resolve.outputs.image_tag }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
digests=()
|
||||
for digest in *; do
|
||||
digests+=("${IMAGE_NAME}@sha256:${digest}")
|
||||
done
|
||||
|
||||
docker buildx imagetools create -t "${IMAGE_NAME}:${IMAGE_TAG}" "${digests[@]}"
|
||||
merged_digest=$(docker buildx imagetools inspect "${IMAGE_NAME}:${IMAGE_TAG}" \
|
||||
--format '{{json .Manifest}}' | jq -r '.digest')
|
||||
echo "digest=${merged_digest}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Deployment summary
|
||||
env:
|
||||
IMAGE_NAME: ${{ env.IMAGE_NAME }}
|
||||
ECR_REPOSITORY: ${{ env.ECR_REPOSITORY }}
|
||||
IMAGE_TAG: ${{ needs.resolve.outputs.image_tag }}
|
||||
TARGET_SHA: ${{ needs.resolve.outputs.target_sha }}
|
||||
MERGED_DIGEST: ${{ steps.manifest.outputs.digest }}
|
||||
run: |
|
||||
{
|
||||
echo "### Published bb-block staging dev relay image"
|
||||
echo
|
||||
echo "**Source commit:** \`${TARGET_SHA}\`"
|
||||
echo "**GHCR image:** \`${IMAGE_NAME}:${IMAGE_TAG}\`"
|
||||
echo "**Manifest digest:** \`${MERGED_DIGEST}\`"
|
||||
echo
|
||||
echo "Set bb-block staging BPCI values to:"
|
||||
echo '```yaml'
|
||||
echo "buzz:"
|
||||
echo " image:"
|
||||
echo " repository: ${ECR_REPOSITORY}"
|
||||
echo " tag: ${IMAGE_TAG}"
|
||||
echo '```'
|
||||
} >> "$GITHUB_STEP_SUMMARY"
|
||||
26
docs/staging-dev-relay-images.md
Normal file
26
docs/staging-dev-relay-images.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# Staging dev relay images
|
||||
|
||||
Use the **Staging dev relay image** GitHub Actions workflow to publish a pre-merge Buzz relay runtime image for bb-block staging.
|
||||
|
||||
1. Run `.github/workflows/staging-dev-relay-image.yml` from the default branch.
|
||||
2. Enter a `target_ref` from `block/buzz` (`my-branch`, `refs/heads/my-branch`, `my-tag`, or `refs/tags/my-tag`).
|
||||
3. Wait for the workflow summary. It resolves that ref to a commit and publishes only the relay `runtime` image to:
|
||||
|
||||
```text
|
||||
ghcr.io/block/buzz-staging-dev:dev-sha-<40-character-commit-sha>-run-<run-id>-<run-attempt>
|
||||
```
|
||||
|
||||
4. In `squareup/builderbot-platform-core-infrastructure`, set bb-block staging values to the distinct pull-through ECR path and immutable tag from the workflow summary:
|
||||
|
||||
```yaml
|
||||
buzz:
|
||||
image:
|
||||
repository: 929862310821.dkr.ecr.us-west-2.amazonaws.com/ghcr.io/block/buzz-staging-dev
|
||||
tag: dev-sha-<40-character-commit-sha>-run-<run-id>-<run-attempt>
|
||||
```
|
||||
|
||||
This path is intentionally separate from the production/main relay image path (`ghcr.io/block/buzz`) so a staging-only branch deployment is obvious in BPCI.
|
||||
|
||||
These images are for manual, pre-merge staging evaluation only. They are not release-qualified and must not be promoted to production or used by the canonical Kargo promotion path.
|
||||
|
||||
While bb-block remains a shared staging environment, do not deploy a target ref through this runtime-only path if it changes `migrations/` or requires changes to `deploy/charts/buzz/`. Backwards-compatible migrations can still leave the shared database ahead of the restored `main` image. Use an isolated environment or deployment-time enforcement for those changes.
|
||||
Reference in New Issue
Block a user