Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 9 additions & 10 deletions .github/workflows/auto-tag-on-release-pr-merge.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: Auto-tag on Release PR Merge

# Five release lanes share this one workflow. Four use an explicit branch
# Four PR-driven release lanes share this workflow. Each uses 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:
#
Expand All @@ -10,18 +10,20 @@ name: Auto-tag on Release PR Merge
# push-chart-release/<v> → tag push-chart-v<v> → push-gateway-helm-chart.yml
# any internal PR that bumps deploy/charts/buzz/Chart.yaml `version`
# → tag chart-v<v> → helm-chart.yml (helm chart)
# mobile-release/<v> → tag mobile-v<v> → (manual sprout_ref for buzz-releases build — see below)
#
# Mobile candidate tags do not come from merged PRs. Operators create immutable
# mobile-v<v>-rc.N tags directly from remote main with scripts/mobile-release.sh,
# then hand the exact tag to buzz-releases.
#
# Release tags are created with a short-lived token from the dedicated
# buzz-release-bot GitHub App. GitHub attributes the ref creation to that
# App, so the consumer's `on.push.tags` trigger runs normally. The workflow's
# default GITHUB_TOKEN remains read-only and is never used to create a tag.
#
# The mobile lane is push-only by infosec necessity: OSS `block/buzz` CI must
# not trigger CI in the private `buzz-releases` repo, so auto-dispatch across
# that boundary is deliberately disallowed. The mobile-v* tag is consumed
# manually instead — a human feeds it as the `sprout_ref` input to the
# `buzz-releases` Buildkite pipeline, which builds and ships mobile.
# Mobile is manual-only by infosec necessity: OSS `block/buzz` CI must
# not trigger CI in the private `buzz-releases` repo. A human feeds the exact
# mobile candidate tag to the private Buildkite pipeline, which builds and
# ships mobile.

on:
pull_request:
Expand Down Expand Up @@ -65,9 +67,6 @@ jobs:
push-chart-release/*)
VERSION="${BRANCH#push-chart-release/}"
TAG_PREFIX="push-chart-v" ;;
mobile-release/*)
VERSION="${BRANCH#mobile-release/}"
TAG_PREFIX="mobile-v" ;;
*)
parent_sha="$(git rev-parse HEAD^)"
old_version="$(git show "${parent_sha}:deploy/charts/buzz/Chart.yaml" 2>/dev/null | awk '/^version:/ {print $2}')"
Expand Down
10 changes: 10 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,19 @@ jobs:
- 'pnpm-lock.yaml'
mobile:
- 'mobile/**'
- 'scripts/mobile-release.sh'
- 'scripts/publish-mobile-release-candidate.sh'
- 'scripts/release-rulesets.sh'
- 'scripts/test-mobile-release-contract.sh'
- 'scripts/test-mobile-release-candidate-publisher.sh'
- '.github/workflows/mobile-release-candidate.yml'
- '.github/workflows/ci.yml'
- name: Release workflow source contract
run: scripts/test-release-ref-contract.sh
- name: Mobile release contract
run: |
scripts/test-mobile-release-contract.sh
scripts/test-mobile-release-candidate-publisher.sh

rust-lint:
name: Rust Lint
Expand Down
69 changes: 69 additions & 0 deletions .github/workflows/mobile-release-candidate.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
name: Publish Mobile Release Candidate
run-name: Publish mobile-v${{ inputs.version }}-rc.${{ inputs.candidate_number }}

on:
workflow_dispatch:
inputs:
version:
description: Mobile marketing version (X.Y.Z)
required: true
type: string
candidate_number:
description: Expected next release-candidate number
required: true
type: string
target_sha:
description: Exact current block/buzz main commit
required: true
type: string

concurrency:
group: mobile-release-candidate-${{ inputs.version }}
cancel-in-progress: false

permissions:
contents: read

jobs:
publish:
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Require the reviewed workflow from main
env:
DISPATCH_REF: ${{ github.ref }}
run: |
if [ "$DISPATCH_REF" != "refs/heads/main" ]; then
echo "::error::Mobile candidates must be dispatched from main, not $DISPATCH_REF"
exit 1
fi

- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
ref: ${{ github.sha }}
persist-credentials: false

- name: Require canonical repository
env:
REPOSITORY: ${{ github.repository }}
run: |
if [ "$REPOSITORY" != "block/buzz" ]; then
echo "::error::Mobile candidate publication is restricted to block/buzz"
exit 1
fi

- name: Create release tagger token
id: release-tagger
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
with:
client-id: ${{ vars.BUZZ_RELEASE_TAGGER_CLIENT_ID }}
private-key: ${{ secrets.BUZZ_RELEASE_TAGGER_PRIVATE_KEY }}
permission-contents: write

- name: Publish annotated candidate tag
env:
GH_TOKEN: ${{ steps.release-tagger.outputs.token }}
MOBILE_VERSION: ${{ inputs.version }}
CANDIDATE_NUMBER: ${{ inputs.candidate_number }}
TARGET_SHA: ${{ inputs.target_sha }}
run: scripts/publish-mobile-release-candidate.sh "$MOBILE_VERSION" "$CANDIDATE_NUMBER" "$TARGET_SHA"
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -569,5 +569,5 @@ just mobile-dev
- [CONTRIBUTING.md](CONTRIBUTING.md) — setup, code style, PR process, how to add event kinds / CLI subcommands / HTTP endpoints
- [TESTING.md](TESTING.md) — multi-agent E2E test guide
- [ARCHITECTURE.md](ARCHITECTURE.md) — system design and component relationships
- [RELEASING.md](RELEASING.md) — release process: `release-desktop`, `release-relay`, `release-mobile`, auto-tag, internal builds
- [RELEASING.md](RELEASING.md) — release process: `release-desktop`, `release-relay`, `scripts/mobile-release.sh`, candidate tags, internal builds
- [README.md](README.md) — project overview and quick start
47 changes: 2 additions & 45 deletions Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -674,14 +674,6 @@ get-next-patch-version:
get-next-relay-patch-version:
@python3 -c "v='$(just get-current-relay-version)'.split('.'); print(f'{v[0]}.{v[1]}.{int(v[2])+1}')"

# Read the current mobile version from pubspec.yaml (strips the +build suffix)
get-current-mobile-version:
@grep -m1 '^version: ' mobile/pubspec.yaml | sed -E 's/version: ([^+]*).*/\1/'

# Compute next mobile patch version (e.g., 0.3.0 → 0.3.1)
get-next-mobile-patch-version:
@python3 -c "v='$(just get-current-mobile-version)'.split('.'); print(f'{v[0]}.{v[1]}.{int(v[2])+1}')"

# Update version in desktop package manifests and regenerate lockfiles
bump-desktop-version version:
#!/usr/bin/env bash
Expand Down Expand Up @@ -721,16 +713,6 @@ bump-relay-version version:
cargo update -p buzz-relay
echo "Bumped buzz-relay to {{ version }} and regenerated Cargo.lock"

# Bump the mobile pubspec version and regenerate the lockfile
bump-mobile-version version:
#!/usr/bin/env bash
set -euo pipefail
# pubspec carries a `version: X.Y.Z+build`; preserve the `+build` convention
# (a literal `+1`, matching the desktop lane's prior behavior).
perl -i -pe 's/^version: .*/version: {{ version }}+1/' mobile/pubspec.yaml
(unset GIT_DIR GIT_WORK_TREE; cd mobile && flutter pub get)
echo "Bumped mobile to {{ version }} and regenerated pubspec.lock"

# Open or update the desktop release PR (signed desktop app)
release-desktop *ARGS:
#!/usr/bin/env bash
Expand All @@ -755,22 +737,8 @@ release-relay *ARGS:
fi
just _release-pr relay "$VERSION"

# Open or update the mobile release PR (Buzz mobile app)
release-mobile *ARGS:
#!/usr/bin/env bash
set -euo pipefail
ARG="{{ ARGS }}"
if [[ -z "$ARG" || "$ARG" == "patch" ]]; then
VERSION=$(just get-next-mobile-patch-version)
else
VERSION="$ARG"
fi
just _release-pr mobile "$VERSION"

# Shared release-PR engine. One body, three lanes — the only lane-specific steps
# are the version-bump command and the file/tag/changelog identifiers selected
# in the `case` below. Everything else (git preflight, branch reset, changelog
# generation, commit, push, PR open/edit) is identical across lanes.
# Shared release-PR engine for desktop and relay. Mobile publishes immutable
# candidate tags directly from remote main instead of using metadata-only PRs.
_release-pr lane version:
#!/usr/bin/env bash
set -euo pipefail
Expand Down Expand Up @@ -801,16 +769,6 @@ _release-pr lane version:
ADD_FILES=(crates/buzz-relay/Cargo.toml Cargo.lock crates/buzz-relay/CHANGELOG.md)
LOG_PATHS=(crates/buzz-relay/ crates/buzz-core/ crates/buzz-db/ crates/buzz-auth/ crates/buzz-pubsub/ crates/buzz-search/ crates/buzz-audit/ crates/buzz-media/ crates/buzz-sdk/ crates/buzz-workflow/ crates/buzz-conformance/ migrations/)
ARTIFACT="Buzz Relay" ;;
mobile)
BRANCH_PREFIX="mobile-release"
TAG_FETCH='mobile-v*'
TAG_MATCH='mobile-v[0-9]*'
TAG_EXCLUDE='mobile-v*-*'
TAG_PREFIX="mobile-v"
CHANGELOG="mobile/CHANGELOG.md"
ADD_FILES=(mobile/pubspec.yaml mobile/pubspec.lock mobile/CHANGELOG.md)
LOG_PATHS=(mobile/)
ARTIFACT="Buzz Mobile" ;;
*)
echo "Error: unknown release lane '{{ lane }}'"
exit 1 ;;
Expand Down Expand Up @@ -851,7 +809,6 @@ _release-pr lane version:
case "{{ lane }}" in
desktop) just bump-desktop-version "$VERSION" ;;
relay) just bump-relay-version "$VERSION" ;;
mobile) just bump-mobile-version "$VERSION" ;;
esac
# Generate the changelog from commits since this lane's last release tag.
LAST_TAG=$(git describe --tags --abbrev=0 --match "$TAG_MATCH" --exclude "$TAG_EXCLUDE" 2>/dev/null || echo "")
Expand Down
Loading
Loading