Skip to content

Ship a prebuilt Homebrew bottle on release; drop install.sh#69

Merged
alexkroman merged 13 commits into
mainfrom
bottle-release-pipeline
Jun 11, 2026
Merged

Ship a prebuilt Homebrew bottle on release; drop install.sh#69
alexkroman merged 13 commits into
mainfrom
bottle-release-pipeline

Conversation

@alexkroman

Copy link
Copy Markdown
Collaborator

Summary

Make brew install assembly / brew upgrade assembly a fast prebuilt install for Mac developers, and simplify the install story to two paths.

  • Add .github/workflows/release.yml — a tag-triggered pipeline. On a vX.Y.Z tag push: the bottle job (macOS arm64, arm64_sonoma) pins the formula to the tag source, builds a Homebrew bottle, and merges the bottle do block into Formula/assembly.rb; the publish job creates the GitHub Release with the bottle attached and opens a release/<tag>-formula PR. Uses only the built-in GITHUB_TOKEN (no special secret) — a maintainer merges the formula PR with the admin override (a GITHUB_TOKEN PR doesn't trigger CI). Release-create + branch/PR steps are idempotent so a retried run doesn't fail.
  • Why a bottle: the formula vendors sdists, so a from-source brew install drags in rustllvm/z3/libgit2 and a second python@3.14 just to compile pydantic-core/jiter/cryptography. A bottle skips all of that. (pipx/uv were never affected — they pull prebuilt dependency wheels from PyPI.)
  • Remove the install.sh one-liner and everything supporting it: the script, its unit + smoke tests, the install_script pytest marker, the install-smoke CI job, and the .pre-commit-config.yaml/doc references. Install is now Homebrew bottle (primary) + pipx/uv git+https (fallback).
  • Docs: rewrite the release-prep skill for the tag→bottle→formula-PR flow; note the bottle in the README; add brew trust assemblyai/cli and drop --HEAD from the Homebrew instructions. Design spec + implementation plan under docs/superpowers/.

Scope is deliberately lean: arm64 macOS bottle only (Apple Silicon is the dominant brew audience; Intel Mac + Linux fall back to source or pipx/uv), GitHub Releases hosting, no release wheels / moving tag / PEP 503 index.

Test Plan

  • ./scripts/check.shAll checks passed. (1536 tests, 99.45% coverage; diff-cover + mutation gate have no changed aai_cli lines)
  • actionlint + zizmor clean on release.yml; all four uses: SHA-pinned; no ${{ }} interpolated in run: bodies
  • Formula pin regex verified against the real sha256 "0" * 64 placeholder (replaces the whole line, leaves resource sha256s untouched)
  • No stray install.sh / install_script references remain
  • Follow-up (real v0.1.0 tag): push the tag, confirm release.yml builds the bottle + opens the formula PR, merge it, then brew install assembly on a clean arm64 Mac pulls the bottle with no rust/llvm in brew deps

🤖 Generated with Claude Code

alexkroman-assembly and others added 13 commits June 11, 2026 13:34
Tag-triggered release.yml that builds the Python wheel/sdist + an arm64
macOS bottle, publishes them to the GitHub Release, and finalizes the
Homebrew formula (url + sha256 + bottle block) so `brew install assembly`
stops compiling the Rust deps from source.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Drop release wheels/sdist, the moving stable tag, and the PEP 503 index;
pipx/uv stay on git+https. Add install.sh removal. Reframe around the goal:
simplest install/upgrade for Mac devs, minimal CI.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Homebrew (bottle) + pipx/uv git+https are the supported install paths;
drop the curl|sh installer, its unit + smoke tests, the install_script
marker, and the install-smoke CI job.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The .pre-commit-config.yaml was missed by the removal grep (.yaml vs .yml);
align its pytest -m filter with check.sh (exclude e2e + install) and fix the
stale install.sh comments.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
release.yml builds an arm64 macOS bottle on a vX.Y.Z tag, publishes it to
the GitHub Release, and opens a formula PR (url+sha256+bottle block) for a
maintainer to merge. Built-in GITHUB_TOKEN only; no special secret.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Match ci.yml's convention (monorepo subpath, no vX tag).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- sha256 pin now consumes the whole placeholder line (matches formula-install);
  the old [0-9a-f]* regex left '* 64 # ...' dangling on the first release.
- guard for exactly one bottle tarball before merge.
- gh release create/upload and the formula branch/PR are now idempotent so a
  retried publish job doesn't die on 'already exists'.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Release is now: version-bump PR -> tag push -> release.yml builds the
bottle + opens the formula PR -> admin-merge. Drop the install.sh smoke
step and the squatted-PyPI install.sh caveat.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Minor markdown style (MD032). Not gate-enforced (.claude/ is outside the
markdownlint glob), just consistent list formatting.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
cut_release.sh derives the version from pyproject.toml and tags/pushes only
when the tree is clean, on main, and in sync with origin (gated by shellcheck).
README's Development section gains a Releasing runbook (and fixes the stale
`uv sync --extra dev`, which errors — dev is a dependency-group); release-prep
step 3 now calls the script.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@alexkroman alexkroman enabled auto-merge (squash) June 11, 2026 21:42
@alexkroman alexkroman merged commit 052ad2e into main Jun 11, 2026
9 checks passed
@alexkroman alexkroman deleted the bottle-release-pipeline branch June 11, 2026 21:45
alexkroman added a commit that referenced this pull request Jun 11, 2026
DX improvements mined from recent sessions:

- Add a PreToolUse(Bash) hook that blocks `git commit` unless ./scripts/check.sh
  passed for the current working tree. check.sh now records a tree signature
  (scripts/gate_marker.py) into .git/aai-gate-pass on success; the hook
  (.claude/hooks/require-gate-before-commit.sh) re-verifies it. The signature is
  staging-invariant but edit-sensitive, so any change after the gate re-requires
  a green run. Escape hatch for deliberate WIP commits: AAI_ALLOW_COMMIT=1.
- Document the tag-triggered release/Homebrew-bottle pipeline in AGENTS.md
  (release.yml, cut_release.sh, bump_minor.sh, update_check.py) — it was
  committed in #69/#70 but undocumented.

gate_marker.py is stdlib-only (runs from the hook and from check.sh without uv);
both new shell paths are added to check.sh's shellcheck list.

Co-authored-by: Alex Kroman <alex@assemblyai.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants