orca/.github/workflows/homebrew-bump.yml

171 lines
6.3 KiB
YAML

name: Homebrew Cask Bump
# Why: keep the stablyai/homebrew-orca tap in sync with GitHub Releases.
# Triggers:
# - workflow_call → release-cut.yml finished publishing a stable tag
# - workflow_dispatch → manual backfill for a specific tag
#
# The job computes the sha256 of orca-macos-arm64.dmg + orca-macos-x64.dmg
# from the release, templates Casks/orca.rb in this repo with the new
# version and hashes, then PRs the result into stablyai/homebrew-orca. It
# does NOT run for -rc.* tags: the stable cask should only track GA.
#
# Why no `release.published` trigger: other products shipped from this repo
# (e.g. mobile under `mobile-v*`) also publish GitHub Releases. A blanket
# `release.published` trigger would fire this workflow for any of them and
# attempt to download `orca-macos-*.dmg` from a non-desktop release, at
# best 404ing and at worst (if the filter were weaker) rewriting the cask
# to a non-desktop version. The tap is only ever bumped by the desktop
# release pipeline calling this workflow directly.
on:
workflow_call:
inputs:
tag:
description: Release tag to sync (e.g. v1.3.25)
required: true
type: string
workflow_dispatch:
inputs:
tag:
description: Release tag to sync (e.g. v1.3.25)
required: true
type: string
jobs:
bump-cask:
runs-on: ubuntu-latest
# Why: defense in depth. The desktop release pipeline already refuses
# to invoke this workflow for `-rc.*` tags, but a manual backfill could
# still pass one in — reject it here so the stable cask can never point
# at an RC. Also requires the desktop tag shape `v<digit>...` so a
# mis-typed mobile tag like `mobile-v0.0.1` is rejected up front.
if: >
inputs.tag != '' &&
!contains(inputs.tag, '-rc.') &&
startsWith(inputs.tag, 'v')
permissions:
contents: read
steps:
- name: Checkout orca
uses: actions/checkout@v4
- name: Resolve tag and version
id: tag
env:
RELEASE_TAG: ${{ github.event.release.tag_name }}
INPUT_TAG: ${{ inputs.tag }}
run: |
set -euo pipefail
if [[ -n "$INPUT_TAG" ]]; then
tag="$INPUT_TAG"
else
tag="$RELEASE_TAG"
fi
version="${tag#v}"
echo "tag=$tag" >>"$GITHUB_OUTPUT"
echo "version=$version" >>"$GITHUB_OUTPUT"
- name: Download DMGs and compute sha256
id: hash
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAG: ${{ steps.tag.outputs.tag }}
run: |
set -euo pipefail
mkdir -p dmgs
gh release download "$TAG" \
--repo "${{ github.repository }}" \
--pattern 'orca-macos-arm64.dmg' \
--pattern 'orca-macos-x64.dmg' \
--dir dmgs
arm=$(sha256sum dmgs/orca-macos-arm64.dmg | awk '{print $1}')
intel=$(sha256sum dmgs/orca-macos-x64.dmg | awk '{print $1}')
echo "arm=$arm" >>"$GITHUB_OUTPUT"
echo "intel=$intel" >>"$GITHUB_OUTPUT"
- name: Render updated cask file
env:
VERSION: ${{ steps.tag.outputs.version }}
ARM_SHA: ${{ steps.hash.outputs.arm }}
INTEL_SHA: ${{ steps.hash.outputs.intel }}
run: |
set -euo pipefail
python3 - <<'PY'
import os, re, pathlib
p = pathlib.Path("Casks/orca.rb")
src = p.read_text()
src = re.sub(r'version "[^"]+"',
f'version "{os.environ["VERSION"]}"', src, count=1)
src = re.sub(r'sha256 arm:\s*"[0-9a-f]+",\s*\n\s*intel:\s*"[0-9a-f]+"',
'sha256 arm: "{arm}",\n intel: "{intel}"'.format(
arm=os.environ["ARM_SHA"],
intel=os.environ["INTEL_SHA"]),
src, count=1)
p.write_text(src)
print(src)
PY
# Why: reuse the existing buf0-bot GitHub App (also used by
# track-community-prs.yaml) instead of minting a new PAT. The app is
# installed org-wide, so it has access to stablyai/homebrew-orca
# automatically. GITHUB_TOKEN cannot push cross-repo; a short-lived
# installation token can.
- name: Generate buf0-bot token
id: app-token
uses: actions/create-github-app-token@v2
with:
app-id: 2590194
private-key: ${{ secrets.BUFO_BOT_PRIVATE_KEY }}
owner: stablyai
repositories: homebrew-orca
- name: Checkout tap
uses: actions/checkout@v4
with:
repository: stablyai/homebrew-orca
path: tap
token: ${{ steps.app-token.outputs.token }}
- name: Copy cask into tap and open PR
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
VERSION: ${{ steps.tag.outputs.version }}
TAG: ${{ steps.tag.outputs.tag }}
run: |
set -euo pipefail
mkdir -p tap/Casks
cp Casks/orca.rb tap/Casks/orca.rb
cd tap
# Why: commit author must match the buf0-bot app so commits are
# attributed to the bot in the tap's history / PR UI.
git config user.name "buf0-bot[bot]"
git config user.email "252831055+buf0-bot[bot]@users.noreply.github.com"
if git diff --quiet; then
echo "Cask already up-to-date for $TAG; nothing to do."
exit 0
fi
branch="bump/orca-$VERSION"
git checkout -b "$branch"
git add Casks/orca.rb
git commit -m "orca $VERSION"
git push -u origin "$branch" --force
# Why: prefer --fill so the PR body matches the commit; fall back
# to a brief body if the PR already exists for this branch.
gh pr create \
--title "orca $VERSION" \
--body "Automated bump from stablyai/orca release $TAG." \
--base main \
--head "$branch" \
|| gh pr edit "$branch" --title "orca $VERSION"
# Why: squash-merge immediately rather than --auto. The tap has no
# required checks or branch protection, and `gh pr merge --auto`
# only activates when there's something to wait on — on a repo
# with no gates it silently no-ops, leaving the PR open forever.
gh pr merge "$branch" --squash --delete-branch