mirror of
https://github.com/block/buzz.git
synced 2026-10-30 14:01:37 +00:00
Merge remote-tracking branch 'origin/main' into codex/demo-gateway-alignment
* origin/main: (33 commits) feat(desktop): restore message quick reactions (#6892) Use paired tags for standing & per-turn context (#6701) fix(cli): preserve signatures in event reads (#6884) refactor(db): finish replaceable event store extraction (#6777) Fix Admin feedback filter overflow (#6825) fix(desktop): stop pulsing addressed agents on send (#6873) fix(desktop): prioritize sidebar channel status (#6861) feat(desktop): hyperlink selected composer text on link paste (#6684) chore(release): release Buzz Desktop version 0.5.20 (#6839) feat(desktop): add KLIPY GIF search to composers (#5554) fix(desktop): respect automatic mention preference after send (#6837) fix(release): attribute desktop candidates to the operator (#6831) fix(ci): check out source in docker.yml merge job (#6833) chore(release): release Buzz Desktop version 0.5.19 (#6828) Remove public relay signing key fallback (#6729) docs(nest): make commit attribution policy-neutral (#6707) fix(desktop-messages): preserve inline agent mentions with persistent addressing (#6793) Qualify canonical relay images for staged delivery (#6781) feat(desktop): persist agent addressing across composer messages (#6714) feat: navigate images across message threads (#6705) ... Signed-off-by: Tom Brow <tomb@block.xyz> # Conflicts: # .env.example # crates/buzz-db/src/push.rs # mobile/lib/shared/profile/user_cache_provider.dart
This commit is contained in:
16
.github/workflows/ci.yml
vendored
16
.github/workflows/ci.yml
vendored
@@ -75,6 +75,8 @@ jobs:
|
||||
- '.github/workflows/ci.yml'
|
||||
- name: Release workflow source contract
|
||||
run: scripts/test-release-ref-contract.sh
|
||||
- name: Relay image eligibility contract
|
||||
run: scripts/test-relay-image-eligibility-workflow.sh
|
||||
- name: Desktop release candidate contract
|
||||
run: scripts/test-desktop-release-candidate.sh
|
||||
- name: OSS desktop promotion contract
|
||||
@@ -527,6 +529,7 @@ jobs:
|
||||
REDIS_URL=redis://localhost:6379 \
|
||||
RELAY_URL=ws://localhost:3000 \
|
||||
BUZZ_BIND_ADDR=0.0.0.0:3000 \
|
||||
BUZZ_RELAY_PRIVATE_KEY="$(openssl rand -hex 32)" \
|
||||
BUZZ_REQUIRE_AUTH_TOKEN=false \
|
||||
BUZZ_RECONCILE_CHANNELS=true \
|
||||
BUZZ_RATE_LIMIT_HUMAN_MESSAGES_PER_MIN=100000 \
|
||||
@@ -692,6 +695,18 @@ jobs:
|
||||
env:
|
||||
DATABASE_URL: postgres://buzz:${{ env.BUZZ_TEST_POSTGRES_PASSWORD }}@localhost:5432/buzz
|
||||
TEST_DATABASE_URL: postgres://buzz:${{ env.BUZZ_TEST_POSTGRES_PASSWORD }}@localhost:5432/buzz
|
||||
- name: Database pressure observability PostgreSQL tests
|
||||
# Explicit pool acquisition and advisory-lock metrics require real
|
||||
# Postgres and are ignored by the infrastructure-free unit-test job.
|
||||
run: |
|
||||
filter='package(buzz-db) and test(/observability::tests::(pool_acquire_records_success_timeout_and_error_with_wait_time|advisory_lock_records_success_contention_timeout_and_error)/)'
|
||||
cargo nextest run \
|
||||
--archive-file target/ci/backend-integration-tests.tar.zst \
|
||||
-E "${filter}" \
|
||||
--run-ignored ignored-only
|
||||
env:
|
||||
DATABASE_URL: postgres://buzz:${{ env.BUZZ_TEST_POSTGRES_PASSWORD }}@localhost:5432/buzz
|
||||
TEST_DATABASE_URL: postgres://buzz:${{ env.BUZZ_TEST_POSTGRES_PASSWORD }}@localhost:5432/buzz
|
||||
- name: Start relay
|
||||
run: |
|
||||
chmod +x ./target/ci/buzz-relay
|
||||
@@ -700,6 +715,7 @@ jobs:
|
||||
REDIS_URL=redis://localhost:6379 \
|
||||
RELAY_URL=ws://localhost:3000 \
|
||||
BUZZ_BIND_ADDR=0.0.0.0:3000 \
|
||||
BUZZ_RELAY_PRIVATE_KEY="$(openssl rand -hex 32)" \
|
||||
BUZZ_REQUIRE_AUTH_TOKEN=false \
|
||||
BUZZ_RECONCILE_CHANNELS=true \
|
||||
BUZZ_GIT_PROBE_WRITERS=8 \
|
||||
|
||||
156
.github/workflows/docker.yml
vendored
156
.github/workflows/docker.yml
vendored
@@ -49,6 +49,10 @@ on:
|
||||
- "Dockerfile.push-gateway"
|
||||
- ".dockerignore"
|
||||
- ".github/workflows/docker.yml"
|
||||
- "deploy/charts/buzz/Chart.yaml"
|
||||
- "scripts/create-deployment-eligibility-predicate.jq"
|
||||
- "scripts/select-qualified-ci-run.jq"
|
||||
- "scripts/test-relay-image-eligibility-workflow.sh"
|
||||
- "Cargo.toml"
|
||||
- "Cargo.lock"
|
||||
- "rust-toolchain.toml"
|
||||
@@ -172,6 +176,10 @@ jobs:
|
||||
target: runtime
|
||||
platforms: ${{ matrix.platform }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
build-args: |
|
||||
BUZZ_SOURCE_SHA=${{ github.sha }}
|
||||
BUZZ_BUILD_ID=github-actions:${{ github.run_id }}:${{ github.run_attempt }}
|
||||
BUZZ_BUILD_URL=https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}/attempts/${{ github.run_attempt }}
|
||||
# Push by digest, not by tag — the merge job assembles the tags
|
||||
# into one multi-arch manifest. This is what makes the native-arm
|
||||
# matrix possible.
|
||||
@@ -190,6 +198,10 @@ jobs:
|
||||
target: runtime-debug
|
||||
platforms: ${{ matrix.platform }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
build-args: |
|
||||
BUZZ_SOURCE_SHA=${{ github.sha }}
|
||||
BUZZ_BUILD_ID=github-actions:${{ github.run_id }}:${{ github.run_attempt }}
|
||||
BUZZ_BUILD_URL=https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}/attempts/${{ github.run_attempt }}
|
||||
outputs: type=image,name=${{ env.IMAGE_NAME }},push-by-digest=true,name-canonical=true,push=${{ github.event_name != 'pull_request' }}
|
||||
cache-from: |
|
||||
type=registry,ref=${{ env.IMAGE_NAME }}-buildcache:${{ matrix.arch }}
|
||||
@@ -222,11 +234,86 @@ jobs:
|
||||
if-no-files-found: error
|
||||
retention-days: 1
|
||||
|
||||
qualify:
|
||||
name: Qualify relay image source
|
||||
if: github.event_name != 'pull_request'
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 70
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
outputs:
|
||||
source_sha: ${{ steps.qualify.outputs.source_sha }}
|
||||
ci_run_id: ${{ steps.qualify.outputs.ci_run_id }}
|
||||
ci_run_attempt: ${{ steps.qualify.outputs.ci_run_attempt }}
|
||||
ci_run_url: ${{ steps.qualify.outputs.ci_run_url }}
|
||||
chart_version: ${{ steps.qualify.outputs.chart_version }}
|
||||
steps:
|
||||
- name: Checkout source
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Require successful same-SHA CI run
|
||||
id: qualify
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
SOURCE_SHA: ${{ github.sha }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
if [[ ! "$SOURCE_SHA" =~ ^[0-9a-f]{40}$ ]]; then
|
||||
echo "::error::Invalid source SHA: $SOURCE_SHA"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
deadline=$((SECONDS + 3900))
|
||||
while (( SECONDS < deadline )); do
|
||||
payload=$(gh api \
|
||||
"/repos/${GITHUB_REPOSITORY}/actions/workflows/ci.yml/runs?head_sha=${SOURCE_SHA}&event=push&per_page=100")
|
||||
successful_run=$(jq -c --arg source_sha "$SOURCE_SHA" \
|
||||
-f "$GITHUB_WORKSPACE/scripts/select-qualified-ci-run.jq" <<<"$payload")
|
||||
|
||||
if [[ -n "$successful_run" ]]; then
|
||||
ci_run_id=$(jq -r '.id' <<<"$successful_run")
|
||||
ci_run_attempt=$(jq -r '.run_attempt' <<<"$successful_run")
|
||||
ci_run_url=$(jq -r '.html_url' <<<"$successful_run")
|
||||
chart_version=$(awk '/^version:/ { print $2; exit }' deploy/charts/buzz/Chart.yaml)
|
||||
if [[ ! "$chart_version" =~ ^[0-9]+\.[0-9]+\.[0-9]+([+-][0-9A-Za-z.-]+)?$ ]]; then
|
||||
echo "::error::Invalid Buzz chart version: $chart_version"
|
||||
exit 1
|
||||
fi
|
||||
{
|
||||
echo "source_sha=$SOURCE_SHA"
|
||||
echo "ci_run_id=$ci_run_id"
|
||||
echo "ci_run_attempt=$ci_run_attempt"
|
||||
echo "ci_run_url=$ci_run_url"
|
||||
echo "chart_version=$chart_version"
|
||||
} >>"$GITHUB_OUTPUT"
|
||||
echo "Qualified source $SOURCE_SHA with CI run $ci_run_id (attempt $ci_run_attempt)."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
matching=$(jq --arg source_sha "$SOURCE_SHA" '[.workflow_runs[] | select(.head_sha == $source_sha) | select(.event == "push") | select(.head_branch == "main" or .head_branch == "release")] | length' <<<"$payload")
|
||||
pending=$(jq --arg source_sha "$SOURCE_SHA" '[.workflow_runs[] | select(.head_sha == $source_sha) | select(.event == "push") | select(.head_branch == "main" or .head_branch == "release") | select(.status != "completed")] | length' <<<"$payload")
|
||||
if (( matching > 0 && pending == 0 )); then
|
||||
echo "::error::No successful CI run exists for source $SOURCE_SHA"
|
||||
jq -r --arg source_sha "$SOURCE_SHA" '.workflow_runs[] | select(.head_sha == $source_sha) | "run=\(.id) attempt=\(.run_attempt) status=\(.status) conclusion=\(.conclusion)"' <<<"$payload"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Waiting for same-SHA CI qualification ($matching matching, $pending pending)..."
|
||||
sleep 30
|
||||
done
|
||||
|
||||
echo "::error::Timed out waiting for successful CI qualification of $SOURCE_SHA"
|
||||
exit 1
|
||||
|
||||
merge:
|
||||
name: Merge ${{ matrix.variant }} multi-arch manifest
|
||||
if: github.event_name != 'pull_request'
|
||||
runs-on: ubuntu-24.04
|
||||
needs: build
|
||||
needs: [build, qualify]
|
||||
timeout-minutes: 15
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -243,6 +330,11 @@ jobs:
|
||||
tag_prefix: debug-
|
||||
|
||||
steps:
|
||||
- name: Checkout source
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Download all per-arch digests
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||
with:
|
||||
@@ -286,6 +378,10 @@ jobs:
|
||||
env:
|
||||
IMAGE_NAME: ${{ env.IMAGE_NAME }}
|
||||
META_TAGS: ${{ steps.meta.outputs.tags }}
|
||||
SOURCE_SHA: ${{ needs.qualify.outputs.source_sha }}
|
||||
CI_RUN_ID: ${{ needs.qualify.outputs.ci_run_id }}
|
||||
CI_RUN_ATTEMPT: ${{ needs.qualify.outputs.ci_run_attempt }}
|
||||
CHART_VERSION: ${{ needs.qualify.outputs.chart_version }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
# Build -t flags from the metadata-action output.
|
||||
@@ -300,7 +396,15 @@ jobs:
|
||||
digests+=("${IMAGE_NAME}@sha256:${digest}")
|
||||
done
|
||||
|
||||
docker buildx imagetools create "${tags[@]}" "${digests[@]}"
|
||||
annotations=(
|
||||
--annotation "index:org.opencontainers.image.revision=${SOURCE_SHA}"
|
||||
--annotation "index:xyz.block.buzz.build.id=github-actions:${GITHUB_RUN_ID}:${GITHUB_RUN_ATTEMPT}"
|
||||
--annotation "index:xyz.block.buzz.qualification.ci-run-id=${CI_RUN_ID}"
|
||||
--annotation "index:xyz.block.buzz.qualification.ci-run-attempt=${CI_RUN_ATTEMPT}"
|
||||
--annotation "index:xyz.block.buzz.qualification.ci-conclusion=success"
|
||||
--annotation "index:xyz.block.buzz.helm-chart.version=${CHART_VERSION}"
|
||||
)
|
||||
docker buildx imagetools create "${tags[@]}" "${annotations[@]}" "${digests[@]}"
|
||||
|
||||
# Capture the merged manifest digest for the attestation step.
|
||||
first_tag=$(echo "$META_TAGS" | head -n1)
|
||||
@@ -317,17 +421,58 @@ jobs:
|
||||
subject-digest: ${{ steps.manifest.outputs.digest }}
|
||||
push-to-registry: true
|
||||
|
||||
- name: Create deployment eligibility predicate
|
||||
if: matrix.variant == 'release'
|
||||
env:
|
||||
SOURCE_SHA: ${{ needs.qualify.outputs.source_sha }}
|
||||
CI_RUN_ID: ${{ needs.qualify.outputs.ci_run_id }}
|
||||
CI_RUN_ATTEMPT: ${{ needs.qualify.outputs.ci_run_attempt }}
|
||||
CI_RUN_URL: ${{ needs.qualify.outputs.ci_run_url }}
|
||||
CHART_VERSION: ${{ needs.qualify.outputs.chart_version }}
|
||||
run: |
|
||||
jq -n \
|
||||
--arg source_repository "$GITHUB_REPOSITORY" \
|
||||
--arg source_ref "$GITHUB_REF" \
|
||||
--arg source_sha "$SOURCE_SHA" \
|
||||
--arg build_workflow ".github/workflows/docker.yml" \
|
||||
--argjson build_run_id "$GITHUB_RUN_ID" \
|
||||
--argjson build_run_attempt "$GITHUB_RUN_ATTEMPT" \
|
||||
--arg build_run_url "https://github.com/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}/attempts/${GITHUB_RUN_ATTEMPT}" \
|
||||
--arg qualification_workflow ".github/workflows/ci.yml" \
|
||||
--argjson qualification_run_id "$CI_RUN_ID" \
|
||||
--argjson qualification_run_attempt "$CI_RUN_ATTEMPT" \
|
||||
--arg qualification_run_url "$CI_RUN_URL" \
|
||||
--arg chart_version "$CHART_VERSION" \
|
||||
-f "$GITHUB_WORKSPACE/scripts/create-deployment-eligibility-predicate.jq" \
|
||||
>/tmp/deployment-eligibility.json
|
||||
|
||||
- name: Attest deployment eligibility
|
||||
if: matrix.variant == 'release'
|
||||
uses: actions/attest@1e69f48acb82d1966a394da916b4c1698aa569d6 # v4.2.2
|
||||
with:
|
||||
subject-name: ${{ env.IMAGE_NAME }}
|
||||
subject-digest: ${{ steps.manifest.outputs.digest }}
|
||||
predicate-type: https://buzz.block.xyz/attestations/deployment-eligibility/v1
|
||||
predicate-path: /tmp/deployment-eligibility.json
|
||||
push-to-registry: true
|
||||
|
||||
- name: Summary
|
||||
env:
|
||||
IMAGE_NAME: ${{ env.IMAGE_NAME }}
|
||||
VARIANT: ${{ matrix.variant }}
|
||||
MERGED_DIGEST: ${{ steps.manifest.outputs.digest }}
|
||||
META_TAGS: ${{ steps.meta.outputs.tags }}
|
||||
SOURCE_SHA: ${{ needs.qualify.outputs.source_sha }}
|
||||
CI_RUN_URL: ${{ needs.qualify.outputs.ci_run_url }}
|
||||
CHART_VERSION: ${{ needs.qualify.outputs.chart_version }}
|
||||
run: |
|
||||
{
|
||||
echo "### Published \`${IMAGE_NAME}\` (${VARIANT})"
|
||||
echo
|
||||
echo "**Digest:** \`${MERGED_DIGEST}\`"
|
||||
echo "**Source:** \`${SOURCE_SHA}\`"
|
||||
echo "**Compatible Buzz chart:** \`${CHART_VERSION}\`"
|
||||
echo "**Qualifying CI:** ${CI_RUN_URL} (success)"
|
||||
echo
|
||||
echo "**Tags:**"
|
||||
echo '```'
|
||||
@@ -338,6 +483,13 @@ jobs:
|
||||
echo '```'
|
||||
echo "gh attestation verify oci://${IMAGE_NAME}@${MERGED_DIGEST} --owner block"
|
||||
echo '```'
|
||||
if [[ "$VARIANT" == "release" ]]; then
|
||||
echo
|
||||
echo "Verify deployment eligibility:"
|
||||
echo '```'
|
||||
echo "gh attestation verify oci://${IMAGE_NAME}@${MERGED_DIGEST} --repo block/buzz --signer-workflow block/buzz/.github/workflows/docker.yml --predicate-type https://buzz.block.xyz/attestations/deployment-eligibility/v1 --source-digest ${SOURCE_SHA}"
|
||||
echo '```'
|
||||
fi
|
||||
} >> "$GITHUB_STEP_SUMMARY"
|
||||
|
||||
push-gateway-build:
|
||||
|
||||
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"
|
||||
Reference in New Issue
Block a user