Skip to content

Commit 6a0926a

Browse files
committed
Add Homebrew formula update script and release docs
1 parent 97ed3d0 commit 6a0926a

2 files changed

Lines changed: 150 additions & 0 deletions

File tree

docs/releasing.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# Releasing
2+
3+
Pushing a `v*` tag triggers the release workflow, which builds and publishes all artifacts: Rust binaries, VSIX, npm tarballs, LSP and tree-sitter outputs. Everything ships from a single tag.
4+
5+
Not every artifact needs manual follow-up. The Homebrew formula is the only piece that requires a separate update after CI finishes.
6+
7+
## What goes where
8+
9+
| Artifact | Destination | Needs manual step? |
10+
|---|---|---|
11+
| Rust CLI binaries (4 platforms) | GitHub release | No (CI publishes) |
12+
| VSIX | GitHub release | No (CI publishes) |
13+
| npm tarballs (allium-cli, allium-lsp, tree-sitter) | GitHub release | No (CI publishes) |
14+
| Homebrew formula | homebrew-allium tap | Yes |
15+
16+
## Steps
17+
18+
1. **Bump versions** with `scripts/version-bump.sh`:
19+
20+
```bash
21+
./scripts/version-bump.sh 1.0.0
22+
```
23+
24+
2. **Commit, tag and push:**
25+
26+
```bash
27+
git add -A && git commit -m "v1.0.0"
28+
git tag v1.0.0
29+
git push origin main --tags
30+
```
31+
32+
3. **Wait for CI** to build and attach release artifacts.
33+
34+
4. **Update the Homebrew tap:**
35+
36+
```bash
37+
./scripts/update-homebrew-formula.sh 1.0.0
38+
```
39+
40+
This downloads the four platform tarballs, computes SHA256 checksums and rewrites the formula. Pass `--dry-run` to preview without modifying the file.
41+
42+
5. **Push the tap repo:**
43+
44+
```bash
45+
cd ~/Code/homebrew-allium
46+
git add -A && git commit -m "allium 1.0.0"
47+
git push
48+
```
49+
50+
## When to release
51+
52+
All core-tier packages share a major.minor version (see `VERSIONING.md`). Right now, every release cuts a single tag and publishes everything. This means a tree-sitter bugfix produces new Rust binaries even if nothing changed in the Rust crates, and vice versa.
53+
54+
This is fine while the project is small. If the coupling becomes a problem, the natural split is separate tags per artifact group (e.g. `cli-v1.0.1`, `vscode-v0.3.0`), each triggering only its own CI job. That would also let the Homebrew update script run automatically as a post-release workflow step rather than requiring a manual invocation.

scripts/update-homebrew-formula.sh

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
# Update the Homebrew formula with checksums from a GitHub release.
5+
#
6+
# Usage:
7+
# ./scripts/update-homebrew-formula.sh [--dry-run] <version> [tap-path]
8+
#
9+
# Examples:
10+
# ./scripts/update-homebrew-formula.sh 1.0.0
11+
# ./scripts/update-homebrew-formula.sh --dry-run 0.1.4
12+
# ./scripts/update-homebrew-formula.sh 1.0.0 ~/Code/homebrew-allium
13+
14+
REPO="juxt/allium-tools"
15+
TARGETS=(
16+
aarch64-apple-darwin
17+
x86_64-apple-darwin
18+
aarch64-unknown-linux-gnu
19+
x86_64-unknown-linux-gnu
20+
)
21+
22+
DRY_RUN=false
23+
VERSION=""
24+
TAP_PATH=""
25+
26+
for arg in "$@"; do
27+
case "$arg" in
28+
--dry-run) DRY_RUN=true ;;
29+
-*) echo "Unknown flag: $arg" >&2; exit 1 ;;
30+
*)
31+
if [[ -z "$VERSION" ]]; then
32+
VERSION="$arg"
33+
else
34+
TAP_PATH="$arg"
35+
fi
36+
;;
37+
esac
38+
done
39+
40+
if [[ -z "$VERSION" ]]; then
41+
echo "Usage: update-homebrew-formula.sh [--dry-run] <version> [tap-path]" >&2
42+
exit 1
43+
fi
44+
45+
if ! [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
46+
echo "Error: version must be in semver format (e.g. 1.0.0)" >&2
47+
exit 1
48+
fi
49+
50+
# Default tap path: sibling directory to this repo
51+
if [[ -z "$TAP_PATH" ]]; then
52+
TAP_PATH="$(cd "$(dirname "$0")/../.." && pwd)/homebrew-allium"
53+
fi
54+
55+
FORMULA="$TAP_PATH/Formula/allium.rb"
56+
57+
if [[ ! -f "$FORMULA" ]]; then
58+
echo "Error: formula not found at $FORMULA" >&2
59+
exit 1
60+
fi
61+
62+
echo "Fetching checksums for v$VERSION..."
63+
64+
declare -A CHECKSUMS
65+
for target in "${TARGETS[@]}"; do
66+
url="https://github.com/$REPO/releases/download/v$VERSION/allium-$target.tar.gz"
67+
echo " $target"
68+
sha=$(curl -fsSL "$url" | shasum -a 256 | awk '{print $1}')
69+
CHECKSUMS[$target]="$sha"
70+
done
71+
72+
echo ""
73+
echo "Checksums:"
74+
for target in "${TARGETS[@]}"; do
75+
echo " $target: ${CHECKSUMS[$target]}"
76+
done
77+
echo ""
78+
79+
if $DRY_RUN; then
80+
echo "(dry run — formula not modified)"
81+
exit 0
82+
fi
83+
84+
# Update version
85+
sed -i '' "s/^ version \".*\"/ version \"$VERSION\"/" "$FORMULA"
86+
87+
# Update checksums using the placeholder/previous values
88+
for target in "${TARGETS[@]}"; do
89+
# Convert target to the placeholder name: hyphens to underscores, uppercase
90+
placeholder=$(echo "$target" | tr '-' '_' | tr '[:lower:]' '[:upper:]')
91+
sha="${CHECKSUMS[$target]}"
92+
# Replace either a placeholder or a previous 64-char hex hash on the line following the matching URL
93+
sed -i '' "/allium-${target}\.tar\.gz/{ n; s/sha256 \"[^\"]*\"/sha256 \"${sha}\"/; }" "$FORMULA"
94+
done
95+
96+
echo "Updated $FORMULA to v$VERSION"

0 commit comments

Comments
 (0)