mirror of
https://github.com/block/buzz.git
synced 2026-11-12 04:12:21 +00:00
feat(auth): integrate reviewed authorization foundation
Cumulative PR layer #1476. Integrates the reviewed authorization foundation, provider-neutral verification backend, loopback fixture repair, public dependency-source normalization, and the advisory-free Mesh revision. Neighbor disclosure: bounded audit capacity remains in #3564; lifecycle and canonical admission remain in #4772; protected and status consumers remain in the later cumulative layers. Signed-off-by: Cea Stapleton Cordasco <261786559+cea@users.noreply.github.com>
This commit is contained in:
@@ -4,7 +4,7 @@ name: Auto-tag on Release PR Merge
|
||||
# prefix; the main chart lane also auto-detects a Chart.yaml version bump so
|
||||
# a chart feature PR can publish its own new version when merged:
|
||||
#
|
||||
# version-bump/<v> → tag v<v> → release.yml (desktop app)
|
||||
# version-bump/<v> → tag desktop-v<v> → release.yml (desktop app)
|
||||
# relay-release/<v> → tag relay-v<v> → docker.yml (relay image)
|
||||
# chart-release/<v> → tag chart-v<v> → helm-chart.yml (main helm chart)
|
||||
# push-chart-release/<v> → tag push-chart-v<v> → push-gateway-helm-chart.yml
|
||||
@@ -35,12 +35,17 @@ permissions:
|
||||
|
||||
jobs:
|
||||
auto-tag:
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: read
|
||||
checks: read
|
||||
statuses: read
|
||||
if: >
|
||||
github.event.pull_request.merged == true &&
|
||||
github.event.pull_request.head.repo.full_name == github.repository
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.merge_commit_sha }}
|
||||
fetch-depth: 0
|
||||
@@ -57,7 +62,7 @@ jobs:
|
||||
case "$BRANCH" in
|
||||
version-bump/*)
|
||||
VERSION="${BRANCH#version-bump/}"
|
||||
TAG_PREFIX="v" ;;
|
||||
TAG_PREFIX="desktop-v" ;;
|
||||
relay-release/*)
|
||||
VERSION="${BRANCH#relay-release/}"
|
||||
TAG_PREFIX="relay-v" ;;
|
||||
@@ -85,9 +90,34 @@ jobs:
|
||||
{
|
||||
echo "enabled=true"
|
||||
echo "tag=${TAG_PREFIX}${VERSION}"
|
||||
if [[ "$TAG_PREFIX" == desktop-v ]]; then
|
||||
echo "target_sha=${{ github.event.pull_request.head.sha }}"
|
||||
echo "desktop=true"
|
||||
else
|
||||
echo "target_sha=$GITHUB_SHA"
|
||||
echo "desktop=false"
|
||||
fi
|
||||
} >> "$GITHUB_OUTPUT"
|
||||
echo "Tagging ${TAG_PREFIX}${VERSION}"
|
||||
|
||||
|
||||
- name: Verify immutable reviewed desktop candidate
|
||||
if: steps.release.outputs.desktop == 'true'
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
VERSION: ${{ steps.release.outputs.tag }}
|
||||
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||
PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }}
|
||||
PR_HEAD_REF: ${{ github.event.pull_request.head.ref }}
|
||||
PR_BASE_REF: ${{ github.event.pull_request.base.ref }}
|
||||
PR_HEAD_REPO: ${{ github.event.pull_request.head.repo.full_name }}
|
||||
MERGE_SHA: ${{ github.event.pull_request.merge_commit_sha }}
|
||||
MERGED_AT: ${{ github.event.pull_request.merged_at }}
|
||||
run: |
|
||||
VERSION="${VERSION#desktop-v}"
|
||||
export VERSION
|
||||
scripts/verify-desktop-release-merge.sh
|
||||
|
||||
- name: Create release tagger token
|
||||
if: steps.release.outputs.enabled == 'true'
|
||||
id: release-tagger
|
||||
@@ -102,21 +132,32 @@ jobs:
|
||||
env:
|
||||
GH_TOKEN: ${{ steps.release-tagger.outputs.token }}
|
||||
TAG: ${{ steps.release.outputs.tag }}
|
||||
TARGET_SHA: ${{ steps.release.outputs.target_sha }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
# Check gh's exit status, not its output. A missing ref returns a 404
|
||||
# JSON body on stdout, which must not be mistaken for an existing tag.
|
||||
if gh api "repos/$GITHUB_REPOSITORY/git/ref/tags/$TAG" --silent 2>/dev/null; then
|
||||
EXISTING_SHA="$(gh api "repos/$GITHUB_REPOSITORY/commits/$TAG" --jq .sha)"
|
||||
if [ "$EXISTING_SHA" = "$GITHUB_SHA" ]; then
|
||||
echo "Tag $TAG already exists at $GITHUB_SHA — skipping tag creation"
|
||||
if [ "$EXISTING_SHA" = "$TARGET_SHA" ]; then
|
||||
echo "Tag $TAG already exists at $TARGET_SHA — skipping tag creation"
|
||||
exit 0
|
||||
else
|
||||
echo "::error::Tag $TAG already exists at $EXISTING_SHA (expected $GITHUB_SHA)"
|
||||
echo "::error::Tag $TAG already exists at $EXISTING_SHA (expected $TARGET_SHA)"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
gh api --method POST "repos/$GITHUB_REPOSITORY/git/refs" \
|
||||
if ! gh api --method POST "repos/$GITHUB_REPOSITORY/git/refs" \
|
||||
-f ref="refs/tags/$TAG" \
|
||||
-f sha="$GITHUB_SHA" \
|
||||
--silent
|
||||
-f sha="$TARGET_SHA" \
|
||||
--silent; then
|
||||
# Ref creation is atomic. A concurrent retry may have won the race;
|
||||
# accept that only when it created the exact immutable ref.
|
||||
EXISTING_SHA="$(gh api "repos/$GITHUB_REPOSITORY/commits/$TAG" --jq .sha)"
|
||||
if [ "$EXISTING_SHA" = "$TARGET_SHA" ]; then
|
||||
echo "Tag $TAG was concurrently created at $TARGET_SHA"
|
||||
exit 0
|
||||
fi
|
||||
echo "::error::Tag creation failed and $TAG resolves to $EXISTING_SHA (expected $TARGET_SHA)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
2
.github/workflows/benchmark-harbor.yml
vendored
2
.github/workflows/benchmark-harbor.yml
vendored
@@ -20,7 +20,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
|
||||
with:
|
||||
python-version: "3.12"
|
||||
|
||||
116
.github/workflows/ci.yml
vendored
116
.github/workflows/ci.yml
vendored
@@ -28,7 +28,7 @@ jobs:
|
||||
web: ${{ steps.filter.outputs.web }}
|
||||
mobile: ${{ steps.filter.outputs.mobile }}
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
fetch-depth: 2
|
||||
- uses: dorny/paths-filter@7b450fff21473bca461d4b92ce414b9d0420d706 # v4.0.2
|
||||
@@ -48,29 +48,44 @@ jobs:
|
||||
- 'scripts/run-tests.sh'
|
||||
- 'justfile'
|
||||
desktop:
|
||||
- 'scripts/check-file-sizes-core.mjs'
|
||||
- 'scripts/check-file-sizes-core.test.mjs'
|
||||
- 'desktop/**'
|
||||
- '!desktop/src-tauri/**'
|
||||
- 'pnpm-lock.yaml'
|
||||
desktop-rust:
|
||||
- 'desktop/src-tauri/**'
|
||||
web:
|
||||
- 'scripts/check-file-sizes-core.mjs'
|
||||
- 'scripts/check-file-sizes-core.test.mjs'
|
||||
- 'web/**'
|
||||
- 'pnpm-lock.yaml'
|
||||
mobile:
|
||||
- 'scripts/check-file-sizes-core.mjs'
|
||||
- 'scripts/check-file-sizes-core.test.mjs'
|
||||
- 'mobile/**'
|
||||
- 'scripts/mobile-release.sh'
|
||||
- 'scripts/mobile-worktree-overrides.sh'
|
||||
- 'scripts/mobile-worktree-clean.sh'
|
||||
- 'scripts/publish-mobile-release-candidate.sh'
|
||||
- 'scripts/release-rulesets.sh'
|
||||
- 'scripts/test-mobile-release-contract.sh'
|
||||
- 'scripts/test-mobile-release-candidate-publisher.sh'
|
||||
- 'scripts/test-mobile-worktree-overrides.sh'
|
||||
- '.github/workflows/mobile-release-candidate.yml'
|
||||
- '.github/workflows/ci.yml'
|
||||
- name: Release workflow source contract
|
||||
run: scripts/test-release-ref-contract.sh
|
||||
- name: Desktop release candidate contract
|
||||
run: scripts/test-desktop-release-candidate.sh
|
||||
- name: Mobile release contract
|
||||
run: |
|
||||
scripts/test-mobile-release-contract.sh
|
||||
scripts/test-mobile-release-candidate-publisher.sh
|
||||
- name: Mobile worktree identity contract
|
||||
run: scripts/test-mobile-worktree-overrides.sh
|
||||
- name: File size ratchet unit tests
|
||||
run: node --test scripts/check-file-sizes-core.test.mjs
|
||||
|
||||
rust-lint:
|
||||
name: Rust Lint
|
||||
@@ -81,7 +96,7 @@ jobs:
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
- uses: cashapp/activate-hermit@cea9af7913204a965fd488637a8d1811bba2e616 # v1
|
||||
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
|
||||
with:
|
||||
@@ -102,7 +117,7 @@ jobs:
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
- uses: cashapp/activate-hermit@cea9af7913204a965fd488637a8d1811bba2e616 # v1
|
||||
- uses: rui314/setup-mold@9c9c13bf4c3f1adef0cc596abc155580bcb04444 # v1
|
||||
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
|
||||
@@ -124,7 +139,9 @@ jobs:
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
fetch-depth: 2
|
||||
- uses: cashapp/activate-hermit@cea9af7913204a965fd488637a8d1811bba2e616 # v1
|
||||
- uses: rui314/setup-mold@9c9c13bf4c3f1adef0cc596abc155580bcb04444 # v1
|
||||
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
|
||||
@@ -208,7 +225,7 @@ jobs:
|
||||
desktop-smoke-e2e:
|
||||
name: Desktop Smoke E2E (${{ matrix.shard }})
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 20
|
||||
timeout-minutes: 30
|
||||
needs: [changes]
|
||||
if: github.event_name == 'push' || needs.changes.outputs.desktop == 'true' || needs.changes.outputs.desktop-rust == 'true' || needs.changes.outputs.rust == 'true'
|
||||
strategy:
|
||||
@@ -218,7 +235,7 @@ jobs:
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
- uses: cashapp/activate-hermit@cea9af7913204a965fd488637a8d1811bba2e616 # v1
|
||||
- name: Get pnpm store directory
|
||||
id: pnpm-cache
|
||||
@@ -301,7 +318,7 @@ jobs:
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
- uses: cashapp/activate-hermit@cea9af7913204a965fd488637a8d1811bba2e616 # v1
|
||||
# Reuse the relay binaries and backend test archive when none of their
|
||||
# inputs changed (desktop-only PRs hit this every time). The key covers
|
||||
@@ -335,6 +352,7 @@ jobs:
|
||||
cargo build --profile ci -p buzz-relay -p git-credential-nostr
|
||||
cargo nextest archive \
|
||||
--cargo-profile ci \
|
||||
-p buzz-db \
|
||||
-p buzz-relay \
|
||||
-p buzz-test-client \
|
||||
--lib \
|
||||
@@ -373,7 +391,7 @@ jobs:
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
- uses: cashapp/activate-hermit@cea9af7913204a965fd488637a8d1811bba2e616 # v1
|
||||
- name: Start integration services
|
||||
run: |
|
||||
@@ -562,7 +580,7 @@ jobs:
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
- uses: cashapp/activate-hermit@cea9af7913204a965fd488637a8d1811bba2e616 # v1
|
||||
- name: Install cargo-nextest
|
||||
uses: taiki-e/install-action@0fd46367812ee04360509b4169d9f659d6892bb2 # v2.79.15
|
||||
@@ -666,11 +684,36 @@ jobs:
|
||||
done
|
||||
cat /tmp/buzz-relay.log
|
||||
exit 1
|
||||
- name: Invite claim security tests
|
||||
- name: Invite security tests
|
||||
run: |
|
||||
cargo nextest run \
|
||||
--archive-file target/ci/backend-integration-tests.tar.zst \
|
||||
-E 'package(buzz-relay) and test(claim_)' \
|
||||
-E '(package(buzz-db) and test(/relay_invite::tests/)) or (package(buzz-relay) and test(/api::invites::tests/))' \
|
||||
--run-ignored ignored-only
|
||||
env:
|
||||
DATABASE_URL: postgres://buzz:${{ env.BUZZ_TEST_POSTGRES_PASSWORD }}@localhost:5432/buzz
|
||||
- name: Relay-verified identity lifecycle tests
|
||||
run: |
|
||||
docker exec -e PGPASSWORD="${BUZZ_TEST_POSTGRES_PASSWORD}" buzz-postgres \
|
||||
psql -U buzz -d postgres -v ON_ERROR_STOP=1 \
|
||||
-c "CREATE DATABASE buzz_identity_tests"
|
||||
cargo nextest run \
|
||||
--archive-file target/ci/backend-integration-tests.tar.zst \
|
||||
-E 'package(buzz-db) and test(/migration::tests::nip_fi_(authorization_tests|direct_final_tests)::/)' \
|
||||
--no-tests=fail \
|
||||
--test-threads 1 \
|
||||
--run-ignored ignored-only
|
||||
env:
|
||||
DATABASE_URL: postgres://buzz:${{ env.BUZZ_TEST_POSTGRES_PASSWORD }}@localhost:5432/buzz_identity_tests
|
||||
- name: Workspace profile (kind:9033) gate tests
|
||||
# Call-site integration for the 9033 authorization gate: open relay
|
||||
# rosterless/steward transitions and the closed-relay admin/owner rule,
|
||||
# against real Postgres. #[ignore]d in the default suite, selected
|
||||
# explicitly here — see handlers::relay_admin::tests.
|
||||
run: |
|
||||
cargo nextest run \
|
||||
--archive-file target/ci/backend-integration-tests.tar.zst \
|
||||
-E 'package(buzz-relay) and test(/handlers::relay_admin::tests/)' \
|
||||
--run-ignored ignored-only
|
||||
env:
|
||||
DATABASE_URL: postgres://buzz:${{ env.BUZZ_TEST_POSTGRES_PASSWORD }}@localhost:5432/buzz
|
||||
@@ -686,6 +729,17 @@ jobs:
|
||||
--run-ignored ignored-only
|
||||
env:
|
||||
RELAY_URL: ws://localhost:3000
|
||||
- name: NIP-MP coordinate deletion guard
|
||||
# Verifies the never-delete-newer invariant of soft_delete_by_coordinate:
|
||||
# a stale tombstone (created_at earlier than the live head) spares that
|
||||
# head, and an equal-timestamp tombstone deletes it.
|
||||
run: |
|
||||
cargo nextest run \
|
||||
--archive-file target/ci/backend-integration-tests.tar.zst \
|
||||
-E 'package(buzz-db) and test(coordinate_delete_spares_head_newer_than_the_deletion)' \
|
||||
--run-ignored ignored-only
|
||||
env:
|
||||
DATABASE_URL: postgres://buzz:${{ env.BUZZ_TEST_POSTGRES_PASSWORD }}@localhost:5432/buzz
|
||||
- name: Upload relay log
|
||||
if: failure()
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
|
||||
@@ -703,7 +757,7 @@ jobs:
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
- uses: cashapp/activate-hermit@cea9af7913204a965fd488637a8d1811bba2e616 # v1
|
||||
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
|
||||
with:
|
||||
@@ -721,12 +775,25 @@ jobs:
|
||||
./scripts/start-relay-for-tests.sh --no-build
|
||||
- name: Relay E2E tests
|
||||
run: |
|
||||
cargo test -p buzz-test-client --test e2e_persona --test e2e_nostr_interop -- --ignored --nocapture
|
||||
cargo test -p buzz-test-client --test e2e_persona --test e2e_team_catalog --test e2e_nostr_interop --test e2e_project -- --ignored --nocapture
|
||||
cargo test -p buzz-test-client --test e2e_relay invite -- --ignored --nocapture
|
||||
cargo test -p buzz-test-client --test e2e_relay nip43_membership_snapshots_are_rejected -- --ignored --nocapture
|
||||
env:
|
||||
RELAY_URL: ws://localhost:3000
|
||||
GIT_CREDENTIAL_NOSTR_BIN: ${{ github.workspace }}/target/ci/git-credential-nostr
|
||||
- name: Media read-auth e2e
|
||||
# Reads require kind:24242 `t=get` auth, so these binaries are the only
|
||||
# coverage that a real relay rejects bare reads and honours host- and
|
||||
# hash-scoped tokens. They were #[ignore]d and selected by no CI job, so
|
||||
# the lane never ran; select it here, where MinIO and the seeded
|
||||
# 'localhost:3000' community already exist.
|
||||
# --no-fail-fast: without it cargo stops after the first failing binary,
|
||||
# so one broken case hides every later binary's result.
|
||||
run: |
|
||||
cargo test -p buzz-test-client --no-fail-fast --test e2e_media --test e2e_media_extended --test e2e_media_video -- --ignored --nocapture
|
||||
env:
|
||||
RELAY_URL: ws://localhost:3000
|
||||
RELAY_HTTP_URL: http://localhost:3000
|
||||
- name: Upload relay logs
|
||||
if: failure()
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
|
||||
@@ -744,7 +811,9 @@ jobs:
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
fetch-depth: 2
|
||||
- uses: cashapp/activate-hermit@cea9af7913204a965fd488637a8d1811bba2e616 # v1
|
||||
- name: Get pnpm store directory
|
||||
id: pnpm-cache
|
||||
@@ -777,7 +846,9 @@ jobs:
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
fetch-depth: 2
|
||||
- uses: cashapp/activate-hermit@cea9af7913204a965fd488637a8d1811bba2e616 # v1
|
||||
- name: Compute Hermit cache key
|
||||
id: hermit-bin-hash
|
||||
@@ -816,6 +887,8 @@ jobs:
|
||||
with:
|
||||
path: ~/.pub-cache
|
||||
key: pub-${{ runner.os }}-${{ hashFiles('mobile/pubspec.lock') }}
|
||||
- name: File size ratchet
|
||||
run: node mobile/scripts/check-file-sizes.mjs
|
||||
- name: Format check
|
||||
run: cd mobile && dart format --output=none --set-exit-if-changed .
|
||||
- name: Analyze
|
||||
@@ -834,7 +907,7 @@ jobs:
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
- uses: cashapp/activate-hermit@cea9af7913204a965fd488637a8d1811bba2e616 # v1
|
||||
- name: Dependency policy
|
||||
run: cargo-deny check
|
||||
@@ -846,7 +919,7 @@ jobs:
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
- name: Check for dead API token references in client code
|
||||
run: |
|
||||
# Fail if dead API token patterns reappear in desktop, mobile, docs, or config.
|
||||
@@ -875,7 +948,7 @@ jobs:
|
||||
- x86_64-unknown-linux-musl
|
||||
- aarch64-unknown-linux-musl
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
- uses: cashapp/activate-hermit@cea9af7913204a965fd488637a8d1811bba2e616 # v1
|
||||
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
|
||||
with:
|
||||
@@ -912,7 +985,7 @@ jobs:
|
||||
env:
|
||||
TARGET: x86_64-pc-windows-msvc
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
# MSVC needs windows.h (aws-lc-sys et al.), so this runs on a real Windows
|
||||
# runner — hermit, used by the Linux jobs, does not provide MSVC. The
|
||||
# toolchain (1.95.0 + clippy via profile = default) comes from the
|
||||
@@ -976,7 +1049,7 @@ jobs:
|
||||
git log -1 --format=%s | grep -qx smoke
|
||||
echo "Host bash resolved and functional; git commit round-trip passed"
|
||||
- name: Check (Tauri crate)
|
||||
run: cargo check --manifest-path desktop/src-tauri/Cargo.toml --target $env:TARGET
|
||||
run: cargo check --manifest-path desktop/src-tauri/Cargo.toml --workspace --all-targets --target $env:TARGET
|
||||
env:
|
||||
CMAKE_POLICY_VERSION_MINIMUM: "3.5"
|
||||
- name: Test (Tauri crate)
|
||||
@@ -993,7 +1066,7 @@ jobs:
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
- uses: cashapp/activate-hermit@cea9af7913204a965fd488637a8d1811bba2e616 # v1
|
||||
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
|
||||
with:
|
||||
@@ -1007,6 +1080,7 @@ jobs:
|
||||
mkdir -p desktop/src-tauri/binaries
|
||||
touch "desktop/src-tauri/binaries/buzz-acp-$TARGET"
|
||||
touch "desktop/src-tauri/binaries/buzz-agent-$TARGET"
|
||||
touch "desktop/src-tauri/binaries/buzz-backend-kubernetes-$TARGET"
|
||||
touch "desktop/src-tauri/binaries/buzz-dev-mcp-$TARGET"
|
||||
touch "desktop/src-tauri/binaries/git-credential-nostr-$TARGET"
|
||||
touch "desktop/src-tauri/binaries/buzz-$TARGET"
|
||||
|
||||
164
.github/workflows/desktop-release-cache-proof.yml
vendored
Normal file
164
.github/workflows/desktop-release-cache-proof.yml
vendored
Normal file
@@ -0,0 +1,164 @@
|
||||
name: Desktop release cache tag-scope proof
|
||||
|
||||
# Dispatch from a cache-proof-* tag at the same trusted-main SHA warmed by all
|
||||
# four canaries. Every job restores only and requires an exact cache hit.
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
macos:
|
||||
name: Prove macOS ${{ matrix.target }} cache visibility
|
||||
if: github.repository == 'block/buzz'
|
||||
runs-on: macos-latest
|
||||
timeout-minutes: 15
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- target: aarch64-apple-darwin
|
||||
features: mesh-llm
|
||||
- target: x86_64-apple-darwin
|
||||
features: default
|
||||
steps:
|
||||
- name: Require cache proof tag
|
||||
run: '[[ "$GITHUB_REF" == refs/tags/cache-proof-* ]] || { echo "::error::Expected cache-proof-* tag; got $GITHUB_REF"; exit 1; }'
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: cashapp/activate-hermit@cea9af7913204a965fd488637a8d1811bba2e616 # v1
|
||||
- name: Patch proof dependency graph
|
||||
run: |
|
||||
cd desktop && node scripts/set-version-from-tag.mjs "0.0.0-cache-proof"
|
||||
cd src-tauri && cargo update --workspace
|
||||
- name: Resolve native toolchain identity
|
||||
id: native_toolchain
|
||||
run: echo "id=$(scripts/desktop-native-toolchain-id.sh macos)" >> "$GITHUB_OUTPUT"
|
||||
- name: Compute exact release cache key
|
||||
id: rust_cache_key
|
||||
env:
|
||||
CACHE_TARGET: ${{ matrix.target }}
|
||||
CACHE_FEATURES: ${{ matrix.features }}
|
||||
NATIVE_TOOLCHAIN_ID: ${{ steps.native_toolchain.outputs.id }}
|
||||
run: |
|
||||
KEY=$(scripts/desktop-release-cache-key.py --platform "$RUNNER_OS" --target "$CACHE_TARGET" --features "$CACHE_FEATURES" --native-inputs "$NATIVE_TOOLCHAIN_ID")
|
||||
echo "key=$KEY" >> "$GITHUB_OUTPUT"
|
||||
- name: Restore exact default-branch cache from tag
|
||||
id: rust_cache
|
||||
uses: actions/cache/restore@caa296126883cff596d87d8935842f9db880ef25 # v5
|
||||
with:
|
||||
path: |
|
||||
~/.cargo/registry
|
||||
~/.cargo/git
|
||||
target
|
||||
desktop/src-tauri/target
|
||||
!desktop/src-tauri/target/**/release/bundle
|
||||
key: ${{ steps.rust_cache_key.outputs.key }}
|
||||
- name: Require exact cache hit
|
||||
env:
|
||||
CACHE_HIT: ${{ steps.rust_cache.outputs.cache-hit }}
|
||||
CACHE_KEY: ${{ steps.rust_cache.outputs.cache-primary-key }}
|
||||
EXPECTED_KEY: ${{ steps.rust_cache_key.outputs.key }}
|
||||
run: '[[ "$CACHE_HIT" == true && "$CACHE_KEY" == "$EXPECTED_KEY" ]] || { echo "::error::Exact tag cache miss (hit=$CACHE_HIT restored=$CACHE_KEY expected=$EXPECTED_KEY)"; exit 1; }'
|
||||
|
||||
linux:
|
||||
name: Prove Linux cache visibility
|
||||
if: github.repository == 'block/buzz'
|
||||
runs-on: ubuntu-latest
|
||||
container: ubuntu:24.04@sha256:4fbb8e6a8395de5a7550b33509421a2bafbc0aab6c06ba2cef9ebffbc7092d90
|
||||
timeout-minutes: 15
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
steps:
|
||||
- name: Require cache proof tag and install release native tools
|
||||
run: |
|
||||
[[ "$GITHUB_REF" == refs/tags/cache-proof-* ]] || { echo "::error::Expected cache-proof-* tag; got $GITHUB_REF"; exit 1; }
|
||||
apt-get update
|
||||
apt-get install -y --no-install-recommends build-essential ca-certificates curl git libasound2-dev libayatana-appindicator3-dev libgtk-3-dev librsvg2-dev libssl-dev libwebkit2gtk-4.1-dev libxdo-dev patchelf pkg-config
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
persist-credentials: false
|
||||
- run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
|
||||
- uses: cashapp/activate-hermit@cea9af7913204a965fd488637a8d1811bba2e616 # v1
|
||||
- name: Patch proof dependency graph
|
||||
run: |
|
||||
cd desktop && node scripts/set-version-from-tag.mjs "0.0.0-cache-proof"
|
||||
cd src-tauri && cargo update --workspace
|
||||
- name: Resolve native toolchain identity
|
||||
id: native_toolchain
|
||||
run: echo "id=$(scripts/desktop-native-toolchain-id.sh linux)" >> "$GITHUB_OUTPUT"
|
||||
- name: Compute exact release cache key
|
||||
id: rust_cache_key
|
||||
env:
|
||||
NATIVE_TOOLCHAIN_ID: ${{ steps.native_toolchain.outputs.id }}
|
||||
run: |
|
||||
KEY=$(scripts/desktop-release-cache-key.py --platform "$RUNNER_OS" --target x86_64-unknown-linux-gnu --features mesh-llm --native-inputs "$NATIVE_TOOLCHAIN_ID")
|
||||
echo "key=$KEY" >> "$GITHUB_OUTPUT"
|
||||
- name: Restore exact default-branch cache from tag
|
||||
id: rust_cache
|
||||
uses: actions/cache/restore@caa296126883cff596d87d8935842f9db880ef25 # v5
|
||||
with:
|
||||
path: |
|
||||
~/.cargo/registry
|
||||
~/.cargo/git
|
||||
target
|
||||
desktop/src-tauri/target
|
||||
!desktop/src-tauri/target/**/release/bundle
|
||||
key: ${{ steps.rust_cache_key.outputs.key }}
|
||||
- name: Require exact cache hit
|
||||
env:
|
||||
CACHE_HIT: ${{ steps.rust_cache.outputs.cache-hit }}
|
||||
CACHE_KEY: ${{ steps.rust_cache.outputs.cache-primary-key }}
|
||||
EXPECTED_KEY: ${{ steps.rust_cache_key.outputs.key }}
|
||||
run: '[[ "$CACHE_HIT" == true && "$CACHE_KEY" == "$EXPECTED_KEY" ]] || { echo "::error::Exact tag cache miss (hit=$CACHE_HIT restored=$CACHE_KEY expected=$EXPECTED_KEY)"; exit 1; }'
|
||||
|
||||
windows:
|
||||
name: Prove Windows cache visibility
|
||||
if: github.repository == 'block/buzz'
|
||||
runs-on: windows-latest
|
||||
timeout-minutes: 15
|
||||
steps:
|
||||
- name: Require cache proof tag
|
||||
shell: bash
|
||||
run: '[[ "$GITHUB_REF" == refs/tags/cache-proof-* ]] || { echo "::error::Expected cache-proof-* tag; got $GITHUB_REF"; exit 1; }'
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Patch proof dependency graph
|
||||
shell: bash
|
||||
run: |
|
||||
cd desktop && node scripts/set-version-from-tag.mjs "0.0.0-cache-proof"
|
||||
cd src-tauri && cargo update --workspace
|
||||
- name: Resolve native toolchain identity
|
||||
id: native_toolchain
|
||||
shell: bash
|
||||
run: echo "id=$(scripts/desktop-native-toolchain-id.sh windows)" >> "$GITHUB_OUTPUT"
|
||||
- name: Compute exact release cache key
|
||||
id: rust_cache_key
|
||||
shell: bash
|
||||
env:
|
||||
NATIVE_TOOLCHAIN_ID: ${{ steps.native_toolchain.outputs.id }}
|
||||
run: |
|
||||
KEY=$(scripts/desktop-release-cache-key.py --platform "$RUNNER_OS" --target x86_64-pc-windows-msvc --features default --native-inputs "$NATIVE_TOOLCHAIN_ID")
|
||||
echo "key=$KEY" >> "$GITHUB_OUTPUT"
|
||||
- name: Restore exact default-branch cache from tag
|
||||
id: rust_cache
|
||||
uses: actions/cache/restore@caa296126883cff596d87d8935842f9db880ef25 # v5
|
||||
with:
|
||||
path: |
|
||||
~/.cargo/registry
|
||||
~/.cargo/git
|
||||
target
|
||||
desktop/src-tauri/target
|
||||
!desktop/src-tauri/target/**/release/bundle
|
||||
key: ${{ steps.rust_cache_key.outputs.key }}
|
||||
- name: Require exact cache hit
|
||||
shell: bash
|
||||
env:
|
||||
CACHE_HIT: ${{ steps.rust_cache.outputs.cache-hit }}
|
||||
CACHE_KEY: ${{ steps.rust_cache.outputs.cache-primary-key }}
|
||||
EXPECTED_KEY: ${{ steps.rust_cache_key.outputs.key }}
|
||||
run: '[[ "$CACHE_HIT" == true && "$CACHE_KEY" == "$EXPECTED_KEY" ]] || { echo "::error::Exact tag cache miss (hit=$CACHE_HIT restored=$CACHE_KEY expected=$EXPECTED_KEY)"; exit 1; }'
|
||||
28
.github/workflows/desktop-release-candidate.yml
vendored
Normal file
28
.github/workflows/desktop-release-candidate.yml
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
name: Desktop Release Candidate
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [main]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: read
|
||||
|
||||
jobs:
|
||||
validate:
|
||||
name: Desktop Release Candidate
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
- name: Validate immutable desktop candidate
|
||||
if: startsWith(github.event.pull_request.head.ref, 'version-bump/')
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
VERSION: ${{ github.event.pull_request.head.ref }}
|
||||
run: |
|
||||
VERSION="${VERSION#version-bump/}"
|
||||
scripts/desktop_release.py validate --candidate HEAD --version "$VERSION" --repo "$GITHUB_REPOSITORY"
|
||||
79
.github/workflows/docker.yml
vendored
79
.github/workflows/docker.yml
vendored
@@ -1,6 +1,8 @@
|
||||
name: Docker image
|
||||
|
||||
# Builds and publishes the public Buzz relay image as ghcr.io/block/buzz.
|
||||
# Builds and publishes the public Buzz relay images as ghcr.io/block/buzz.
|
||||
# Normal tags contain stripped binaries; matching debug-* tags contain the same
|
||||
# optimized binaries with line-table debug information for native profilers.
|
||||
#
|
||||
# Strategy: each architecture builds on its native runner (ubuntu-24.04 for
|
||||
# amd64, ubuntu-24.04-arm for arm64), pushes to GHCR by digest, then a final
|
||||
@@ -15,8 +17,10 @@ name: Docker image
|
||||
#
|
||||
# Triggers:
|
||||
# - push to main → :main + :sha-<7>
|
||||
# + :debug-main + :debug-sha-<7>
|
||||
# - push tags relay-v*.*.* → :{version} + :{major}.{minor} + :{major}
|
||||
# (+ :latest for stable, NOT for prereleases)
|
||||
# + matching :debug-* tags
|
||||
# (+ :latest/:debug-latest for stable releases)
|
||||
# - pull_request → build only (no push), cache stays warm
|
||||
# - workflow_dispatch → manual relay-tag rescue at the tag itself
|
||||
#
|
||||
@@ -95,13 +99,9 @@ jobs:
|
||||
runner: ubuntu-24.04-arm
|
||||
arch: arm64
|
||||
|
||||
outputs:
|
||||
# Used downstream by `merge` to stitch the manifest.
|
||||
version: ${{ steps.meta.outputs.version }}
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
@@ -163,12 +163,13 @@ jobs:
|
||||
org.opencontainers.image.description=WebSocket relay server for the Buzz communications platform
|
||||
org.opencontainers.image.licenses=Apache-2.0
|
||||
|
||||
- name: Build and push by digest
|
||||
id: build
|
||||
- name: Build and push release image by digest
|
||||
id: build-release
|
||||
uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7.2.0
|
||||
with:
|
||||
context: .
|
||||
file: ./Dockerfile
|
||||
target: runtime
|
||||
platforms: ${{ matrix.platform }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
# Push by digest, not by tag — the merge job assembles the tags
|
||||
@@ -180,25 +181,49 @@ jobs:
|
||||
cache-to: |
|
||||
${{ (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository) && format('type=registry,ref={0}-buildcache:{1},mode=max,compression=zstd', env.IMAGE_NAME, matrix.arch) || '' }}
|
||||
|
||||
- name: Export digest
|
||||
- name: Build and push debug image by digest
|
||||
id: build-debug
|
||||
uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7.2.0
|
||||
with:
|
||||
context: .
|
||||
file: ./Dockerfile
|
||||
target: runtime-debug
|
||||
platforms: ${{ matrix.platform }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
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 }}
|
||||
|
||||
- name: Export release and debug digests
|
||||
if: github.event_name != 'pull_request'
|
||||
env:
|
||||
DIGEST: ${{ steps.build.outputs.digest }}
|
||||
RELEASE_DIGEST: ${{ steps.build-release.outputs.digest }}
|
||||
DEBUG_DIGEST: ${{ steps.build-debug.outputs.digest }}
|
||||
run: |
|
||||
mkdir -p /tmp/digests
|
||||
touch "/tmp/digests/${DIGEST#sha256:}"
|
||||
mkdir -p /tmp/digests-release /tmp/digests-debug
|
||||
touch "/tmp/digests-release/${RELEASE_DIGEST#sha256:}"
|
||||
touch "/tmp/digests-debug/${DEBUG_DIGEST#sha256:}"
|
||||
|
||||
- name: Upload digest
|
||||
- name: Upload release digest
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
with:
|
||||
name: digests-${{ matrix.arch }}
|
||||
path: /tmp/digests/*
|
||||
name: digests-release-${{ matrix.arch }}
|
||||
path: /tmp/digests-release/*
|
||||
if-no-files-found: error
|
||||
retention-days: 1
|
||||
|
||||
- name: Upload debug digest
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
with:
|
||||
name: digests-debug-${{ matrix.arch }}
|
||||
path: /tmp/digests-debug/*
|
||||
if-no-files-found: error
|
||||
retention-days: 1
|
||||
|
||||
merge:
|
||||
name: Merge multi-arch manifest
|
||||
name: Merge ${{ matrix.variant }} multi-arch manifest
|
||||
if: github.event_name != 'pull_request'
|
||||
runs-on: ubuntu-24.04
|
||||
needs: build
|
||||
@@ -208,13 +233,21 @@ jobs:
|
||||
packages: write # push the merged manifest
|
||||
id-token: write # OIDC for provenance attestation on the manifest
|
||||
attestations: write
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- variant: release
|
||||
tag_prefix: ""
|
||||
- variant: debug
|
||||
tag_prefix: debug-
|
||||
|
||||
steps:
|
||||
- name: Download all per-arch digests
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||
with:
|
||||
path: /tmp/digests
|
||||
pattern: digests-*
|
||||
pattern: digests-${{ matrix.variant }}-*
|
||||
merge-multiple: true
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
@@ -237,9 +270,12 @@ jobs:
|
||||
# the build job's `meta` step for why match=^relay-v(.*)$, why
|
||||
# value=${{ inputs.version }} carries the rescue-dispatch version,
|
||||
# and why :latest is left to flavor.latest=auto.
|
||||
flavor: |
|
||||
latest=auto
|
||||
prefix=${{ matrix.tag_prefix }},onlatest=true
|
||||
tags: |
|
||||
type=ref,event=branch,enable=${{ github.event_name != 'workflow_dispatch' || inputs.version == '' }}
|
||||
type=sha,prefix=sha-,format=short,enable=${{ github.event_name != 'workflow_dispatch' || inputs.version == '' }}
|
||||
type=sha,prefix=${{ matrix.tag_prefix }}sha-,format=short,enable=${{ github.event_name != 'workflow_dispatch' || inputs.version == '' }}
|
||||
type=semver,pattern={{version}},match=^relay-v(.*)$,value=${{ inputs.version }}
|
||||
type=semver,pattern={{major}}.{{minor}},match=^relay-v(.*)$,value=${{ inputs.version }}
|
||||
type=semver,pattern={{major}},match=^relay-v(.*)$,value=${{ inputs.version }}
|
||||
@@ -284,11 +320,12 @@ jobs:
|
||||
- name: Summary
|
||||
env:
|
||||
IMAGE_NAME: ${{ env.IMAGE_NAME }}
|
||||
VARIANT: ${{ matrix.variant }}
|
||||
MERGED_DIGEST: ${{ steps.manifest.outputs.digest }}
|
||||
META_TAGS: ${{ steps.meta.outputs.tags }}
|
||||
run: |
|
||||
{
|
||||
echo "### Published \`${IMAGE_NAME}\`"
|
||||
echo "### Published \`${IMAGE_NAME}\` (${VARIANT})"
|
||||
echo
|
||||
echo "**Digest:** \`${MERGED_DIGEST}\`"
|
||||
echo
|
||||
@@ -322,7 +359,7 @@ jobs:
|
||||
arch: arm64
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
|
||||
6
.github/workflows/helm-chart.yml
vendored
6
.github/workflows/helm-chart.yml
vendored
@@ -59,7 +59,7 @@ jobs:
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
||||
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
|
||||
with:
|
||||
# On chart-tag rescue dispatch, lint/render the tagged commit that the
|
||||
# publish job will package, not whatever `main` is when the dispatch
|
||||
@@ -119,7 +119,7 @@ jobs:
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
||||
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
@@ -166,7 +166,7 @@ jobs:
|
||||
packages: write # push the chart to GHCR
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
||||
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
|
||||
with:
|
||||
# On the rescue dispatch, build the tagged commit (github.ref is
|
||||
# `main` there); on a tag push, the default ref is already the tag.
|
||||
|
||||
72
.github/workflows/linux-canary.yml
vendored
72
.github/workflows/linux-canary.yml
vendored
@@ -7,8 +7,8 @@ name: Linux Canary
|
||||
# Design notes vs. signed-macos-canary.yml:
|
||||
# - fix-appimage.sh is run without signing env vars; the script detects
|
||||
# their absence and skips re-signing, repacking only (documented inline).
|
||||
# - mold linker added (rui314/setup-mold) to reduce link time, matching
|
||||
# the Linux Rust CI jobs in ci.yml.
|
||||
# - Build tools match release.yml; cache keys derive the concrete linker and
|
||||
# native library identity rather than assuming the moving runner image.
|
||||
# - pnpm store restore/save pattern mirrors ci.yml:149-196.
|
||||
on:
|
||||
workflow_dispatch:
|
||||
@@ -21,7 +21,7 @@ jobs:
|
||||
name: Build Linux canary
|
||||
if: github.repository == 'block/buzz'
|
||||
runs-on: ubuntu-latest
|
||||
container: ubuntu:22.04@sha256:0e0a0fc6d18feda9db1590da249ac93e8d5abfea8f4c3c0c849ce512b5ef8982
|
||||
container: ubuntu:24.04@sha256:4fbb8e6a8395de5a7550b33509421a2bafbc0aab6c06ba2cef9ebffbc7092d90
|
||||
timeout-minutes: 60
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -83,18 +83,6 @@ jobs:
|
||||
|
||||
- uses: cashapp/activate-hermit@cea9af7913204a965fd488637a8d1811bba2e616 # v1
|
||||
|
||||
- uses: rui314/setup-mold@9c9c13bf4c3f1adef0cc596abc155580bcb04444 # v1
|
||||
|
||||
# Rust cache covering both the workspace sidecar build and the Tauri
|
||||
# crate build. shared-key scoped to linux-canary-release so canary runs
|
||||
# warm each other without colliding with CI's debug-profile keys.
|
||||
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
|
||||
with:
|
||||
workspaces: |
|
||||
.
|
||||
desktop/src-tauri
|
||||
shared-key: linux-canary-release
|
||||
|
||||
- name: Install appimagetool
|
||||
run: |
|
||||
case "$(uname -m)" in
|
||||
@@ -154,6 +142,38 @@ jobs:
|
||||
cd desktop && node scripts/set-version-from-tag.mjs "$VERSION"
|
||||
cd src-tauri && cargo update --workspace
|
||||
|
||||
- name: Resolve native toolchain identity
|
||||
id: native_toolchain
|
||||
run: echo "id=$(scripts/desktop-native-toolchain-id.sh linux)" >> "$GITHUB_OUTPUT"
|
||||
|
||||
# Compute this after cargo update so the key describes the graph that is
|
||||
# actually compiled. The helper normalizes only Buzz Desktop's release
|
||||
# version, allowing a canary to warm an otherwise identical tag build.
|
||||
- name: Compute exact release cache key
|
||||
id: rust_cache_key
|
||||
env:
|
||||
NATIVE_TOOLCHAIN_ID: ${{ steps.native_toolchain.outputs.id }}
|
||||
run: |
|
||||
KEY=$(scripts/desktop-release-cache-key.py \
|
||||
--platform "$RUNNER_OS" \
|
||||
--target x86_64-unknown-linux-gnu \
|
||||
--features mesh-llm \
|
||||
--native-inputs "$NATIVE_TOOLCHAIN_ID")
|
||||
echo "key=$KEY" >> "$GITHUB_OUTPUT"
|
||||
echo "Release cache key: $KEY"
|
||||
|
||||
- name: Restore exact release Cargo cache
|
||||
id: rust_cache
|
||||
uses: actions/cache/restore@caa296126883cff596d87d8935842f9db880ef25 # v5
|
||||
with:
|
||||
path: |
|
||||
~/.cargo/registry
|
||||
~/.cargo/git
|
||||
target
|
||||
desktop/src-tauri/target
|
||||
!desktop/src-tauri/target/**/release/bundle
|
||||
key: ${{ steps.rust_cache_key.outputs.key }}
|
||||
|
||||
- name: Generate non-updating bundle config
|
||||
run: |
|
||||
cat > desktop/src-tauri/tauri.canary.conf.json <<'JSON'
|
||||
@@ -166,11 +186,11 @@ jobs:
|
||||
|
||||
- name: Build sidecars
|
||||
run: |
|
||||
cargo build --release -p buzz-acp -p buzz-agent -p buzz-dev-mcp -p git-credential-nostr -p buzz-cli
|
||||
cargo build --release -p buzz-acp -p buzz-agent -p buzz-backend-kubernetes -p buzz-dev-mcp -p git-credential-nostr -p buzz-cli
|
||||
./scripts/bundle-sidecars.sh
|
||||
|
||||
- name: Build Linux Tauri app
|
||||
run: cd desktop && pnpm tauri build --ci --bundles deb,appimage --config src-tauri/tauri.canary.conf.json
|
||||
run: cd desktop && pnpm tauri build --ci --bundles deb,appimage --features mesh-llm --config src-tauri/tauri.canary.conf.json
|
||||
env:
|
||||
CMAKE_POLICY_VERSION_MINIMUM: "3.5"
|
||||
|
||||
@@ -190,6 +210,24 @@ jobs:
|
||||
fi
|
||||
bash desktop/scripts/fix-appimage.sh "${APPIMAGES[0]}"
|
||||
|
||||
- name: Measure release Cargo cache inputs
|
||||
if: always()
|
||||
run: du -sh ~/.cargo/registry ~/.cargo/git target desktop/src-tauri/target 2>/dev/null || true
|
||||
|
||||
# Only this trusted, main-bound canary writes the cache. Excluding bundle
|
||||
# output prevents installers from entering it.
|
||||
- name: Save exact release Cargo cache
|
||||
if: steps.rust_cache.outputs.cache-hit != 'true'
|
||||
uses: actions/cache/save@caa296126883cff596d87d8935842f9db880ef25 # v5
|
||||
with:
|
||||
path: |
|
||||
~/.cargo/registry
|
||||
~/.cargo/git
|
||||
target
|
||||
desktop/src-tauri/target
|
||||
!desktop/src-tauri/target/**/release/bundle
|
||||
key: ${{ steps.rust_cache_key.outputs.key }}
|
||||
|
||||
- name: Save pnpm store cache
|
||||
uses: actions/cache/save@caa296126883cff596d87d8935842f9db880ef25 # v5
|
||||
with:
|
||||
|
||||
126
.github/workflows/macos-intel-canary.yml
vendored
Normal file
126
.github/workflows/macos-intel-canary.yml
vendored
Normal file
@@ -0,0 +1,126 @@
|
||||
name: macOS Intel Canary
|
||||
|
||||
# Produces an unsigned Intel DMG from trusted main. Its release-equivalent
|
||||
# Cargo state warms the distinct x86_64 release target without signing or
|
||||
# publishing anything.
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build macOS Intel canary
|
||||
if: github.repository == 'block/buzz'
|
||||
runs-on: macos-latest
|
||||
timeout-minutes: 60
|
||||
env:
|
||||
TARGET: x86_64-apple-darwin
|
||||
steps:
|
||||
- name: Require main
|
||||
env:
|
||||
SOURCE_REF: ${{ github.ref }}
|
||||
run: |
|
||||
if [[ "$SOURCE_REF" != "refs/heads/main" ]]; then
|
||||
echo "::error::Canary builds must run from main; got $SOURCE_REF"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- uses: cashapp/activate-hermit@cea9af7913204a965fd488637a8d1811bba2e616 # v1
|
||||
|
||||
- name: Add Rust target
|
||||
run: rustup target add "$TARGET"
|
||||
|
||||
- name: Install desktop dependencies
|
||||
run: just desktop-install-ci
|
||||
|
||||
- name: Derive and patch canary version
|
||||
run: |
|
||||
BASE_VERSION=$(node -p "require('./desktop/package.json').version")
|
||||
VERSION="${BASE_VERSION%%-*}-intel-test.${GITHUB_RUN_NUMBER}"
|
||||
cd desktop && node scripts/set-version-from-tag.mjs "$VERSION"
|
||||
cd src-tauri && cargo update --workspace
|
||||
|
||||
- name: Resolve native toolchain identity
|
||||
id: native_toolchain
|
||||
run: echo "id=$(scripts/desktop-native-toolchain-id.sh macos)" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Compute exact release cache key
|
||||
id: rust_cache_key
|
||||
env:
|
||||
NATIVE_TOOLCHAIN_ID: ${{ steps.native_toolchain.outputs.id }}
|
||||
run: |
|
||||
KEY=$(scripts/desktop-release-cache-key.py \
|
||||
--platform "$RUNNER_OS" \
|
||||
--target "$TARGET" \
|
||||
--features default \
|
||||
--native-inputs "$NATIVE_TOOLCHAIN_ID")
|
||||
echo "key=$KEY" >> "$GITHUB_OUTPUT"
|
||||
echo "Release cache key: $KEY"
|
||||
|
||||
- name: Restore exact release Cargo cache
|
||||
id: rust_cache
|
||||
uses: actions/cache/restore@caa296126883cff596d87d8935842f9db880ef25 # v5
|
||||
with:
|
||||
path: |
|
||||
~/.cargo/registry
|
||||
~/.cargo/git
|
||||
target
|
||||
desktop/src-tauri/target
|
||||
!desktop/src-tauri/target/**/release/bundle
|
||||
key: ${{ steps.rust_cache_key.outputs.key }}
|
||||
|
||||
- name: Generate non-updating bundle config
|
||||
run: |
|
||||
cat > desktop/src-tauri/tauri.canary.conf.json <<'JSON'
|
||||
{"bundle":{"createUpdaterArtifacts":false,"macOS":{"minimumSystemVersion":"10.15"}}}
|
||||
JSON
|
||||
|
||||
- name: Build Intel sidecars
|
||||
run: |
|
||||
cargo build --release --target "$TARGET" -p buzz-acp -p buzz-agent -p buzz-backend-kubernetes -p buzz-dev-mcp -p git-credential-nostr -p buzz-cli
|
||||
./scripts/bundle-sidecars.sh "$TARGET"
|
||||
|
||||
- name: Build unsigned Intel DMG
|
||||
run: cd desktop && pnpm tauri build --verbose --no-sign --target "$TARGET" --bundles dmg --config src-tauri/tauri.canary.conf.json
|
||||
env:
|
||||
CMAKE_POLICY_VERSION_MINIMUM: "3.5"
|
||||
MACOSX_DEPLOYMENT_TARGET: "10.15"
|
||||
CMAKE_OSX_DEPLOYMENT_TARGET: "10.15"
|
||||
TAURI_BUNDLER_DMG_IGNORE_CI: "true"
|
||||
|
||||
- name: Locate fresh Intel DMG
|
||||
id: artifact
|
||||
run: |
|
||||
DMG=$(find "desktop/src-tauri/target/${TARGET}/release/bundle/dmg" -name '*.dmg' -type f | head -1)
|
||||
[[ -n "$DMG" ]] || { echo "::error::No Intel DMG found"; exit 1; }
|
||||
echo "dmg=$DMG" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Upload Intel canary
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
|
||||
with:
|
||||
name: buzz-macos-intel-canary-${{ github.sha }}
|
||||
path: ${{ steps.artifact.outputs.dmg }}
|
||||
if-no-files-found: error
|
||||
retention-days: 7
|
||||
|
||||
- name: Measure release Cargo cache inputs
|
||||
if: always()
|
||||
run: du -sh ~/.cargo/registry ~/.cargo/git target desktop/src-tauri/target 2>/dev/null || true
|
||||
|
||||
- name: Save exact release Cargo cache
|
||||
if: steps.rust_cache.outputs.cache-hit != 'true'
|
||||
uses: actions/cache/save@caa296126883cff596d87d8935842f9db880ef25 # v5
|
||||
with:
|
||||
path: |
|
||||
~/.cargo/registry
|
||||
~/.cargo/git
|
||||
target
|
||||
desktop/src-tauri/target
|
||||
!desktop/src-tauri/target/**/release/bundle
|
||||
key: ${{ steps.rust_cache_key.outputs.key }}
|
||||
111
.github/workflows/mesh-lifecycle.yml
vendored
Normal file
111
.github/workflows/mesh-lifecycle.yml
vendored
Normal file
@@ -0,0 +1,111 @@
|
||||
name: Mesh Lifecycle
|
||||
# Relay-driven mesh lifecycle smoke: membership → signed discovery notes →
|
||||
# relay-derived allowlist → join → CPU inference over QUIC → stranger denied
|
||||
# (relay membership rejection + no routed inference, with a differential
|
||||
# trusted-inference health proof so a dead serve node can't fake a denial).
|
||||
# Runs the full Buzz "shared compute" join story with three real mesh-llm
|
||||
# node processes on one runner, using the Buzz relay as the control plane
|
||||
# (no hand-carried invite tokens). Mirrors the shape mesh-llm's own CI uses
|
||||
# for its two-node smokes (tiny CPU model, one runner, real QUIC mesh).
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
paths:
|
||||
- 'crates/buzz-relay/examples/mesh_*.rs'
|
||||
- 'crates/buzz-relay/Cargo.toml'
|
||||
- 'crates/buzz-admin/**'
|
||||
- 'crates/buzz-test-client/**'
|
||||
- 'crates/buzz-ws-client/**'
|
||||
- 'Cargo.lock'
|
||||
- 'desktop/src-tauri/src/mesh_llm/**'
|
||||
- 'scripts/ci-mesh-lifecycle-smoke.sh'
|
||||
- 'scripts/start-relay-for-tests.sh'
|
||||
- '.github/workflows/mesh-lifecycle.yml'
|
||||
pull_request:
|
||||
paths:
|
||||
- 'crates/buzz-relay/examples/mesh_*.rs'
|
||||
- 'crates/buzz-relay/Cargo.toml'
|
||||
- 'crates/buzz-admin/**'
|
||||
- 'crates/buzz-test-client/**'
|
||||
- 'crates/buzz-ws-client/**'
|
||||
- 'Cargo.lock'
|
||||
- 'desktop/src-tauri/src/mesh_llm/**'
|
||||
- 'scripts/ci-mesh-lifecycle-smoke.sh'
|
||||
- 'scripts/start-relay-for-tests.sh'
|
||||
- '.github/workflows/mesh-lifecycle.yml'
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: mesh-lifecycle-${{ github.event_name == 'pull_request' && github.ref || github.sha }}
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
|
||||
jobs:
|
||||
lifecycle-smoke:
|
||||
name: Relay-Driven Mesh Lifecycle Smoke
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 45
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
|
||||
- uses: cashapp/activate-hermit@cea9af7913204a965fd488637a8d1811bba2e616 # v1
|
||||
|
||||
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
|
||||
with:
|
||||
save-if: ${{ github.event_name != 'pull_request' }}
|
||||
|
||||
# The mesh-llm SDK downloads a signed native runtime (llama.cpp CPU
|
||||
# build) on first init, and the serve node downloads the smoke model
|
||||
# from HuggingFace on first run. Key on the lockfile so a mesh pin bump
|
||||
# rolls the runtime cache; the model ref is stable.
|
||||
- name: Restore mesh runtime + model caches
|
||||
id: mesh-caches
|
||||
uses: actions/cache/restore@caa296126883cff596d87d8935842f9db880ef25 # v5
|
||||
with:
|
||||
path: |
|
||||
~/.cache/mesh-llm/native-runtimes
|
||||
~/.cache/huggingface/hub
|
||||
key: mesh-lifecycle-${{ runner.os }}-smollm2-135m-${{ hashFiles('Cargo.lock') }}
|
||||
restore-keys: |
|
||||
mesh-lifecycle-${{ runner.os }}-smollm2-135m-
|
||||
|
||||
- name: Start integration services
|
||||
run: |
|
||||
for attempt in 1 2 3; do
|
||||
if docker compose up -d postgres redis minio minio-init; then
|
||||
break
|
||||
fi
|
||||
if [ "$attempt" -eq 3 ]; then
|
||||
echo "docker compose up failed after 3 attempts" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "docker compose up failed (attempt $attempt), retrying in $((attempt * 5))s..." >&2
|
||||
sleep $((attempt * 5))
|
||||
done
|
||||
|
||||
- name: Run relay-driven mesh lifecycle smoke
|
||||
run: ./scripts/ci-mesh-lifecycle-smoke.sh 2>&1 | tee /tmp/mesh-lifecycle-harness.log
|
||||
|
||||
- name: Save mesh runtime + model caches
|
||||
if: github.ref == 'refs/heads/main' && steps.mesh-caches.outputs.cache-hit != 'true'
|
||||
uses: actions/cache/save@caa296126883cff596d87d8935842f9db880ef25 # v5
|
||||
with:
|
||||
path: |
|
||||
~/.cache/mesh-llm/native-runtimes
|
||||
~/.cache/huggingface/hub
|
||||
key: mesh-lifecycle-${{ runner.os }}-smollm2-135m-${{ hashFiles('Cargo.lock') }}
|
||||
|
||||
- name: Upload relay + harness logs
|
||||
if: failure()
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
|
||||
with:
|
||||
name: mesh-lifecycle-logs
|
||||
path: |
|
||||
/tmp/buzz-relay.log
|
||||
/tmp/mesh-lifecycle-harness.log
|
||||
if-no-files-found: ignore
|
||||
344
.github/workflows/release.yml
vendored
344
.github/workflows/release.yml
vendored
@@ -1,14 +1,13 @@
|
||||
name: Release
|
||||
|
||||
concurrency:
|
||||
group: desktop-release-${{ github.ref }}
|
||||
cancel-in-progress: false
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v[0-9]*'
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
description: "Semver version matching the v-prefixed dispatch tag"
|
||||
required: true
|
||||
- 'desktop-v[0-9]*'
|
||||
|
||||
jobs:
|
||||
# Shared setup: verify the immutable release tag, determine the version, and
|
||||
@@ -19,23 +18,14 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
permissions:
|
||||
contents: write
|
||||
contents: read
|
||||
outputs:
|
||||
version: ${{ steps.version.outputs.version }}
|
||||
source_sha: ${{ steps.source.outputs.source_sha }}
|
||||
steps:
|
||||
- name: Determine version
|
||||
id: version
|
||||
env:
|
||||
EVENT_NAME: ${{ github.event_name }}
|
||||
INPUT_VERSION: ${{ inputs.version }}
|
||||
run: |
|
||||
if [[ "$EVENT_NAME" == "push" ]]; then
|
||||
VERSION="${GITHUB_REF_NAME#v}"
|
||||
else
|
||||
VERSION="$INPUT_VERSION"
|
||||
fi
|
||||
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
|
||||
run: echo "version=${GITHUB_REF_NAME#desktop-v}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Validate version
|
||||
env:
|
||||
@@ -46,7 +36,7 @@ jobs:
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
@@ -56,42 +46,9 @@ jobs:
|
||||
env:
|
||||
VERSION: ${{ steps.version.outputs.version }}
|
||||
run: |
|
||||
scripts/verify-release-ref.sh v "$VERSION"
|
||||
scripts/verify-release-ref.sh desktop-v "$VERSION"
|
||||
echo "source_sha=$(git rev-parse 'HEAD^{commit}')" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Create versioned GitHub release
|
||||
env:
|
||||
VERSION: ${{ steps.version.outputs.version }}
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
RELEASE_SHA=$(git rev-parse HEAD)
|
||||
NOTES=""
|
||||
if [[ -f CHANGELOG.md ]]; then
|
||||
NOTES=$(awk "/^## v${VERSION}\$/{found=1; next} found && /^## v/{exit} found && !/^\$/" CHANGELOG.md)
|
||||
fi
|
||||
if [[ -z "$NOTES" ]]; then
|
||||
NOTES="Buzz Desktop v${VERSION}"
|
||||
fi
|
||||
PRERELEASE_FLAGS=()
|
||||
if [[ "$VERSION" =~ -(test|alpha|beta|rc)([.-]|$) ]]; then
|
||||
PRERELEASE_FLAGS=(--prerelease --latest=false)
|
||||
fi
|
||||
gh release create "v${VERSION}" \
|
||||
--target "$RELEASE_SHA" \
|
||||
--title "Buzz Desktop v${VERSION}" \
|
||||
--notes "$NOTES" \
|
||||
"${PRERELEASE_FLAGS[@]}"
|
||||
|
||||
- name: Create rolling auto-update release
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
gh release create buzz-desktop-latest \
|
||||
--prerelease \
|
||||
--title "Buzz Desktop Auto-Update" \
|
||||
--notes "Rolling release for the Tauri auto-updater. Do not download manually — use the versioned release instead." \
|
||||
2>/dev/null || true
|
||||
|
||||
release:
|
||||
name: Release
|
||||
if: github.repository == 'block/buzz'
|
||||
@@ -99,7 +56,7 @@ jobs:
|
||||
needs: setup
|
||||
timeout-minutes: 60
|
||||
permissions:
|
||||
contents: write
|
||||
contents: read
|
||||
id-token: write # required by block/apple-codesign-action for OIDC
|
||||
outputs:
|
||||
archive_name: ${{ steps.artifacts.outputs.archive_name }}
|
||||
@@ -107,14 +64,14 @@ jobs:
|
||||
env:
|
||||
VERSION: ${{ needs.setup.outputs.version }}
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
ref: ${{ needs.setup.outputs.source_sha }}
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
|
||||
- name: Verify tag-bound release source
|
||||
run: scripts/verify-release-ref.sh v "$VERSION"
|
||||
run: scripts/verify-release-ref.sh desktop-v "$VERSION"
|
||||
|
||||
- uses: cashapp/activate-hermit@cea9af7913204a965fd488637a8d1811bba2e616 # v1
|
||||
|
||||
@@ -134,7 +91,7 @@ jobs:
|
||||
|
||||
- name: Build sidecars
|
||||
run: |
|
||||
cargo build --release -p buzz-acp -p buzz-agent -p buzz-dev-mcp -p git-credential-nostr -p buzz-cli
|
||||
cargo build --release -p buzz-acp -p buzz-agent -p buzz-backend-kubernetes -p buzz-dev-mcp -p git-credential-nostr -p buzz-cli
|
||||
./scripts/bundle-sidecars.sh
|
||||
|
||||
# Mesh rev derived from Cargo.lock (no lockstep edit on dep bump); cache key tracks it.
|
||||
@@ -272,13 +229,19 @@ jobs:
|
||||
fi
|
||||
echo "dmg=$DMG" >> "$GITHUB_OUTPUT"
|
||||
|
||||
# Find the updater .tar.gz and .sig
|
||||
# Find the updater .tar.gz and .sig. Give each architecture a unique
|
||||
# release basename before artifacts are merged by the final writer.
|
||||
ARCHIVE=$(find "$BUNDLE_DIR/macos" -name '*.tar.gz' ! -name '*.sig' -type f | head -1)
|
||||
SIG="${ARCHIVE}.sig"
|
||||
if [[ -z "$ARCHIVE" || ! -f "$SIG" ]]; then
|
||||
echo "::error::Updater archive or signature not found in $BUNDLE_DIR/macos"
|
||||
exit 1
|
||||
fi
|
||||
RENAMED="$(dirname "$ARCHIVE")/Buzz_${VERSION}_aarch64.app.tar.gz"
|
||||
mv "$ARCHIVE" "$RENAMED"
|
||||
mv "$SIG" "${RENAMED}.sig"
|
||||
ARCHIVE="$RENAMED"
|
||||
SIG="${RENAMED}.sig"
|
||||
echo "archive=$ARCHIVE" >> "$GITHUB_OUTPUT"
|
||||
echo "archive_name=$(basename "$ARCHIVE")" >> "$GITHUB_OUTPUT"
|
||||
echo "sig=$SIG" >> "$GITHUB_OUTPUT"
|
||||
@@ -289,23 +252,15 @@ jobs:
|
||||
env:
|
||||
SIG_PATH: ${{ steps.artifacts.outputs.sig }}
|
||||
|
||||
- name: Upload arm64 DMG to versioned GitHub release
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
DMG_PATH: ${{ steps.artifacts.outputs.dmg }}
|
||||
run: gh release upload "v${VERSION}" "$DMG_PATH" --clobber
|
||||
|
||||
- name: Upload updater archive to rolling release
|
||||
if: github.ref == format('refs/tags/v{0}', needs.setup.outputs.version)
|
||||
run: |
|
||||
gh release upload buzz-desktop-latest \
|
||||
"$ARCHIVE_PATH" \
|
||||
"$SIG_PATH" \
|
||||
--clobber
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
ARCHIVE_PATH: ${{ steps.artifacts.outputs.archive }}
|
||||
SIG_PATH: ${{ steps.artifacts.outputs.sig }}
|
||||
- name: Stage Apple Silicon release artifacts
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
|
||||
with:
|
||||
name: desktop-release-macos-arm64
|
||||
if-no-files-found: error
|
||||
path: |
|
||||
${{ steps.artifacts.outputs.dmg }}
|
||||
${{ steps.artifacts.outputs.archive }}
|
||||
${{ steps.artifacts.outputs.sig }}
|
||||
|
||||
release-macos-x64:
|
||||
name: Release macOS (Intel)
|
||||
@@ -314,7 +269,7 @@ jobs:
|
||||
needs: setup
|
||||
timeout-minutes: 60
|
||||
permissions:
|
||||
contents: write
|
||||
contents: read
|
||||
id-token: write # required by block/apple-codesign-action for OIDC
|
||||
outputs:
|
||||
archive_name: ${{ steps.artifacts.outputs.archive_name }}
|
||||
@@ -323,14 +278,14 @@ jobs:
|
||||
VERSION: ${{ needs.setup.outputs.version }}
|
||||
TARGET: x86_64-apple-darwin
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
ref: ${{ needs.setup.outputs.source_sha }}
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
|
||||
- name: Verify tag-bound release source
|
||||
run: scripts/verify-release-ref.sh v "$VERSION"
|
||||
run: scripts/verify-release-ref.sh desktop-v "$VERSION"
|
||||
|
||||
- uses: cashapp/activate-hermit@cea9af7913204a965fd488637a8d1811bba2e616 # v1
|
||||
|
||||
@@ -353,7 +308,7 @@ jobs:
|
||||
|
||||
- name: Build sidecars
|
||||
run: |
|
||||
cargo build --release --target "$TARGET" -p buzz-acp -p buzz-agent -p buzz-dev-mcp -p git-credential-nostr -p buzz-cli
|
||||
cargo build --release --target "$TARGET" -p buzz-acp -p buzz-agent -p buzz-backend-kubernetes -p buzz-dev-mcp -p git-credential-nostr -p buzz-cli
|
||||
./scripts/bundle-sidecars.sh "$TARGET"
|
||||
|
||||
- name: Build unsigned Tauri app
|
||||
@@ -443,6 +398,11 @@ jobs:
|
||||
echo "::error::Updater archive or signature not found in $BUNDLE_DIR/macos"
|
||||
exit 1
|
||||
fi
|
||||
RENAMED="$(dirname "$ARCHIVE")/Buzz_${VERSION}_x64.app.tar.gz"
|
||||
mv "$ARCHIVE" "$RENAMED"
|
||||
mv "$SIG" "${RENAMED}.sig"
|
||||
ARCHIVE="$RENAMED"
|
||||
SIG="${RENAMED}.sig"
|
||||
echo "archive=$ARCHIVE" >> "$GITHUB_OUTPUT"
|
||||
echo "archive_name=$(basename "$ARCHIVE")" >> "$GITHUB_OUTPUT"
|
||||
echo "sig=$SIG" >> "$GITHUB_OUTPUT"
|
||||
@@ -453,34 +413,26 @@ jobs:
|
||||
env:
|
||||
SIG_PATH: ${{ steps.artifacts.outputs.sig }}
|
||||
|
||||
- name: Upload Intel DMG to versioned GitHub release
|
||||
run: gh release upload "v${VERSION}" "$DMG_PATH" --clobber
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
DMG_PATH: ${{ steps.unsigned.outputs.dmg }}
|
||||
|
||||
- name: Upload updater archive to rolling release
|
||||
if: github.ref == format('refs/tags/v{0}', needs.setup.outputs.version)
|
||||
run: |
|
||||
gh release upload buzz-desktop-latest \
|
||||
"$ARCHIVE_PATH" \
|
||||
"$SIG_PATH" \
|
||||
--clobber
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
ARCHIVE_PATH: ${{ steps.artifacts.outputs.archive }}
|
||||
SIG_PATH: ${{ steps.artifacts.outputs.sig }}
|
||||
- name: Stage Intel macOS release artifacts
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
|
||||
with:
|
||||
name: desktop-release-macos-x64
|
||||
if-no-files-found: error
|
||||
path: |
|
||||
${{ steps.unsigned.outputs.dmg }}
|
||||
${{ steps.artifacts.outputs.archive }}
|
||||
${{ steps.artifacts.outputs.sig }}
|
||||
|
||||
release-linux:
|
||||
name: Release Linux
|
||||
if: github.repository == 'block/buzz'
|
||||
runs-on: ubuntu-latest
|
||||
# Digest-pinned like the SHA-pinned actions below; Renovate keeps it fresh.
|
||||
container: ubuntu:22.04@sha256:0e0a0fc6d18feda9db1590da249ac93e8d5abfea8f4c3c0c849ce512b5ef8982
|
||||
container: ubuntu:24.04@sha256:4fbb8e6a8395de5a7550b33509421a2bafbc0aab6c06ba2cef9ebffbc7092d90
|
||||
needs: setup
|
||||
timeout-minutes: 60
|
||||
permissions:
|
||||
contents: write
|
||||
contents: read
|
||||
env:
|
||||
# AppImage tools (linuxdeploy, appimagetool) are themselves AppImages.
|
||||
# Containers lack FUSE, so we must use the extract-and-run fallback.
|
||||
@@ -498,7 +450,7 @@ jobs:
|
||||
env:
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
run: |
|
||||
# Must run first: bare ubuntu:22.04 ships without curl, wget, git, or
|
||||
# Must run first: bare ubuntu:24.04 ships without curl, wget, git, or
|
||||
# ca-certificates. activate-hermit bootstraps via curl+HTTPS (needs
|
||||
# both), and actions/checkout falls back to a REST tarball without git.
|
||||
# Running as root — no sudo needed.
|
||||
@@ -543,7 +495,7 @@ jobs:
|
||||
apt-get update
|
||||
apt-get install -y --no-install-recommends gh
|
||||
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
ref: ${{ needs.setup.outputs.source_sha }}
|
||||
fetch-depth: 0
|
||||
@@ -555,7 +507,7 @@ jobs:
|
||||
- name: Verify tag-bound release source
|
||||
env:
|
||||
VERSION: ${{ needs.setup.outputs.version }}
|
||||
run: scripts/verify-release-ref.sh v "$VERSION"
|
||||
run: scripts/verify-release-ref.sh desktop-v "$VERSION"
|
||||
|
||||
- uses: cashapp/activate-hermit@cea9af7913204a965fd488637a8d1811bba2e616 # v1
|
||||
|
||||
@@ -611,7 +563,7 @@ jobs:
|
||||
|
||||
- name: Build sidecars
|
||||
run: |
|
||||
cargo build --release -p buzz-acp -p buzz-agent -p buzz-dev-mcp -p git-credential-nostr -p buzz-cli
|
||||
cargo build --release -p buzz-acp -p buzz-agent -p buzz-backend-kubernetes -p buzz-dev-mcp -p git-credential-nostr -p buzz-cli
|
||||
./scripts/bundle-sidecars.sh
|
||||
|
||||
- name: Generate release config
|
||||
@@ -621,7 +573,7 @@ jobs:
|
||||
BUZZ_UPDATER_ENDPOINT: https://github.com/block/buzz/releases/download/buzz-desktop-latest/latest.json
|
||||
|
||||
- name: Build Linux Tauri app
|
||||
run: cd desktop && pnpm tauri build --verbose --ci --bundles deb,appimage --config src-tauri/tauri.release.conf.json
|
||||
run: cd desktop && pnpm tauri build --verbose --ci --bundles deb,appimage --features mesh-llm --config src-tauri/tauri.release.conf.json
|
||||
env:
|
||||
BUZZ_UPDATER_PUBLIC_KEY: ${{ secrets.BUZZ_UPDATER_PUBLIC_KEY || secrets.SPROUT_UPDATER_PUBLIC_KEY }}
|
||||
BUZZ_UPDATER_ENDPOINT: https://github.com/block/buzz/releases/download/buzz-desktop-latest/latest.json
|
||||
@@ -629,7 +581,7 @@ jobs:
|
||||
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
|
||||
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
|
||||
|
||||
- name: Fix AppImage (remove infra libs, symlink system GStreamer)
|
||||
- name: Fix AppImage (remove infra libs, shim host GStreamer)
|
||||
run: |
|
||||
mapfile -t APPIMAGES < <(find desktop/src-tauri/target/release/bundle/appimage -name '*.AppImage' -type f)
|
||||
if [[ ${#APPIMAGES[@]} -eq 0 ]]; then
|
||||
@@ -689,29 +641,16 @@ jobs:
|
||||
SIG_PATH: ${{ steps.linux-artifacts.outputs.sig }}
|
||||
|
||||
# NOTE: .deb is NOT auto-updatable (Tauri updater constraint — only AppImage supports it on Linux)
|
||||
- name: Upload Linux artifacts to versioned GitHub release
|
||||
env:
|
||||
VERSION: ${{ needs.setup.outputs.version }}
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
DEB_PATH: ${{ steps.linux-artifacts.outputs.deb }}
|
||||
APPIMAGE_PATH: ${{ steps.linux-artifacts.outputs.appimage }}
|
||||
run: |
|
||||
gh release upload "v$VERSION" \
|
||||
"$DEB_PATH" \
|
||||
"$APPIMAGE_PATH" \
|
||||
--clobber
|
||||
|
||||
- name: Upload updater archive to rolling release
|
||||
if: github.ref == format('refs/tags/v{0}', needs.setup.outputs.version)
|
||||
run: |
|
||||
gh release upload buzz-desktop-latest \
|
||||
"$ARCHIVE_PATH" \
|
||||
"$SIG_PATH" \
|
||||
--clobber
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
ARCHIVE_PATH: ${{ steps.linux-artifacts.outputs.archive }}
|
||||
SIG_PATH: ${{ steps.linux-artifacts.outputs.sig }}
|
||||
- name: Stage Linux release artifacts
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
|
||||
with:
|
||||
name: desktop-release-linux-x64
|
||||
if-no-files-found: error
|
||||
path: |
|
||||
${{ steps.linux-artifacts.outputs.deb }}
|
||||
${{ steps.linux-artifacts.outputs.appimage }}
|
||||
${{ steps.linux-artifacts.outputs.archive }}
|
||||
${{ steps.linux-artifacts.outputs.sig }}
|
||||
|
||||
release-windows:
|
||||
name: Release Windows
|
||||
@@ -719,7 +658,7 @@ jobs:
|
||||
needs: setup
|
||||
timeout-minutes: 60
|
||||
permissions:
|
||||
contents: write
|
||||
contents: read
|
||||
outputs:
|
||||
archive_name: ${{ steps.artifacts.outputs.archive_name }}
|
||||
sig: ${{ steps.read-sig.outputs.sig }}
|
||||
@@ -727,7 +666,7 @@ jobs:
|
||||
VERSION: ${{ needs.setup.outputs.version }}
|
||||
TARGET: x86_64-pc-windows-msvc
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
ref: ${{ needs.setup.outputs.source_sha }}
|
||||
fetch-depth: 0
|
||||
@@ -735,7 +674,7 @@ jobs:
|
||||
|
||||
- name: Verify tag-bound release source
|
||||
shell: bash
|
||||
run: scripts/verify-release-ref.sh v "$VERSION"
|
||||
run: scripts/verify-release-ref.sh desktop-v "$VERSION"
|
||||
|
||||
- uses: dtolnay/rust-toolchain@e081816240890017053eacbb1bdf337761dc5582 # 1.95.0
|
||||
with:
|
||||
@@ -745,7 +684,7 @@ jobs:
|
||||
with:
|
||||
node-version: 24.14.1
|
||||
# Disable dependency caching: a writable cache in this release workflow
|
||||
# (contents: write, feeds a signed installer) is a poisoning vector. pnpm
|
||||
# (contents: read, feeds a signed installer) is a poisoning vector. pnpm
|
||||
# install runs uncached below.
|
||||
package-manager-cache: false
|
||||
|
||||
@@ -827,25 +766,14 @@ jobs:
|
||||
env:
|
||||
SIG_PATH: ${{ steps.artifacts.outputs.sig }}
|
||||
|
||||
- name: Upload Windows installer to versioned GitHub release
|
||||
shell: bash
|
||||
run: gh release upload "v${VERSION}" "$EXE_PATH" --clobber
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
EXE_PATH: ${{ steps.artifacts.outputs.exe }}
|
||||
|
||||
- name: Upload updater archive to rolling release
|
||||
if: github.ref == format('refs/tags/v{0}', needs.setup.outputs.version)
|
||||
shell: bash
|
||||
run: |
|
||||
gh release upload buzz-desktop-latest \
|
||||
"$ARCHIVE_PATH" \
|
||||
"$SIG_PATH" \
|
||||
--clobber
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
ARCHIVE_PATH: ${{ steps.artifacts.outputs.archive }}
|
||||
SIG_PATH: ${{ steps.artifacts.outputs.sig }}
|
||||
- name: Stage Windows release artifacts
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
|
||||
with:
|
||||
name: desktop-release-windows-x64
|
||||
if-no-files-found: error
|
||||
path: |
|
||||
${{ steps.artifacts.outputs.exe }}
|
||||
${{ steps.artifacts.outputs.sig }}
|
||||
|
||||
assemble-manifest:
|
||||
name: Assemble multi-platform latest.json
|
||||
@@ -853,7 +781,11 @@ jobs:
|
||||
if: |
|
||||
always() &&
|
||||
needs.setup.result == 'success' &&
|
||||
github.ref == format('refs/tags/v{0}', needs.setup.outputs.version)
|
||||
needs.release.result == 'success' &&
|
||||
needs.release-macos-x64.result == 'success' &&
|
||||
needs.release-linux.result == 'success' &&
|
||||
needs.release-windows.result == 'success' &&
|
||||
github.ref == format('refs/tags/desktop-v{0}', needs.setup.outputs.version)
|
||||
runs-on: ubuntu-latest
|
||||
needs: [setup, release, release-macos-x64, release-linux, release-windows]
|
||||
timeout-minutes: 10
|
||||
@@ -863,14 +795,33 @@ jobs:
|
||||
VERSION: ${{ needs.setup.outputs.version }}
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
ref: ${{ needs.setup.outputs.source_sha }}
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
|
||||
- name: Verify tag-bound release source
|
||||
run: scripts/verify-release-ref.sh v "$VERSION"
|
||||
run: scripts/verify-release-ref.sh desktop-v "$VERSION"
|
||||
|
||||
- name: Download staged release artifacts
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||
with:
|
||||
pattern: desktop-release-*
|
||||
path: staged-by-platform
|
||||
|
||||
- name: Flatten staged artifacts without basename collisions
|
||||
run: |
|
||||
set -euo pipefail
|
||||
mkdir staged
|
||||
while IFS= read -r -d '' file; do
|
||||
name="$(basename "$file")"
|
||||
[[ ! -e "staged/$name" ]] || {
|
||||
echo "::error::release artifact basename collision: $name"
|
||||
exit 1
|
||||
}
|
||||
cp "$file" "staged/$name"
|
||||
done < <(find staged-by-platform -type f -print0)
|
||||
|
||||
- name: Write signature files
|
||||
env:
|
||||
@@ -899,7 +850,7 @@ jobs:
|
||||
write_sig "$RESULT_LINUX" linux-x86_64 "$SIG_LINUX"
|
||||
write_sig "$RESULT_WIN" windows-x86_64 "$SIG_WIN"
|
||||
|
||||
- name: Verify archive URLs are accessible
|
||||
- name: Verify draft release has every updater archive
|
||||
env:
|
||||
RESULT_ARM64: ${{ needs.release.result }}
|
||||
RESULT_X64: ${{ needs.release-macos-x64.result }}
|
||||
@@ -911,39 +862,19 @@ jobs:
|
||||
ARCHIVE_WIN: ${{ needs.release-windows.outputs.archive_name }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
BASE="https://github.com/block/buzz/releases/download/buzz-desktop-latest"
|
||||
ARCHIVES=()
|
||||
|
||||
add_archive() {
|
||||
local result="$1" platform="$2" archive="$3"
|
||||
if [[ "$result" == "success" ]]; then
|
||||
[[ -n "$archive" ]] || { echo "::error::Missing archive name for successful platform: $platform"; exit 1; }
|
||||
ARCHIVES+=("$archive")
|
||||
fi
|
||||
}
|
||||
|
||||
add_archive "$RESULT_ARM64" darwin-aarch64 "$ARCHIVE_ARM64"
|
||||
add_archive "$RESULT_X64" darwin-x86_64 "$ARCHIVE_X64"
|
||||
add_archive "$RESULT_LINUX" linux-x86_64 "$ARCHIVE_LINUX"
|
||||
add_archive "$RESULT_WIN" windows-x86_64 "$ARCHIVE_WIN"
|
||||
|
||||
for name in "${ARCHIVES[@]}"; do
|
||||
echo "Checking $BASE/$name ..."
|
||||
success=false
|
||||
for attempt in 1 2 3; do
|
||||
if curl -fsI "$BASE/$name" > /dev/null 2>&1; then
|
||||
success=true
|
||||
break
|
||||
fi
|
||||
echo "Attempt $attempt failed for $name, retrying in 10s..."
|
||||
sleep 10
|
||||
done
|
||||
if [ "$success" != "true" ]; then
|
||||
echo "::error::Archive not accessible after 3 attempts: $BASE/$name"
|
||||
exit 1
|
||||
assets=$(find staged -type f -exec basename {} \;)
|
||||
for spec in \
|
||||
"$RESULT_ARM64:$ARCHIVE_ARM64" \
|
||||
"$RESULT_X64:$ARCHIVE_X64" \
|
||||
"$RESULT_LINUX:$ARCHIVE_LINUX" \
|
||||
"$RESULT_WIN:$ARCHIVE_WIN"; do
|
||||
result="${spec%%:*}"
|
||||
archive="${spec#*:}"
|
||||
if [[ "$result" == success ]]; then
|
||||
[[ -n "$archive" ]] || { echo "::error::successful platform has no archive"; exit 1; }
|
||||
grep -Fxq "$archive" <<<"$assets" || { echo "::error::draft release missing $archive"; exit 1; }
|
||||
fi
|
||||
done
|
||||
echo "All archive URLs verified."
|
||||
|
||||
- name: Generate unified latest.json
|
||||
env:
|
||||
@@ -957,7 +888,7 @@ jobs:
|
||||
ARCHIVE_WIN: ${{ needs.release-windows.outputs.archive_name }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
BASE="https://github.com/block/buzz/releases/download/buzz-desktop-latest"
|
||||
BASE="https://github.com/block/buzz/releases/download/desktop-v${VERSION}"
|
||||
TRIPLES=()
|
||||
|
||||
add_triple() {
|
||||
@@ -977,6 +908,45 @@ jobs:
|
||||
bash desktop/scripts/generate-oss-latest-json.sh "$VERSION" "${TRIPLES[@]}" > latest.json
|
||||
cat latest.json
|
||||
|
||||
- name: Upload latest.json to rolling release
|
||||
- name: Create or verify versioned draft
|
||||
run: |
|
||||
gh release upload buzz-desktop-latest latest.json --clobber
|
||||
set -euo pipefail
|
||||
NOTES_FILE="${RUNNER_TEMP}/release-notes.md"
|
||||
awk "/^## v${VERSION}\$/{found=1; next} found && /^## v/{exit} found" CHANGELOG.md > "$NOTES_FILE"
|
||||
[[ -s "$NOTES_FILE" ]] || { echo "::error::missing non-empty changelog block for v${VERSION}"; exit 1; }
|
||||
PRERELEASE_FLAGS=()
|
||||
if [[ "$VERSION" == *-* ]]; then
|
||||
PRERELEASE_FLAGS=(--prerelease --latest=false)
|
||||
fi
|
||||
if gh release view "desktop-v${VERSION}" >/dev/null 2>&1; then
|
||||
EXISTING_SHA=$(gh release view "desktop-v${VERSION}" --json targetCommitish --jq .targetCommitish)
|
||||
IS_DRAFT=$(gh release view "desktop-v${VERSION}" --json isDraft --jq .isDraft)
|
||||
[[ "$EXISTING_SHA" == "${{ needs.setup.outputs.source_sha }}" ]] || {
|
||||
echo "::error::existing release targets $EXISTING_SHA, not the immutable source"; exit 1;
|
||||
}
|
||||
if [[ "$IS_DRAFT" != true ]]; then
|
||||
echo "already_published=true" >> "$GITHUB_ENV"
|
||||
fi
|
||||
else
|
||||
gh release create "desktop-v${VERSION}" \
|
||||
--draft \
|
||||
--target "${{ needs.setup.outputs.source_sha }}" \
|
||||
--title "Buzz Desktop v${VERSION}" \
|
||||
--notes-file "$NOTES_FILE" \
|
||||
"${PRERELEASE_FLAGS[@]}"
|
||||
fi
|
||||
|
||||
- name: Upload complete artifact set to versioned draft
|
||||
if: env.already_published != 'true'
|
||||
run: |
|
||||
mapfile -t files < <(find staged -type f -print)
|
||||
[[ "${#files[@]}" -gt 0 ]] || { echo "::error::no staged release artifacts"; exit 1; }
|
||||
gh release upload "desktop-v${VERSION}" "${files[@]}" --clobber
|
||||
|
||||
- name: Publish complete versioned release
|
||||
if: env.already_published != 'true'
|
||||
run: gh release edit "desktop-v${VERSION}" --draft=false
|
||||
|
||||
- name: Upload latest.json to rolling release last
|
||||
if: ${{ !contains(needs.setup.outputs.version, '-') }}
|
||||
run: gh release upload buzz-desktop-latest latest.json --clobber
|
||||
|
||||
62
.github/workflows/signed-macos-canary.yml
vendored
62
.github/workflows/signed-macos-canary.yml
vendored
@@ -34,16 +34,6 @@ jobs:
|
||||
|
||||
- uses: cashapp/activate-hermit@cea9af7913204a965fd488637a8d1811bba2e616 # v1
|
||||
|
||||
# Rust cache covering both the workspace sidecar build and the Tauri
|
||||
# crate build. shared-key scoped to macos-canary-release so canary runs
|
||||
# warm each other without colliding with CI's debug-profile keys.
|
||||
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
|
||||
with:
|
||||
workspaces: |
|
||||
.
|
||||
desktop/src-tauri
|
||||
shared-key: macos-canary-release
|
||||
|
||||
- name: Get pnpm store directory
|
||||
id: pnpm-cache
|
||||
run: echo "STORE_PATH=$(pnpm store path --silent)" >> "$GITHUB_OUTPUT"
|
||||
@@ -78,6 +68,38 @@ jobs:
|
||||
cd desktop && node scripts/set-version-from-tag.mjs "$VERSION"
|
||||
cd src-tauri && cargo update --workspace
|
||||
|
||||
- name: Resolve native toolchain identity
|
||||
id: native_toolchain
|
||||
run: echo "id=$(scripts/desktop-native-toolchain-id.sh macos)" >> "$GITHUB_OUTPUT"
|
||||
|
||||
# Compute this after cargo update so the key describes the graph that is
|
||||
# actually compiled. The helper normalizes only Buzz Desktop's release
|
||||
# version, allowing a canary to warm an otherwise identical tag build.
|
||||
- name: Compute exact release cache key
|
||||
id: rust_cache_key
|
||||
env:
|
||||
NATIVE_TOOLCHAIN_ID: ${{ steps.native_toolchain.outputs.id }}
|
||||
run: |
|
||||
KEY=$(scripts/desktop-release-cache-key.py \
|
||||
--platform "$RUNNER_OS" \
|
||||
--target aarch64-apple-darwin \
|
||||
--features mesh-llm \
|
||||
--native-inputs "$NATIVE_TOOLCHAIN_ID")
|
||||
echo "key=$KEY" >> "$GITHUB_OUTPUT"
|
||||
echo "Release cache key: $KEY"
|
||||
|
||||
- name: Restore exact release Cargo cache
|
||||
id: rust_cache
|
||||
uses: actions/cache/restore@caa296126883cff596d87d8935842f9db880ef25 # v5
|
||||
with:
|
||||
path: |
|
||||
~/.cargo/registry
|
||||
~/.cargo/git
|
||||
target
|
||||
desktop/src-tauri/target
|
||||
!desktop/src-tauri/target/**/release/bundle
|
||||
key: ${{ steps.rust_cache_key.outputs.key }}
|
||||
|
||||
- name: Generate non-updating bundle config
|
||||
run: |
|
||||
cat > desktop/src-tauri/tauri.canary.conf.json <<'JSON'
|
||||
@@ -93,7 +115,7 @@ jobs:
|
||||
|
||||
- name: Build sidecars
|
||||
run: |
|
||||
cargo build --release -p buzz-acp -p buzz-agent -p buzz-dev-mcp -p git-credential-nostr -p buzz-cli
|
||||
cargo build --release -p buzz-acp -p buzz-agent -p buzz-backend-kubernetes -p buzz-dev-mcp -p git-credential-nostr -p buzz-cli
|
||||
./scripts/bundle-sidecars.sh
|
||||
|
||||
# Mesh rev derived from Cargo.lock (no lockstep edit on dep bump); cache key tracks it.
|
||||
@@ -210,6 +232,24 @@ jobs:
|
||||
if-no-files-found: error
|
||||
retention-days: 7
|
||||
|
||||
- name: Measure release Cargo cache inputs
|
||||
if: always()
|
||||
run: du -sh ~/.cargo/registry ~/.cargo/git target desktop/src-tauri/target 2>/dev/null || true
|
||||
|
||||
# Only this trusted, main-bound canary writes the cache. Excluding bundle
|
||||
# output prevents installers or signed artifacts from entering it.
|
||||
- name: Save exact release Cargo cache
|
||||
if: steps.rust_cache.outputs.cache-hit != 'true'
|
||||
uses: actions/cache/save@caa296126883cff596d87d8935842f9db880ef25 # v5
|
||||
with:
|
||||
path: |
|
||||
~/.cargo/registry
|
||||
~/.cargo/git
|
||||
target
|
||||
desktop/src-tauri/target
|
||||
!desktop/src-tauri/target/**/release/bundle
|
||||
key: ${{ steps.rust_cache_key.outputs.key }}
|
||||
|
||||
- name: Save pnpm store cache
|
||||
uses: actions/cache/save@caa296126883cff596d87d8935842f9db880ef25 # v5
|
||||
with:
|
||||
|
||||
233
.github/workflows/sprig-image.yml
vendored
Normal file
233
.github/workflows/sprig-image.yml
vendored
Normal file
@@ -0,0 +1,233 @@
|
||||
name: Sprig image
|
||||
|
||||
# Builds and publishes the public agent container image as
|
||||
# ghcr.io/block/buzz-sprig — the digest-pinned box the Kubernetes backend
|
||||
# deploys agents into (see Dockerfile.sprig and docs/remote-agents.md).
|
||||
#
|
||||
# Strategy mirrors docker.yml (the relay image): each architecture builds on
|
||||
# its native runner, pushes to GHCR by digest, then a merge job stitches the
|
||||
# per-arch digests into one multi-arch manifest and attests provenance.
|
||||
# No QEMU emulation.
|
||||
#
|
||||
# Triggers:
|
||||
# - push to main (paths-filtered) → :main + :sha-<7>
|
||||
# - tag sprig-v* → semver family (shared with sprig.yml's
|
||||
# binary release — one tag versions both)
|
||||
# - pull_request (paths-filtered) → build only, no push
|
||||
# - workflow_dispatch → manual publish at the current ref
|
||||
#
|
||||
# NOTE: the first push creates the GHCR package PRIVATE by default. An org
|
||||
# admin must flip ghcr.io/block/buzz-sprig to public once (Package settings →
|
||||
# Change visibility). Subsequent pushes keep the visibility.
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
tags: ["sprig-v[0-9]*"]
|
||||
paths:
|
||||
- "Dockerfile.sprig"
|
||||
- "scripts/sprig-entrypoint.sh"
|
||||
- ".github/workflows/sprig-image.yml"
|
||||
- "Cargo.toml"
|
||||
- "Cargo.lock"
|
||||
- "rust-toolchain.toml"
|
||||
- "crates/**"
|
||||
pull_request:
|
||||
paths:
|
||||
- "Dockerfile.sprig"
|
||||
- "scripts/sprig-entrypoint.sh"
|
||||
- ".github/workflows/sprig-image.yml"
|
||||
workflow_dispatch: {}
|
||||
|
||||
concurrency:
|
||||
group: sprig-image-${{ github.ref }}
|
||||
cancel-in-progress: ${{ github.ref_type == 'branch' && github.event_name == 'pull_request' }}
|
||||
|
||||
permissions: {}
|
||||
|
||||
env:
|
||||
# Single source of truth for the image name; override with the
|
||||
# GHCR_SPRIG_IMAGE repo variable (same pattern as docker.yml).
|
||||
IMAGE_NAME: ${{ vars.GHCR_SPRIG_IMAGE != '' && vars.GHCR_SPRIG_IMAGE || 'ghcr.io/block/buzz-sprig' }}
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build (${{ matrix.platform }})
|
||||
runs-on: ${{ matrix.runner }}
|
||||
timeout-minutes: 60
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
id-token: write
|
||||
attestations: 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
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0
|
||||
with:
|
||||
# Same OOM cap as docker.yml — Rust compiles blow the 7GB runner
|
||||
# at buildkit's default parallelism of 4.
|
||||
buildkitd-config-inline: |
|
||||
[worker.oci]
|
||||
max-parallelism = 2
|
||||
|
||||
- name: Log in to GHCR
|
||||
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
|
||||
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 }}
|
||||
# match=^sprig-v(.*)$ strips the tag prefix for the semver parser,
|
||||
# exactly as docker.yml does for relay-v. :latest comes from
|
||||
# flavor.latest=auto — stable semver only, never main pushes.
|
||||
tags: |
|
||||
type=ref,event=branch
|
||||
type=sha,prefix=sha-,format=short
|
||||
type=semver,pattern={{version}},match=^sprig-v(.*)$
|
||||
type=semver,pattern={{major}}.{{minor}},match=^sprig-v(.*)$
|
||||
labels: |
|
||||
org.opencontainers.image.title=Buzz Sprig
|
||||
org.opencontainers.image.description=Agent runtime image for Buzz remote agents (buzz-acp multicall + git + curl)
|
||||
org.opencontainers.image.licenses=Apache-2.0
|
||||
|
||||
- name: Build and push by digest
|
||||
id: build
|
||||
uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7.2.0
|
||||
with:
|
||||
context: .
|
||||
file: ./Dockerfile.sprig
|
||||
platforms: ${{ matrix.platform }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
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 }}
|
||||
cache-to: |
|
||||
${{ (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository) && format('type=registry,ref={0}-buildcache:{1},mode=max,compression=zstd', env.IMAGE_NAME, matrix.arch) || '' }}
|
||||
|
||||
- name: Export digest
|
||||
if: github.event_name != 'pull_request'
|
||||
env:
|
||||
DIGEST: ${{ steps.build.outputs.digest }}
|
||||
run: |
|
||||
mkdir -p /tmp/digests
|
||||
touch "/tmp/digests/${DIGEST#sha256:}"
|
||||
|
||||
- name: Upload digest
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
with:
|
||||
name: sprig-digest-${{ matrix.arch }}
|
||||
path: /tmp/digests/*
|
||||
if-no-files-found: error
|
||||
retention-days: 1
|
||||
|
||||
merge:
|
||||
name: Merge multi-arch manifest
|
||||
if: github.event_name != 'pull_request'
|
||||
runs-on: ubuntu-24.04
|
||||
needs: build
|
||||
timeout-minutes: 15
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
id-token: write
|
||||
attestations: write
|
||||
|
||||
steps:
|
||||
- name: Download per-arch digests
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||
with:
|
||||
path: /tmp/digests
|
||||
pattern: sprig-digest-*
|
||||
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: Extract metadata
|
||||
id: meta
|
||||
uses: docker/metadata-action@80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9 # v6.1.0
|
||||
with:
|
||||
images: ${{ env.IMAGE_NAME }}
|
||||
# Must mirror the build job's tag matrix exactly (see docker.yml).
|
||||
flavor: |
|
||||
latest=auto
|
||||
tags: |
|
||||
type=ref,event=branch
|
||||
type=sha,prefix=sha-,format=short
|
||||
type=semver,pattern={{version}},match=^sprig-v(.*)$
|
||||
type=semver,pattern={{major}}.{{minor}},match=^sprig-v(.*)$
|
||||
|
||||
- name: Create and push manifest list
|
||||
id: manifest
|
||||
working-directory: /tmp/digests
|
||||
env:
|
||||
IMAGE_NAME: ${{ env.IMAGE_NAME }}
|
||||
META_TAGS: ${{ steps.meta.outputs.tags }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
tags=()
|
||||
while IFS= read -r tag; do
|
||||
[ -n "$tag" ] && tags+=("-t" "$tag")
|
||||
done <<< "$META_TAGS"
|
||||
|
||||
digests=()
|
||||
for digest in *; do
|
||||
digests+=("${IMAGE_NAME}@sha256:${digest}")
|
||||
done
|
||||
|
||||
docker buildx imagetools create "${tags[@]}" "${digests[@]}"
|
||||
|
||||
first_tag=$(echo "$META_TAGS" | head -n1)
|
||||
merged_digest=$(docker buildx imagetools inspect "$first_tag" \
|
||||
--format '{{json .Manifest}}' | jq -r '.digest')
|
||||
echo "digest=${merged_digest}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Attest provenance for the merged image
|
||||
# Verify with: gh attestation verify oci://ghcr.io/block/buzz-sprig:<tag> --owner block
|
||||
uses: actions/attest-build-provenance@0f67c3f4856b2e3261c31976d6725780e5e4c373 # v4.1.1
|
||||
with:
|
||||
subject-name: ${{ env.IMAGE_NAME }}
|
||||
subject-digest: ${{ steps.manifest.outputs.digest }}
|
||||
push-to-registry: true
|
||||
|
||||
- name: Summary
|
||||
env:
|
||||
IMAGE_NAME: ${{ env.IMAGE_NAME }}
|
||||
DIGEST: ${{ steps.manifest.outputs.digest }}
|
||||
run: |
|
||||
{
|
||||
echo "### Sprig image published"
|
||||
echo '```'
|
||||
echo "${IMAGE_NAME}@${DIGEST}"
|
||||
echo '```'
|
||||
} >> "$GITHUB_STEP_SUMMARY"
|
||||
6
.github/workflows/sprig.yml
vendored
6
.github/workflows/sprig.yml
vendored
@@ -42,7 +42,7 @@ jobs:
|
||||
- x86_64-unknown-linux-musl
|
||||
- aarch64-unknown-linux-musl
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
|
||||
- uses: cashapp/activate-hermit@cea9af7913204a965fd488637a8d1811bba2e616 # v1
|
||||
|
||||
@@ -116,7 +116,7 @@ jobs:
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
|
||||
- name: Download all Sprig artifacts
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||
@@ -154,7 +154,7 @@ jobs:
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
|
||||
- name: Download all Sprig artifacts
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||
|
||||
68
.github/workflows/windows-canary.yml
vendored
68
.github/workflows/windows-canary.yml
vendored
@@ -46,24 +46,9 @@ jobs:
|
||||
shell: bash
|
||||
run: rustup target add "$TARGET"
|
||||
|
||||
# Rust cache covering both the workspace sidecar build and the Tauri
|
||||
# crate build. shared-key scoped to windows-canary-release so canary
|
||||
# runs warm each other without colliding with CI's debug-profile key
|
||||
# (CI windows job does clippy/check, not --release).
|
||||
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
|
||||
with:
|
||||
workspaces: |
|
||||
.
|
||||
desktop/src-tauri
|
||||
shared-key: windows-canary-release
|
||||
|
||||
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
||||
with:
|
||||
node-version: 24.14.1
|
||||
# Disable setup-node's built-in cache: we manage the pnpm store cache
|
||||
# explicitly below (restore before install, save after) to mirror the
|
||||
# pattern used by ci.yml and to keep caching logic consistent across
|
||||
# all three canary workflows.
|
||||
package-manager-cache: false
|
||||
|
||||
- uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4.3.0
|
||||
@@ -108,6 +93,40 @@ jobs:
|
||||
cd desktop && node scripts/set-version-from-tag.mjs "$VERSION"
|
||||
cd src-tauri && cargo update --workspace
|
||||
|
||||
- name: Resolve native toolchain identity
|
||||
id: native_toolchain
|
||||
shell: bash
|
||||
run: echo "id=$(scripts/desktop-native-toolchain-id.sh windows)" >> "$GITHUB_OUTPUT"
|
||||
|
||||
# Compute this after cargo update so the key describes the graph that is
|
||||
# actually compiled. The helper normalizes only Buzz Desktop's release
|
||||
# version, allowing a canary to warm an otherwise identical tag build.
|
||||
- name: Compute exact release cache key
|
||||
id: rust_cache_key
|
||||
shell: bash
|
||||
env:
|
||||
NATIVE_TOOLCHAIN_ID: ${{ steps.native_toolchain.outputs.id }}
|
||||
run: |
|
||||
KEY=$(scripts/desktop-release-cache-key.py \
|
||||
--platform "$RUNNER_OS" \
|
||||
--target x86_64-pc-windows-msvc \
|
||||
--features default \
|
||||
--native-inputs "$NATIVE_TOOLCHAIN_ID")
|
||||
echo "key=$KEY" >> "$GITHUB_OUTPUT"
|
||||
echo "Release cache key: $KEY"
|
||||
|
||||
- name: Restore exact release Cargo cache
|
||||
id: rust_cache
|
||||
uses: actions/cache/restore@caa296126883cff596d87d8935842f9db880ef25 # v5
|
||||
with:
|
||||
path: |
|
||||
~/.cargo/registry
|
||||
~/.cargo/git
|
||||
target
|
||||
desktop/src-tauri/target
|
||||
!desktop/src-tauri/target/**/release/bundle
|
||||
key: ${{ steps.rust_cache_key.outputs.key }}
|
||||
|
||||
- name: Generate non-updating bundle config
|
||||
shell: bash
|
||||
run: |
|
||||
@@ -152,6 +171,25 @@ jobs:
|
||||
if-no-files-found: error
|
||||
retention-days: 7
|
||||
|
||||
- name: Measure release Cargo cache inputs
|
||||
if: always()
|
||||
shell: bash
|
||||
run: du -sh ~/.cargo/registry ~/.cargo/git target desktop/src-tauri/target 2>/dev/null || true
|
||||
|
||||
# Only this trusted, main-bound canary writes the cache. Excluding bundle
|
||||
# output prevents installers from entering it.
|
||||
- name: Save exact release Cargo cache
|
||||
if: steps.rust_cache.outputs.cache-hit != 'true'
|
||||
uses: actions/cache/save@caa296126883cff596d87d8935842f9db880ef25 # v5
|
||||
with:
|
||||
path: |
|
||||
~/.cargo/registry
|
||||
~/.cargo/git
|
||||
target
|
||||
desktop/src-tauri/target
|
||||
!desktop/src-tauri/target/**/release/bundle
|
||||
key: ${{ steps.rust_cache_key.outputs.key }}
|
||||
|
||||
- name: Save pnpm store cache
|
||||
uses: actions/cache/save@caa296126883cff596d87d8935842f9db880ef25 # v5
|
||||
with:
|
||||
|
||||
Reference in New Issue
Block a user