mirror of
https://github.com/block/buzz.git
synced 2026-11-04 00:12:02 +00:00
feat(release): add GitHub App token, git-log release notes, and Buildkite automation
The sync-release-changelog workflow now uses a GitHub App token instead of GITHUB_TOKEN so pushes to the release PR branch re-trigger CI (the repo's ruleset requires 5 status checks to pass). Also hardens PR discovery with --limit 100 --base main, and serializes concurrent runs with cancel-in-progress: false to prevent non-fast-forward push races. release.yml generates GitHub release notes from git log at release time instead of reading from CHANGELOG.md, closing the merge-before-sync race where someone merges the release PR before the changelog sync finishes. auto-tag-on-release-pr-merge.yml now triggers the internal sprout-releases Buildkite pipeline via REST API after pushing the tag, passing version metadata so the pipeline's input step is skipped.
This commit is contained in:
@@ -60,3 +60,25 @@ jobs:
|
||||
gh workflow run release.yml \
|
||||
-f version="$VERSION" \
|
||||
-f ref="v$VERSION"
|
||||
|
||||
- name: Trigger internal release build
|
||||
env:
|
||||
BUILDKITE_API_TOKEN: ${{ secrets.BUILDKITE_API_TOKEN }}
|
||||
VERSION: ${{ env.version }}
|
||||
run: |
|
||||
curl -sf -X POST \
|
||||
"https://api.buildkite.com/v2/organizations/runway/pipelines/sprout-releases/builds" \
|
||||
-H "Authorization: Bearer ${BUILDKITE_API_TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{
|
||||
\"commit\": \"HEAD\",
|
||||
\"branch\": \"main\",
|
||||
\"message\": \"Release v${VERSION}\",
|
||||
\"meta_data\": {
|
||||
\"version\": \"${VERSION}\",
|
||||
\"sprout_ref\": \"v${VERSION}\",
|
||||
\"relay_url\": \"wss://sprout-oss.stage.blox.sqprod.co\",
|
||||
\"publish_latest\": \"true\"
|
||||
}
|
||||
}"
|
||||
|
||||
|
||||
13
.github/workflows/release.yml
vendored
13
.github/workflows/release.yml
vendored
@@ -50,6 +50,8 @@ jobs:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
ref: ${{ github.event_name == 'push' && github.ref || inputs.ref }}
|
||||
fetch-depth: 0
|
||||
fetch-tags: true
|
||||
persist-credentials: false
|
||||
|
||||
- uses: cashapp/activate-hermit@e49f5cb4dd64ff0b0b659d1d8df499595451155a # v1
|
||||
@@ -229,12 +231,11 @@ jobs:
|
||||
DMG_PATH: ${{ steps.artifacts.outputs.dmg }}
|
||||
run: |
|
||||
RELEASE_SHA=$(git rev-parse HEAD)
|
||||
NOTES=""
|
||||
if [[ -f CHANGELOG.md ]]; then
|
||||
NOTES=$(awk "/^## v${VERSION}$/,/^## v/" CHANGELOG.md | sed '$d')
|
||||
fi
|
||||
if [[ -z "$NOTES" ]]; then
|
||||
NOTES="Sprout Desktop v${VERSION}"
|
||||
PREV_TAG=$(git describe --tags --abbrev=0 --match 'v[0-9]*' HEAD^ 2>/dev/null || echo "")
|
||||
if [[ -n "$PREV_TAG" ]]; then
|
||||
NOTES=$(git log "${PREV_TAG}..HEAD" --oneline --no-merges)
|
||||
else
|
||||
NOTES="Initial release"
|
||||
fi
|
||||
gh release create "v${VERSION}" \
|
||||
--target "$RELEASE_SHA" \
|
||||
|
||||
17
.github/workflows/sync-release-changelog.yml
vendored
17
.github/workflows/sync-release-changelog.yml
vendored
@@ -4,10 +4,10 @@ on:
|
||||
push:
|
||||
branches: [main]
|
||||
|
||||
# Collapse rapid successive main pushes into one sync run.
|
||||
# Serialize successive main pushes — each run generates the correct changelog.
|
||||
concurrency:
|
||||
group: sync-release-changelog
|
||||
cancel-in-progress: true
|
||||
cancel-in-progress: false
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
@@ -29,6 +29,8 @@ jobs:
|
||||
PRS=$(gh pr list \
|
||||
--repo block/sprout \
|
||||
--state open \
|
||||
--base main \
|
||||
--limit 100 \
|
||||
--json number,headRefName,headRepository \
|
||||
--jq '[.[] |
|
||||
select(.headRepository.nameWithOwner == "block/sprout") |
|
||||
@@ -59,6 +61,14 @@ jobs:
|
||||
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
|
||||
echo "Found release PR #${NUMBER} (${BRANCH})"
|
||||
|
||||
- name: Generate GitHub App token
|
||||
if: steps.find-pr.outputs.found == 'true'
|
||||
id: app-token
|
||||
uses: actions/create-github-app-token@v3
|
||||
with:
|
||||
client-id: ${{ vars.RELEASE_APP_CLIENT_ID }}
|
||||
private-key: ${{ secrets.RELEASE_APP_PRIVATE_KEY }}
|
||||
|
||||
- name: Check out release PR branch
|
||||
if: steps.find-pr.outputs.found == 'true'
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
@@ -66,13 +76,14 @@ jobs:
|
||||
ref: ${{ steps.find-pr.outputs.branch }}
|
||||
fetch-depth: 0
|
||||
fetch-tags: true
|
||||
token: ${{ steps.app-token.outputs.token }}
|
||||
|
||||
- name: Regenerate changelog section
|
||||
if: steps.find-pr.outputs.found == 'true'
|
||||
env:
|
||||
VERSION: ${{ steps.find-pr.outputs.version }}
|
||||
PR_NUMBER: ${{ steps.find-pr.outputs.number }}
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GH_TOKEN: ${{ steps.app-token.outputs.token }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
|
||||
26
RELEASING.md
26
RELEASING.md
@@ -26,9 +26,9 @@ This creates a `version-bump/<version>` PR that bumps all version manifests, reg
|
||||
|
||||
2. **The release PR stays in sync** — if other PRs merge to `main` while the release PR is open, the `sync-release-changelog` workflow automatically updates the changelog on the release PR branch so the final release notes reflect everything that will be in the binary. No manual action needed.
|
||||
|
||||
3. **Merge the PR** — the `auto-tag-on-release-pr-merge` workflow detects the `version-bump/*` branch merge and pushes a `v<version>` tag.
|
||||
3. **Merge the PR** — the `auto-tag-on-release-pr-merge` workflow detects the `version-bump/*` branch merge, pushes a `v<version>` tag, and triggers both the OSS release build and the internal Buildkite pipeline automatically.
|
||||
|
||||
4. **Tag triggers `release.yml`** — the existing release workflow builds, signs, notarizes, and publishes the desktop app for macOS and Linux.
|
||||
4. **Builds run in parallel** — `release.yml` builds, signs, notarizes, and publishes the OSS desktop app. The `sprout-releases` Buildkite pipeline produces Block-signed macOS and iOS builds with the `-block` version suffix.
|
||||
|
||||
---
|
||||
|
||||
@@ -70,7 +70,13 @@ If the automated flow isn't suitable (e.g., building from a non-main ref):
|
||||
|
||||
## Internal Releases
|
||||
|
||||
After the OSS release ships, trigger an internal build via the **sprout-releases** Buildkite pipeline:
|
||||
Internal builds are triggered automatically when the release PR merges. The `auto-tag-on-release-pr-merge` workflow calls the Buildkite REST API to start the [sprout-releases pipeline](https://buildkite.com/runway/sprout-releases) with the correct version, tag ref, relay URL, and `publish_latest=true`. No manual action needed.
|
||||
|
||||
Internal desktop builds display a `-block` suffix in the version (e.g., `v0.3.0-block` in the Settings panel). This distinguishes them from OSS builds at a glance. iOS builds and GitHub release tags use the clean version (`0.3.0`) since Apple's `CFBundleShortVersionString` rejects pre-release suffixes.
|
||||
|
||||
### Manual Buildkite Trigger (Fallback)
|
||||
|
||||
If the automated trigger fails or you need a custom build (different relay URL, `publish_latest=false`, non-tag ref):
|
||||
|
||||
1. Go to the [sprout-releases pipeline](https://buildkite.com/runway/sprout-releases) and click **New Build**
|
||||
2. Fill in the input fields:
|
||||
@@ -80,9 +86,7 @@ After the OSS release ships, trigger an internal build via the **sprout-releases
|
||||
| `version` | `0.3.0` | Semver, no `v` prefix |
|
||||
| `sprout_ref` | `v0.3.0` | The OSS git tag — use the tag, not a branch name |
|
||||
| `relay_url` | *(default)* | Pre-filled with the production relay; usually leave as-is |
|
||||
| `publish_latest` | `true` | Updates `latest.json` on Artifactory so installed apps auto-update. Set to `false` for test builds. |
|
||||
|
||||
Internal desktop builds display a `-block` suffix in the version (e.g., `v0.3.0-block` in the Settings panel). This distinguishes them from OSS builds at a glance. iOS builds and GitHub release tags use the clean version (`0.3.0`) since Apple's `CFBundleShortVersionString` rejects pre-release suffixes.
|
||||
| `publish_latest` | `true` | Set to `false` for test builds |
|
||||
|
||||
---
|
||||
|
||||
@@ -102,11 +106,14 @@ Each release produces two GitHub releases:
|
||||
- **`gh` CLI** authenticated (`gh auth status`)
|
||||
- The following **GitHub Actions secrets** must be configured:
|
||||
|
||||
| Secret | Purpose |
|
||||
|--------|---------|
|
||||
| Secret / Variable | Purpose |
|
||||
|-------------------|---------|
|
||||
| `SPROUT_UPDATER_PUBLIC_KEY` | Tauri updater public key (minisign) |
|
||||
| `TAURI_SIGNING_PRIVATE_KEY` | Tauri updater private key |
|
||||
| `TAURI_SIGNING_PRIVATE_KEY_PASSWORD` | Password for the private key |
|
||||
| `RELEASE_APP_CLIENT_ID` (variable) | GitHub App client ID for release automation |
|
||||
| `RELEASE_APP_PRIVATE_KEY` (secret) | GitHub App private key for release automation |
|
||||
| `BUILDKITE_API_TOKEN` | Runway Buildkite API token (`write_builds` scope) |
|
||||
|
||||
---
|
||||
|
||||
@@ -126,3 +133,6 @@ Verify that the `sprout-desktop-latest` release exists and contains a valid `lat
|
||||
|
||||
### `sync-release-changelog` workflow fails with "Multiple open release PRs"
|
||||
More than one `version-bump/*` PR is open. Close or merge the stale one before the sync can resume.
|
||||
|
||||
### Internal Buildkite build didn't trigger after release PR merge
|
||||
Check the `auto-tag-on-release-pr-merge` workflow run for errors in the "Trigger internal release build" step. Common causes: expired `BUILDKITE_API_TOKEN`, pipeline slug changed, or the token lacks `BUILD_AND_READ` access on the pipeline. Fall back to a [manual Buildkite trigger](#manual-buildkite-trigger-fallback).
|
||||
|
||||
Reference in New Issue
Block a user