homebrew-tap/.forgejo/workflows/update.yml
F∆I Platform 1c0eb6c668 feat: seed Homebrew formula + auto-update workflow
Mirror of installer/homebrew/fai.rb in fai/platform. Source
of truth is the platform repo; this is a passive distribution
mirror.

Auto-update workflow at .forgejo/workflows/update.yml runs
every 4 hours, diffs the latest platform release against
Formula/fai.rb, and rewrites version + sha256 when a new
version ships. Manual trigger via workflow_dispatch.

Users install with:
  brew tap fai/tap https://git.flemming.ai/fai/homebrew-tap
  brew install fai

End-state matches Phase 1 of
docs/releases/go-live-checklist.md.
2026-05-30 00:46:49 +02:00

133 lines
5 KiB
YAML

# Auto-update workflow for the fai/homebrew-tap repo.
#
# Lives here as the canonical source of truth. The bootstrap
# script (scripts/bootstrap-distribution-repos.sh in
# fai/platform) seeds this file into the tap repo at
# .forgejo/workflows/update.yml. Edit it here, run the
# bootstrap script, the tap repo picks up the new version.
#
# What it does:
# * Every 4 hours, fetches the latest release manifest for
# fai/platform.
# * If the version differs from the one currently in
# Formula/fai.rb, rewrites the formula's version + sha256
# entries (macos-aarch64 + macos-x86_64) and commits.
# * Workflow_dispatch trigger lets you force an update from
# the Forgejo UI without waiting for the cron tick.
#
# Manifest contract: fai/platform's release.yml writes
# .binaries.{macos-aarch64,macos-x86_64}.sha256 — see
# crates/fai_hub/src/update.rs::ReleaseManifest for the
# authoritative schema.
name: Update Homebrew formula
on:
schedule:
- cron: '0 */4 * * *'
workflow_dispatch: {}
jobs:
update:
name: Sync formula to latest platform release
runs-on: ubuntu-latest
steps:
- name: Checkout via external URL
run: |
set -eu
mkdir -p "$GITHUB_WORKSPACE"
cd "$GITHUB_WORKSPACE"
git init -q
git remote add origin \
"https://x-access-token:${GITHUB_TOKEN}@git.flemming.ai/${GITHUB_REPOSITORY}.git"
git fetch --depth=1 origin "$GITHUB_REF_NAME"
git checkout -q FETCH_HEAD
- name: Install jq + curl
run: |
apt-get update -qq
apt-get install -y --no-install-recommends jq curl ca-certificates
- name: Fetch latest manifest
id: manifest
run: |
set -eu
# Forgejo's releases API returns newest-first.
REL=$(curl -fsSL \
"https://git.flemming.ai/api/v1/repos/fai/platform/releases?limit=1" \
| jq -r '.[0]')
TAG=$(echo "$REL" | jq -r '.tag_name')
VERSION="${TAG#v}"
MANIFEST=$(curl -fsSL \
"https://git.flemming.ai/fai/platform/releases/download/${TAG}/manifest.json")
MAC_ARM=$(echo "$MANIFEST" | jq -r '.binaries["macos-aarch64"].sha256 // empty')
MAC_X64=$(echo "$MANIFEST" | jq -r '.binaries["macos-x86_64"].sha256 // empty')
if [ -z "$MAC_ARM" ] || [ -z "$MAC_X64" ]; then
echo "manifest for $TAG has no macOS entries yet — likely the local"
echo "publish step hasn't run. Skipping update."
echo "skip=true" >> "$GITHUB_OUTPUT"
exit 0
fi
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
echo "sha_aarch64=$MAC_ARM" >> "$GITHUB_OUTPUT"
echo "sha_x86_64=$MAC_X64" >> "$GITHUB_OUTPUT"
- name: Detect formula version
id: current
if: steps.manifest.outputs.skip != 'true'
run: |
CUR=$(grep -E '^\s*version\s+"' Formula/fai.rb \
| head -1 | sed -E 's/.*"([^"]+)".*/\1/')
echo "version=$CUR" >> "$GITHUB_OUTPUT"
- name: Rewrite Formula/fai.rb
id: rewrite
if: |
steps.manifest.outputs.skip != 'true'
&& steps.manifest.outputs.version != steps.current.outputs.version
env:
NEW_VERSION: ${{ steps.manifest.outputs.version }}
NEW_SHA_AARCH64: ${{ steps.manifest.outputs.sha_aarch64 }}
NEW_SHA_X86_64: ${{ steps.manifest.outputs.sha_x86_64 }}
run: |
set -eu
python3 - <<'PY'
import os, re, pathlib
p = pathlib.Path("Formula/fai.rb")
src = p.read_text()
new_version = os.environ["NEW_VERSION"]
arm_sha = os.environ["NEW_SHA_AARCH64"]
x64_sha = os.environ["NEW_SHA_X86_64"]
# version line
src = re.sub(r'(\bversion\s+)"[^"]+"',
f'\\1"{new_version}"', src, count=1)
# find the two sha256 lines, one in the arm branch, one in
# the else branch. The formula's structure is fixed —
# aarch64 block comes first.
lines = src.splitlines()
replaced = 0
for i, line in enumerate(lines):
m = re.match(r'(\s*sha256\s+)"[^"]+"', line)
if not m:
continue
sha = arm_sha if replaced == 0 else x64_sha
lines[i] = f'{m.group(1)}"{sha}"'
replaced += 1
if replaced == 2:
break
if replaced != 2:
raise SystemExit(f"expected 2 sha256 lines, rewrote {replaced}")
p.write_text("\n".join(lines) + "\n")
PY
echo "rewritten=true" >> "$GITHUB_OUTPUT"
- name: Commit + push
if: steps.rewrite.outputs.rewritten == 'true'
env:
NEW_VERSION: ${{ steps.manifest.outputs.version }}
run: |
set -eu
git config user.email "platform@flemming.ai"
git config user.name "fai-tap-bot"
git add Formula/fai.rb
git commit -s -m "chore: formula -> v${NEW_VERSION}"
git push origin "HEAD:${GITHUB_REF_NAME}"