mirror of
https://github.com/block/buzz.git
synced 2026-11-07 18:01:06 +00:00
Merge remote-tracking branch 'origin/main' into micn/bundled-goose-acp
* origin/main: (291 commits) fix(desktop): allow editing built-in agents (#1928) fix(desktop): load downloaded mesh runtime on signed macOS builds (#1932) feat(media): require auth for relay media reads (#1926) fix(desktop): remove superseded built-in agents (#1929) Move agent AI defaults into Settings (#1919) feat(desktop): add Honey and Bumble starter agents (#1925) feat(desktop): expand owned team mentions (#1918) Fix live agent reactions in Inbox and channels (#1921) refactor(desktop): unify page/section header hierarchy across Agents and Settings (#1912) chore(release): release Buzz Desktop version 0.4.6 (#1911) fix(desktop): restore chat-first agent creation after mesh rebase (#1909) feat(relay): add community unarchive endpoint (#1908) Polish agent and team sharing and snapshots (#1852) fix(buzz-acp): distinguish cancel-drain expiry from real hard-cap timeout (#1893) fix(desktop): filter punctuation from avatar initials (#1904) fix(desktop): preserve snapshot attachment URLs (#1905) Chat-first agent creation via portable buzz CLI drafts (#1878) feat(desktop): enable community rail by default (#1902) feat(desktop): redesign Nostr bind verification flow (#1850) fix(desktop): simplify sign out settings row (#1903) ...
This commit is contained in:
@@ -1,11 +1,15 @@
|
||||
name: Auto-tag on Release PR Merge
|
||||
|
||||
# Four release lanes share this one workflow — adding a lane is one more branch
|
||||
# prefix, never a forked copy:
|
||||
# Five release lanes share this one workflow. Four use an explicit branch
|
||||
# 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> → dispatch release.yml (desktop app)
|
||||
# relay-release/<v> → tag relay-v<v> → dispatch docker.yml (relay image)
|
||||
# chart-release/<v> → tag chart-v<v> → dispatch helm-chart.yml (helm chart)
|
||||
# chart-release/<v> → tag chart-v<v> → dispatch helm-chart.yml (main helm chart)
|
||||
# push-chart-release/<v> → tag push-chart-v<v> → dispatch push-gateway-helm-chart.yml
|
||||
# any internal PR that bumps deploy/charts/buzz/Chart.yaml `version`
|
||||
# → tag chart-v<v> → dispatch helm-chart.yml (helm chart)
|
||||
# mobile-release/<v> → tag mobile-v<v> → (manual sprout_ref for buzz-releases build — see below)
|
||||
#
|
||||
# The desktop, relay, and chart lanes dispatch their build workflow rather than
|
||||
@@ -36,10 +40,6 @@ jobs:
|
||||
auto-tag:
|
||||
if: >
|
||||
github.event.pull_request.merged == true &&
|
||||
(startsWith(github.event.pull_request.head.ref, 'version-bump/') ||
|
||||
startsWith(github.event.pull_request.head.ref, 'relay-release/') ||
|
||||
startsWith(github.event.pull_request.head.ref, 'chart-release/') ||
|
||||
startsWith(github.event.pull_request.head.ref, 'mobile-release/')) &&
|
||||
github.event.pull_request.head.repo.full_name == github.repository
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
@@ -48,12 +48,14 @@ jobs:
|
||||
ref: ${{ github.event.pull_request.merge_commit_sha }}
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Resolve lane and version from branch name
|
||||
- name: Resolve release lane and version
|
||||
id: release
|
||||
env:
|
||||
BRANCH: ${{ github.event.pull_request.head.ref }}
|
||||
run: |
|
||||
# Lane is decided by branch prefix: the tag prefix and whether a
|
||||
# downstream workflow_dispatch is needed both follow from it.
|
||||
# Explicit release branches retain their established behavior. For an
|
||||
# ordinary internal PR, publish only when Chart.yaml itself changed
|
||||
# and its version differs from the PR's base commit.
|
||||
case "$BRANCH" in
|
||||
version-bump/*)
|
||||
VERSION="${BRANCH#version-bump/}"
|
||||
@@ -67,26 +69,42 @@ jobs:
|
||||
VERSION="${BRANCH#chart-release/}"
|
||||
TAG_PREFIX="chart-v"
|
||||
DISPATCH="helm-chart" ;;
|
||||
push-chart-release/*)
|
||||
VERSION="${BRANCH#push-chart-release/}"
|
||||
TAG_PREFIX="push-chart-v"
|
||||
DISPATCH="push-gateway-helm-chart" ;;
|
||||
mobile-release/*)
|
||||
VERSION="${BRANCH#mobile-release/}"
|
||||
TAG_PREFIX="mobile-v"
|
||||
DISPATCH="" ;;
|
||||
*)
|
||||
echo "::error::Unhandled branch prefix: '$BRANCH'"
|
||||
exit 1 ;;
|
||||
parent_sha="$(git rev-parse HEAD^)"
|
||||
old_version="$(git show "${parent_sha}:deploy/charts/buzz/Chart.yaml" 2>/dev/null | awk '/^version:/ {print $2}')"
|
||||
VERSION="$(awk '/^version:/ {print $2}' deploy/charts/buzz/Chart.yaml)"
|
||||
if [ -z "$old_version" ] || [ -z "$VERSION" ] || [ "$old_version" = "$VERSION" ]; then
|
||||
echo "No release branch or chart version bump — nothing to tag"
|
||||
echo "enabled=false" >> "$GITHUB_OUTPUT"
|
||||
exit 0
|
||||
fi
|
||||
TAG_PREFIX="chart-v"
|
||||
DISPATCH="helm-chart" ;;
|
||||
esac
|
||||
if ! echo "$VERSION" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?$'; then
|
||||
echo "::error::Invalid version in branch name: '$VERSION'"
|
||||
echo "::error::Invalid release version: '$VERSION'"
|
||||
exit 1
|
||||
fi
|
||||
echo "version=$VERSION" >> "$GITHUB_ENV"
|
||||
echo "tag=${TAG_PREFIX}${VERSION}" >> "$GITHUB_ENV"
|
||||
echo "dispatch=$DISPATCH" >> "$GITHUB_ENV"
|
||||
{
|
||||
echo "enabled=true"
|
||||
echo "version=$VERSION"
|
||||
echo "tag=${TAG_PREFIX}${VERSION}"
|
||||
echo "dispatch=$DISPATCH"
|
||||
} >> "$GITHUB_OUTPUT"
|
||||
echo "Tagging ${TAG_PREFIX}${VERSION}"
|
||||
|
||||
- name: Create and push tag
|
||||
if: steps.release.outputs.enabled == 'true'
|
||||
env:
|
||||
TAG: ${{ env.tag }}
|
||||
TAG: ${{ steps.release.outputs.tag }}
|
||||
run: |
|
||||
EXISTING_SHA="$(git ls-remote --tags origin "refs/tags/$TAG" | awk '{print $1}')"
|
||||
if [ -n "$EXISTING_SHA" ]; then
|
||||
@@ -104,16 +122,16 @@ jobs:
|
||||
git push origin "$TAG"
|
||||
|
||||
- name: Trigger release build
|
||||
# The desktop and relay lanes dispatch their build workflow because the
|
||||
# consumer's on:push:tags trigger is dead for auto-pushed tags (default
|
||||
# GITHUB_TOKEN, recursion guard — see header comment). Mobile has no
|
||||
# The desktop, relay, and chart lanes dispatch their build workflow
|
||||
# because the consumer's on:push:tags trigger is dead for tags pushed
|
||||
# by GITHUB_TOKEN (recursion guard — see header comment). Mobile has no
|
||||
# consumer yet, so dispatch="" skips this step entirely.
|
||||
if: ${{ env.dispatch != '' }}
|
||||
if: steps.release.outputs.enabled == 'true' && steps.release.outputs.dispatch != ''
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
DISPATCH: ${{ env.dispatch }}
|
||||
VERSION: ${{ env.version }}
|
||||
TAG: ${{ env.tag }}
|
||||
DISPATCH: ${{ steps.release.outputs.dispatch }}
|
||||
VERSION: ${{ steps.release.outputs.version }}
|
||||
TAG: ${{ steps.release.outputs.tag }}
|
||||
run: |
|
||||
# Both workflows take the bare version (for the build) and the tag ref
|
||||
# (so the dispatch builds the tagged commit, not main).
|
||||
@@ -121,6 +139,7 @@ jobs:
|
||||
release) WORKFLOW="release.yml" ;;
|
||||
docker) WORKFLOW="docker.yml" ;;
|
||||
helm-chart) WORKFLOW="helm-chart.yml" ;;
|
||||
push-gateway-helm-chart) WORKFLOW="push-gateway-helm-chart.yml" ;;
|
||||
*)
|
||||
echo "::error::Unhandled dispatch target: '$DISPATCH'"
|
||||
exit 1 ;;
|
||||
|
||||
39
.github/workflows/benchmark-harbor.yml
vendored
Normal file
39
.github/workflows/benchmark-harbor.yml
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
name: Harbor Buzz Orchestra
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
paths:
|
||||
- "benchmarks/harbor-buzz-orchestra/**"
|
||||
- ".github/workflows/benchmark-harbor.yml"
|
||||
pull_request:
|
||||
paths:
|
||||
- "benchmarks/harbor-buzz-orchestra/**"
|
||||
- ".github/workflows/benchmark-harbor.yml"
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
test:
|
||||
name: Python tests and lint
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
|
||||
with:
|
||||
python-version: "3.12"
|
||||
cache: pip
|
||||
- name: Test adapter
|
||||
working-directory: benchmarks/harbor-buzz-orchestra
|
||||
run: |
|
||||
python -m pip install --disable-pip-version-check -e ".[dev]"
|
||||
pytest -q
|
||||
ruff check .
|
||||
- name: Test provisioner
|
||||
working-directory: benchmarks/harbor-buzz-orchestra/testbed
|
||||
run: |
|
||||
python -m pip install --disable-pip-version-check -e ".[dev]"
|
||||
pytest -q
|
||||
ruff check .
|
||||
25
.github/workflows/ci.yml
vendored
25
.github/workflows/ci.yml
vendored
@@ -54,6 +54,7 @@ jobs:
|
||||
- 'pnpm-lock.yaml'
|
||||
mobile:
|
||||
- 'mobile/**'
|
||||
- '.github/workflows/ci.yml'
|
||||
|
||||
rust-lint:
|
||||
name: Rust Lint
|
||||
@@ -156,6 +157,10 @@ jobs:
|
||||
run: just desktop-test
|
||||
- name: Desktop build
|
||||
run: just desktop-build
|
||||
- name: Desktop Tauri clippy
|
||||
run: just desktop-tauri-clippy
|
||||
env:
|
||||
CMAKE_POLICY_VERSION_MINIMUM: "3.5"
|
||||
- name: Desktop Tauri check
|
||||
run: just desktop-tauri-check
|
||||
env:
|
||||
@@ -230,15 +235,21 @@ jobs:
|
||||
run: just desktop-build
|
||||
- name: Desktop smoke e2e
|
||||
run: cd desktop && pnpm exec playwright test --project=smoke --shard=${{ matrix.shard }}/4
|
||||
- name: Summarize flaky tests
|
||||
if: ${{ !cancelled() }}
|
||||
run: node scripts/summarize-flaky-tests.mjs playwright-report.json "Desktop Smoke E2E (${{ matrix.shard }})"
|
||||
working-directory: desktop
|
||||
- name: Upload desktop smoke e2e artifacts
|
||||
if: failure()
|
||||
if: ${{ !cancelled() }}
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
|
||||
with:
|
||||
name: desktop-smoke-e2e-artifacts-${{ matrix.shard }}
|
||||
path: |
|
||||
desktop/playwright-report
|
||||
desktop/playwright-report.json
|
||||
desktop/test-results
|
||||
if-no-files-found: ignore
|
||||
retention-days: 7
|
||||
|
||||
desktop:
|
||||
name: Desktop
|
||||
@@ -439,16 +450,22 @@ jobs:
|
||||
run: bash scripts/setup-desktop-test-data.sh
|
||||
- name: Desktop relay-backed e2e
|
||||
run: cd desktop && pnpm exec playwright test --project=integration --shard=${{ matrix.shard }}/2
|
||||
- name: Summarize flaky tests
|
||||
if: ${{ !cancelled() }}
|
||||
run: node scripts/summarize-flaky-tests.mjs playwright-report.json "Desktop E2E Integration (${{ matrix.shard }}/2)"
|
||||
working-directory: desktop
|
||||
- name: Upload desktop integration artifacts
|
||||
if: failure()
|
||||
if: ${{ !cancelled() }}
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
|
||||
with:
|
||||
name: desktop-e2e-integration-artifacts-${{ matrix.shard }}
|
||||
path: |
|
||||
desktop/playwright-report
|
||||
desktop/playwright-report.json
|
||||
desktop/test-results
|
||||
/tmp/buzz-relay.log
|
||||
if-no-files-found: ignore
|
||||
retention-days: 7
|
||||
- name: Save pnpm store cache
|
||||
if: github.event_name == 'push'
|
||||
uses: actions/cache/save@caa296126883cff596d87d8935842f9db880ef25 # v5
|
||||
@@ -718,6 +735,8 @@ jobs:
|
||||
run: cd mobile && flutter analyze
|
||||
- name: Test
|
||||
run: cd mobile && flutter test
|
||||
- name: Build Android debug APK
|
||||
run: just mobile-build-android
|
||||
|
||||
security:
|
||||
name: Security
|
||||
@@ -911,7 +930,7 @@ jobs:
|
||||
id: mesh_rev
|
||||
run: |
|
||||
set -euo pipefail
|
||||
REV=$(grep -oE 'mesh-llm\.git\?rev=[0-9a-f]{40}' Cargo.lock | head -1 | grep -oE '[0-9a-f]{40}')
|
||||
REV=$(python3 -c 'import tomllib; d=tomllib.load(open("Cargo.lock", "rb")); p=next(p for p in d["package"] if p["name"] == "mesh-llm-sdk"); print(p["source"].rsplit("#", 1)[1])')
|
||||
[[ -n "$REV" ]] || { echo "::error::could not resolve mesh-llm rev from Cargo.lock"; exit 1; }
|
||||
echo "rev=$REV" >> "$GITHUB_OUTPUT"
|
||||
echo "short=${REV:0:7}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
148
.github/workflows/docker.yml
vendored
148
.github/workflows/docker.yml
vendored
@@ -47,6 +47,7 @@ on:
|
||||
pull_request:
|
||||
paths:
|
||||
- "Dockerfile"
|
||||
- "Dockerfile.push-gateway"
|
||||
- ".dockerignore"
|
||||
- ".github/workflows/docker.yml"
|
||||
- "Cargo.toml"
|
||||
@@ -304,3 +305,150 @@ jobs:
|
||||
echo "gh attestation verify oci://${IMAGE_NAME}@${MERGED_DIGEST} --owner block"
|
||||
echo '```'
|
||||
} >> "$GITHUB_STEP_SUMMARY"
|
||||
|
||||
push-gateway-build:
|
||||
name: Build public push gateway (${{ matrix.platform }})
|
||||
runs-on: ${{ matrix.runner }}
|
||||
timeout-minutes: 60
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- platform: linux/amd64
|
||||
runner: ubuntu-24.04
|
||||
arch: amd64
|
||||
- platform: linux/arm64
|
||||
runner: ubuntu-24.04-arm
|
||||
arch: arm64
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
with:
|
||||
ref: ${{ github.event_name == 'workflow_dispatch' && inputs.ref || '' }}
|
||||
persist-credentials: false
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0
|
||||
with:
|
||||
buildkitd-config-inline: |
|
||||
[worker.oci]
|
||||
max-parallelism = 2
|
||||
- name: Log in to GHCR
|
||||
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: ghcr.io/block/buzz-push-gateway
|
||||
labels: |
|
||||
org.opencontainers.image.title=Buzz Push Gateway
|
||||
org.opencontainers.image.description=Capability-gated APNs last hop for Buzz
|
||||
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.push-gateway
|
||||
platforms: ${{ matrix.platform }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
outputs: type=image,name=ghcr.io/block/buzz-push-gateway,push-by-digest=true,name-canonical=true,push=${{ github.event_name != 'pull_request' }}
|
||||
cache-from: type=registry,ref=ghcr.io/block/buzz-push-gateway-buildcache:${{ matrix.arch }}
|
||||
cache-to: ${{ (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository) && format('type=registry,ref=ghcr.io/block/buzz-push-gateway-buildcache:{0},mode=max,compression=zstd', matrix.arch) || '' }}
|
||||
- name: Export digest
|
||||
if: github.event_name != 'pull_request'
|
||||
env:
|
||||
DIGEST: ${{ steps.build.outputs.digest }}
|
||||
run: mkdir -p /tmp/gateway-digests && touch "/tmp/gateway-digests/${DIGEST#sha256:}"
|
||||
- name: Upload digest
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
with:
|
||||
name: gateway-digests-${{ matrix.arch }}
|
||||
path: /tmp/gateway-digests/*
|
||||
if-no-files-found: error
|
||||
retention-days: 1
|
||||
|
||||
push-gateway-merge:
|
||||
name: Publish public push gateway image
|
||||
if: github.event_name != 'pull_request'
|
||||
runs-on: ubuntu-24.04
|
||||
needs: push-gateway-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/gateway-digests
|
||||
pattern: gateway-digests-*
|
||||
merge-multiple: true
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0
|
||||
- name: Log in to GHCR
|
||||
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Extract metadata
|
||||
id: meta
|
||||
uses: docker/metadata-action@80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9 # v6.1.0
|
||||
with:
|
||||
images: ghcr.io/block/buzz-push-gateway
|
||||
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=semver,pattern={{version}},match=^relay-v(.*)$,value=${{ inputs.version }}
|
||||
type=semver,pattern={{major}}.{{minor}},match=^relay-v(.*)$,value=${{ inputs.version }}
|
||||
- name: Merge and publish manifest
|
||||
id: manifest
|
||||
working-directory: /tmp/gateway-digests
|
||||
env:
|
||||
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+=("ghcr.io/block/buzz-push-gateway@sha256:${digest}"); done
|
||||
docker buildx imagetools create "${tags[@]}" "${digests[@]}"
|
||||
first_tag=$(echo "$META_TAGS" | head -n1)
|
||||
digest=$(docker buildx imagetools inspect "$first_tag" --format '{{json .Manifest}}' | jq -r '.digest')
|
||||
echo "digest=${digest}" >> "$GITHUB_OUTPUT"
|
||||
- name: Attest gateway image provenance
|
||||
uses: actions/attest-build-provenance@0f67c3f4856b2e3261c31976d6725780e5e4c373 # v4.1.1
|
||||
with:
|
||||
subject-name: ghcr.io/block/buzz-push-gateway
|
||||
subject-digest: ${{ steps.manifest.outputs.digest }}
|
||||
push-to-registry: true
|
||||
- name: Gateway publication summary
|
||||
env:
|
||||
GATEWAY_DIGEST: ${{ steps.manifest.outputs.digest }}
|
||||
GATEWAY_TAGS: ${{ steps.meta.outputs.tags }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
{
|
||||
echo "### Published \`ghcr.io/block/buzz-push-gateway\`"
|
||||
echo
|
||||
printf "**Digest:** \`%s\`\n" "$GATEWAY_DIGEST"
|
||||
echo
|
||||
echo '**Tags:**'
|
||||
echo "\`\`\`"
|
||||
printf '%s\n' "$GATEWAY_TAGS"
|
||||
echo "\`\`\`"
|
||||
echo
|
||||
echo 'Verify provenance before deployment:'
|
||||
echo "\`\`\`"
|
||||
printf 'gh attestation verify oci://ghcr.io/block/buzz-push-gateway@%s --owner block\n' "$GATEWAY_DIGEST"
|
||||
echo "\`\`\`"
|
||||
} >> "$GITHUB_STEP_SUMMARY"
|
||||
|
||||
4
.github/workflows/helm-chart.yml
vendored
4
.github/workflows/helm-chart.yml
vendored
@@ -40,6 +40,7 @@ on:
|
||||
pull_request:
|
||||
paths:
|
||||
- "deploy/charts/buzz/**"
|
||||
- "deploy/charts/buzz-push-gateway/**"
|
||||
- ".github/workflows/helm-chart.yml"
|
||||
- "ct.yaml"
|
||||
|
||||
@@ -88,6 +89,9 @@ jobs:
|
||||
- name: Build chart dependencies
|
||||
run: helm dependency build deploy/charts/buzz
|
||||
|
||||
- name: Push gateway chart lint + render guard
|
||||
run: deploy/charts/buzz-push-gateway/tests/render.sh
|
||||
|
||||
- name: ct lint
|
||||
run: ct lint --config ct.yaml --all
|
||||
|
||||
|
||||
68
.github/workflows/push-gateway-helm-chart.yml
vendored
Normal file
68
.github/workflows/push-gateway-helm-chart.yml
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
name: push gateway helm chart
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
description: "Chart semver (without push-chart-v prefix)"
|
||||
required: true
|
||||
ref:
|
||||
description: "Matching push-chart-v tag"
|
||||
required: true
|
||||
push:
|
||||
tags: ["push-chart-v[0-9]*"]
|
||||
pull_request:
|
||||
paths:
|
||||
- "deploy/charts/buzz-push-gateway/**"
|
||||
- ".github/workflows/push-gateway-helm-chart.yml"
|
||||
permissions: {}
|
||||
env:
|
||||
CHART_REPO: oci://ghcr.io/block/buzz/charts
|
||||
jobs:
|
||||
validate:
|
||||
runs-on: ubuntu-latest
|
||||
permissions: { contents: read }
|
||||
steps:
|
||||
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
|
||||
with:
|
||||
ref: ${{ github.event_name == 'workflow_dispatch' && inputs.ref || '' }}
|
||||
fetch-depth: 0
|
||||
- uses: azure/setup-helm@1a275c3b69536ee54be43f2070a358922e12c8d4
|
||||
with: { version: v3.16.4 }
|
||||
- run: deploy/charts/buzz-push-gateway/tests/render.sh
|
||||
- run: deploy/charts/buzz-push-gateway/tests/release-contract.sh
|
||||
publish:
|
||||
if: github.event_name != 'pull_request'
|
||||
needs: validate
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
steps:
|
||||
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
|
||||
with:
|
||||
ref: ${{ github.event_name == 'workflow_dispatch' && inputs.ref || '' }}
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
- uses: azure/setup-helm@1a275c3b69536ee54be43f2070a358922e12c8d4
|
||||
with: { version: v3.16.4 }
|
||||
- name: Verify release tag and chart version
|
||||
env:
|
||||
INPUT_VERSION: ${{ inputs.version }}
|
||||
REF_NAME: ${{ github.ref_name }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
version="${INPUT_VERSION:-${REF_NAME#push-chart-v}}"
|
||||
[[ "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?$ ]]
|
||||
test "$(helm show chart deploy/charts/buzz-push-gateway | awk '/^version:/ {print $2}')" = "$version"
|
||||
if [ -n "$INPUT_VERSION" ]; then
|
||||
test "$(git rev-parse HEAD)" = "$(git rev-parse "refs/tags/push-chart-v${version}^{commit}")"
|
||||
fi
|
||||
echo "VERSION=$version" >> "$GITHUB_ENV"
|
||||
- uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
- run: helm package deploy/charts/buzz-push-gateway --destination dist
|
||||
- run: helm push "dist/buzz-push-gateway-${VERSION}.tgz" "$CHART_REPO"
|
||||
147
.github/workflows/release.yml
vendored
147
.github/workflows/release.yml
vendored
@@ -138,7 +138,7 @@ jobs:
|
||||
id: mesh_rev
|
||||
run: |
|
||||
set -euo pipefail
|
||||
REV=$(grep -oE 'mesh-llm\.git\?rev=[0-9a-f]{40}' Cargo.lock | head -1 | grep -oE '[0-9a-f]{40}')
|
||||
REV=$(python3 -c 'import tomllib; d=tomllib.load(open("Cargo.lock", "rb")); p=next(p for p in d["package"] if p["name"] == "mesh-llm-sdk"); print(p["source"].rsplit("#", 1)[1])')
|
||||
[[ -n "$REV" ]] || { echo "::error::could not resolve mesh-llm rev from Cargo.lock"; exit 1; }
|
||||
echo "rev=$REV" >> "$GITHUB_OUTPUT"
|
||||
echo "short=${REV:0:7}" >> "$GITHUB_OUTPUT"
|
||||
@@ -199,6 +199,15 @@ jobs:
|
||||
fi
|
||||
echo "dmg=$DMG" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Set DMG Finder label text size
|
||||
env:
|
||||
DMG_PATH: ${{ steps.unsigned.outputs.dmg }}
|
||||
run: desktop/scripts/set-dmg-finder-text-size.sh "$DMG_PATH" 14
|
||||
|
||||
# mdx-ios-codesign-helper discovers this file by its exact lowercase basename.
|
||||
- name: Stage signing entitlements
|
||||
run: cp desktop/src-tauri/Entitlements.plist "${RUNNER_TEMP}/entitlements.plist"
|
||||
|
||||
- name: Codesign and Notarize
|
||||
id: codesign
|
||||
uses: block/apple-codesign-action@679535d1ab7c5a7c18e6f9afcba3464512cc3dde # v1.1.0
|
||||
@@ -206,7 +215,7 @@ jobs:
|
||||
osx-codesign-role: ${{ secrets.OSX_CODESIGN_ROLE }}
|
||||
codesign-s3-bucket: ${{ secrets.CODESIGN_S3_BUCKET }}
|
||||
unsigned-artifact-path: ${{ steps.unsigned.outputs.dmg }}
|
||||
entitlements-plist-path: desktop/src-tauri/Entitlements.plist
|
||||
entitlements-plist-path: ${{ runner.temp }}/entitlements.plist
|
||||
artifact-name: buzz-${{ github.sha }}-${{ github.run_id }}-arm64
|
||||
|
||||
- name: Replace DMG and rebuild updater archive
|
||||
@@ -243,6 +252,8 @@ jobs:
|
||||
desktop/src-tauri/target/release/bundle/macos/Buzz.app
|
||||
spctl --assess --type execute --verbose=4 \
|
||||
desktop/src-tauri/target/release/bundle/macos/Buzz.app
|
||||
desktop/scripts/verify-macos-entitlements.sh \
|
||||
desktop/src-tauri/target/release/bundle/macos/Buzz.app
|
||||
|
||||
- name: Locate build artifacts
|
||||
id: artifacts
|
||||
@@ -361,6 +372,15 @@ jobs:
|
||||
fi
|
||||
echo "dmg=$DMG" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Set DMG Finder label text size
|
||||
env:
|
||||
DMG_PATH: ${{ steps.unsigned.outputs.dmg }}
|
||||
run: desktop/scripts/set-dmg-finder-text-size.sh "$DMG_PATH" 14
|
||||
|
||||
# mdx-ios-codesign-helper discovers this file by its exact lowercase basename.
|
||||
- name: Stage signing entitlements
|
||||
run: cp desktop/src-tauri/Entitlements.plist "${RUNNER_TEMP}/entitlements.plist"
|
||||
|
||||
- name: Codesign and Notarize
|
||||
id: codesign
|
||||
uses: block/apple-codesign-action@679535d1ab7c5a7c18e6f9afcba3464512cc3dde # v1.1.0
|
||||
@@ -368,7 +388,7 @@ jobs:
|
||||
osx-codesign-role: ${{ secrets.OSX_CODESIGN_ROLE }}
|
||||
codesign-s3-bucket: ${{ secrets.CODESIGN_S3_BUCKET }}
|
||||
unsigned-artifact-path: ${{ steps.unsigned.outputs.dmg }}
|
||||
entitlements-plist-path: desktop/src-tauri/Entitlements.plist
|
||||
entitlements-plist-path: ${{ runner.temp }}/entitlements.plist
|
||||
artifact-name: buzz-${{ github.sha }}-${{ github.run_id }}-x64
|
||||
|
||||
- name: Replace DMG and rebuild updater archive
|
||||
@@ -403,6 +423,7 @@ jobs:
|
||||
APP_DIR="desktop/src-tauri/target/${TARGET}/release/bundle/macos/Buzz.app"
|
||||
codesign --verify --deep --strict --verbose=2 "$APP_DIR"
|
||||
spctl --assess --type execute --verbose=4 "$APP_DIR"
|
||||
desktop/scripts/verify-macos-entitlements.sh "$APP_DIR"
|
||||
|
||||
- name: Locate updater archive
|
||||
id: artifacts
|
||||
@@ -447,42 +468,48 @@ jobs:
|
||||
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
|
||||
needs: setup
|
||||
timeout-minutes: 60
|
||||
permissions:
|
||||
contents: write
|
||||
env:
|
||||
# AppImage tools (linuxdeploy, appimagetool) are themselves AppImages.
|
||||
# Containers lack FUSE, so we must use the extract-and-run fallback.
|
||||
APPIMAGE_EXTRACT_AND_RUN: "1"
|
||||
# This job runs in a container where the default run shell is dash;
|
||||
# the AppImage steps below use bash-only syntax ([[ ]], mapfile, arrays).
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
outputs:
|
||||
archive_name: ${{ steps.linux-artifacts.outputs.archive_name }}
|
||||
sig: ${{ steps.read-sig.outputs.sig }}
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
with:
|
||||
ref: ${{ github.event_name == 'push' && github.ref || inputs.ref }}
|
||||
persist-credentials: false
|
||||
|
||||
- uses: cashapp/activate-hermit@cea9af7913204a965fd488637a8d1811bba2e616 # v1
|
||||
|
||||
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
|
||||
with:
|
||||
workspaces: desktop/src-tauri
|
||||
lookup-only: true
|
||||
|
||||
- name: Install Tauri dependencies (Linux)
|
||||
- name: Install system dependencies
|
||||
env:
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
run: |
|
||||
sudo apt-get update \
|
||||
# Must run first: bare ubuntu:22.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.
|
||||
apt-get update \
|
||||
-o Acquire::Retries=3 \
|
||||
-o Acquire::http::Timeout=30 \
|
||||
-o Acquire::https::Timeout=30
|
||||
sudo apt-get install -y --no-install-recommends \
|
||||
apt-get install -y --no-install-recommends \
|
||||
-o Acquire::Retries=3 \
|
||||
-o Acquire::http::Timeout=30 \
|
||||
-o Acquire::https::Timeout=30 \
|
||||
-o DPkg::Lock::Timeout=120 \
|
||||
build-essential \
|
||||
ca-certificates \
|
||||
curl \
|
||||
desktop-file-utils \
|
||||
file \
|
||||
git \
|
||||
libasound2-dev \
|
||||
libayatana-appindicator3-dev \
|
||||
libgtk-3-dev \
|
||||
@@ -491,7 +518,73 @@ jobs:
|
||||
libwebkit2gtk-4.1-dev \
|
||||
libxdo-dev \
|
||||
patchelf \
|
||||
wget
|
||||
pkg-config \
|
||||
squashfs-tools \
|
||||
wget \
|
||||
xdg-utils
|
||||
# Install GitHub CLI — preinstalled on runners but absent in containers.
|
||||
# wget and ca-certificates are now available from the step above.
|
||||
mkdir -p -m 755 /etc/apt/keyrings
|
||||
wget -q --tries=3 --timeout=30 -O /usr/share/keyrings/githubcli-archive-keyring.gpg \
|
||||
https://cli.github.com/packages/githubcli-archive-keyring.gpg
|
||||
# Pin the keyring like appimagetool below. If GitHub rotates the
|
||||
# keyring this fails loudly — recompute and update the hash.
|
||||
echo "6084d5d7bd8e288441e0e94fc6275570895da18e6751f70f057485dc2d1a811b /usr/share/keyrings/githubcli-archive-keyring.gpg" | sha256sum -c
|
||||
chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg
|
||||
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" \
|
||||
> /etc/apt/sources.list.d/github-cli.list
|
||||
apt-get update
|
||||
apt-get install -y --no-install-recommends gh
|
||||
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
with:
|
||||
ref: ${{ github.event_name == 'push' && github.ref || inputs.ref }}
|
||||
persist-credentials: false
|
||||
|
||||
- name: Mark workspace safe for git (containerized job)
|
||||
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
|
||||
|
||||
- uses: cashapp/activate-hermit@cea9af7913204a965fd488637a8d1811bba2e616 # v1
|
||||
|
||||
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
|
||||
with:
|
||||
workspaces: desktop/src-tauri
|
||||
lookup-only: true
|
||||
|
||||
- name: Install appimagetool
|
||||
run: |
|
||||
# Pin to an immutable release tag to avoid supply-chain drift from the
|
||||
# mutable `continuous` tag. Tag: 1.9.1, asset: appimagetool-<arch>.AppImage
|
||||
# (https://github.com/AppImage/appimagetool/releases/tag/1.9.1)
|
||||
case "$(uname -m)" in
|
||||
x86_64) ARCH_SUFFIX="x86_64" ;;
|
||||
aarch64) ARCH_SUFFIX="aarch64" ;;
|
||||
*)
|
||||
echo "::error::Unsupported architecture: $(uname -m)"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
wget -q --tries=3 --timeout=30 -O /tmp/appimagetool \
|
||||
"https://github.com/AppImage/appimagetool/releases/download/1.9.1/appimagetool-${ARCH_SUFFIX}.AppImage"
|
||||
# SHA256 integrity check. Refuse to run an unverified binary: if a new
|
||||
# arch (e.g. aarch64) is enabled in CI, compute its hash and add it here.
|
||||
if [[ "$ARCH_SUFFIX" == "x86_64" ]]; then
|
||||
echo "ed4ce84f0d9caff66f50bcca6ff6f35aae54ce8135408b3fa33abfc3cb384eb0 /tmp/appimagetool" | sha256sum -c
|
||||
else
|
||||
echo "::error::No pinned SHA256 for appimagetool-${ARCH_SUFFIX} — add it before enabling this architecture"
|
||||
exit 1
|
||||
fi
|
||||
install -m 755 /tmp/appimagetool /usr/local/bin/appimagetool
|
||||
# appimagetool otherwise fetches the AppImage type2 runtime from the
|
||||
# MUTABLE `continuous` tag at repack time — the runtime is the first
|
||||
# code users execute, so pin it too. Tag: 20251108, hash is for the
|
||||
# x86_64 asset (non-x86_64 already hard-fails above).
|
||||
# (https://github.com/AppImage/type2-runtime/releases/tag/20251108)
|
||||
wget -q --tries=3 --timeout=30 -O /tmp/appimage-runtime \
|
||||
"https://github.com/AppImage/type2-runtime/releases/download/20251108/runtime-${ARCH_SUFFIX}"
|
||||
echo "2fca8b443c92510f1483a883f60061ad09b46b978b2631c807cd873a47ec260d /tmp/appimage-runtime" | sha256sum -c
|
||||
install -D -m 644 /tmp/appimage-runtime /usr/local/lib/appimage-runtime
|
||||
echo "APPIMAGETOOL_RUNTIME_FILE=/usr/local/lib/appimage-runtime" >> "$GITHUB_ENV"
|
||||
|
||||
- name: Install desktop dependencies
|
||||
run: just desktop-install-ci
|
||||
@@ -524,6 +617,22 @@ 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)
|
||||
run: |
|
||||
mapfile -t APPIMAGES < <(find desktop/src-tauri/target/release/bundle/appimage -name '*.AppImage' -type f)
|
||||
if [[ ${#APPIMAGES[@]} -eq 0 ]]; then
|
||||
echo "::error::No AppImage found to post-process"
|
||||
exit 1
|
||||
fi
|
||||
if [[ ${#APPIMAGES[@]} -gt 1 ]]; then
|
||||
echo "::error::Expected exactly one AppImage, found ${#APPIMAGES[@]}: ${APPIMAGES[*]}"
|
||||
exit 1
|
||||
fi
|
||||
bash desktop/scripts/fix-appimage.sh "${APPIMAGES[0]}"
|
||||
env:
|
||||
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
|
||||
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
|
||||
|
||||
- name: Locate Linux build artifacts
|
||||
id: linux-artifacts
|
||||
run: |
|
||||
|
||||
Reference in New Issue
Block a user