Add full release automation script

Amp-Thread-ID: https://ampcode.com/threads/T-789d9ba6-2aea-4ee9-b4dc-ce73e8f496f4
Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
Steve Yegge
2025-10-25 16:57:15 -07:00
parent d31e9e7156
commit a91467d2fb
3 changed files with 306 additions and 1 deletions

View File

@@ -2,7 +2,25 @@
Quick guide for releasing a new version of beads.
## Pre-Release Checklist
## 🚀 The Easy Way (Recommended)
Use the fully automated release script:
```bash
./scripts/release.sh 0.9.3
```
This does **everything**: version bump, tests, git tag, Homebrew update, and local installation.
See [scripts/README.md](scripts/README.md#releasesh--the-easy-button) for details.
---
## 📋 The Manual Way
If you prefer step-by-step control:
### Pre-Release Checklist
1. **Kill all running daemons (CRITICAL)**:
```bash

View File

@@ -2,6 +2,71 @@
Utility scripts for maintaining the beads project.
## release.sh (⭐ The Easy Button)
**One-command release** from version bump to local installation.
### Usage
```bash
# Full release (does everything)
./scripts/release.sh 0.9.3
# Preview what would happen
./scripts/release.sh 0.9.3 --dry-run
```
### What It Does
This master script automates the **entire release process**:
1. ✅ Kills running daemons (avoids version conflicts)
2. ✅ Runs tests and linting
3. ✅ Bumps version in all files
4. ✅ Commits and pushes version bump
5. ✅ Creates and pushes git tag
6. ✅ Updates Homebrew formula
7. ✅ Upgrades local brew installation
8. ✅ Verifies everything works
**After this script completes, your system is running the new version!**
### Examples
```bash
# Release version 0.9.3
./scripts/release.sh 0.9.3
# Preview a release (no changes made)
./scripts/release.sh 1.0.0 --dry-run
```
### Prerequisites
- Clean git working directory
- All changes committed
- golangci-lint installed
- Homebrew installed (for local upgrade)
- Push access to steveyegge/beads and steveyegge/homebrew-beads
### Output
The script provides colorful, step-by-step progress output:
- 🟨 Yellow: Current step
- 🟩 Green: Step completed
- 🟥 Red: Errors
- 🟦 Blue: Section headers
### What Happens Next
After the script finishes:
- GitHub Actions builds binaries for all platforms (~5 minutes)
- PyPI package is published automatically
- Users can `brew upgrade bd` to get the new version
- GitHub Release is created with binaries and changelog
---
## bump-version.sh
Bumps the version number across all beads components in a single command.

222
scripts/release.sh Executable file
View File

@@ -0,0 +1,222 @@
#!/bin/bash
set -euo pipefail
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
usage() {
cat << EOF
Usage: $0 <version> [--dry-run]
Fully automate a beads release from version bump to local installation.
Arguments:
version Version number (e.g., 0.9.3)
--dry-run Show what would happen without making changes
This script performs the complete release workflow:
1. Kill running daemons
2. Run tests and linting
3. Bump version in all files
4. Commit and push version bump
5. Create and push git tag
6. Update Homebrew formula
7. Upgrade local brew installation
8. Verify everything is working
Examples:
$0 0.9.3 # Full release
$0 0.9.3 --dry-run # Preview what would happen
After this script completes, your system will be running the new version!
EOF
exit 1
}
# Parse arguments
DRY_RUN=false
VERSION=""
for arg in "$@"; do
case $arg in
--dry-run)
DRY_RUN=true
shift
;;
*)
if [ -z "$VERSION" ]; then
VERSION="$arg"
fi
shift
;;
esac
done
if [ -z "$VERSION" ]; then
usage
fi
# Strip 'v' prefix if present
VERSION="${VERSION#v}"
echo -e "${BLUE}╔═══════════════════════════════════════════════════════════════╗${NC}"
echo -e "${BLUE}${NC} ${GREEN}Beads Full Release Automation${NC} ${BLUE}${NC}"
echo -e "${BLUE}${NC} Version: ${YELLOW}v${VERSION}${NC} ${BLUE}${NC}"
if [ "$DRY_RUN" = true ]; then
echo -e "${BLUE}${NC} ${YELLOW}Mode: DRY RUN (no changes will be made)${NC} ${BLUE}${NC}"
fi
echo -e "${BLUE}╔═══════════════════════════════════════════════════════════════╗${NC}"
echo ""
# Step 1: Kill daemons
echo -e "${YELLOW}Step 1/8: Killing running daemons...${NC}"
if [ "$DRY_RUN" = true ]; then
echo "[DRY RUN] Would run: pkill -f 'bd.*daemon'"
else
pkill -f "bd.*daemon" 2>/dev/null || true
sleep 1
if pgrep -lf "bd.*daemon" > /dev/null 2>&1; then
echo -e "${RED}✗ Daemons still running${NC}"
pgrep -lf "bd.*daemon"
exit 1
fi
fi
echo -e "${GREEN}✓ All daemons stopped${NC}\n"
# Step 2: Run tests
echo -e "${YELLOW}Step 2/8: Running tests and linting...${NC}"
if [ "$DRY_RUN" = true ]; then
echo "[DRY RUN] Would run: TMPDIR=/tmp go test ./..."
echo "[DRY RUN] Would run: golangci-lint run ./..."
else
if ! TMPDIR=/tmp go test ./...; then
echo -e "${RED}✗ Tests failed${NC}"
exit 1
fi
if ! golangci-lint run ./...; then
echo -e "${YELLOW}⚠ Linting warnings (see LINTING.md for baseline)${NC}"
fi
fi
echo -e "${GREEN}✓ Tests passed${NC}\n"
# Step 3: Bump version
echo -e "${YELLOW}Step 3/8: Bumping version to ${VERSION}...${NC}"
if [ "$DRY_RUN" = true ]; then
echo "[DRY RUN] Would run: $SCRIPT_DIR/bump-version.sh $VERSION --commit"
$SCRIPT_DIR/bump-version.sh "$VERSION" 2>/dev/null || true
else
if ! $SCRIPT_DIR/bump-version.sh "$VERSION" --commit; then
echo -e "${RED}✗ Version bump failed${NC}"
exit 1
fi
fi
echo -e "${GREEN}✓ Version bumped and committed${NC}\n"
# Step 4: Rebuild local binary
echo -e "${YELLOW}Step 4/8: Rebuilding local binary...${NC}"
if [ "$DRY_RUN" = true ]; then
echo "[DRY RUN] Would run: go build -o bd ./cmd/bd"
else
if ! go build -o bd ./cmd/bd; then
echo -e "${RED}✗ Build failed${NC}"
exit 1
fi
BUILT_VERSION=$(./bd version 2>/dev/null | head -1)
echo "Built version: $BUILT_VERSION"
fi
echo -e "${GREEN}✓ Binary rebuilt${NC}\n"
# Step 5: Push version bump
echo -e "${YELLOW}Step 5/8: Pushing version bump to GitHub...${NC}"
if [ "$DRY_RUN" = true ]; then
echo "[DRY RUN] Would run: git push origin main"
else
if ! git push origin main; then
echo -e "${RED}✗ Push failed${NC}"
exit 1
fi
fi
echo -e "${GREEN}✓ Version bump pushed${NC}\n"
# Step 6: Create and push tag
echo -e "${YELLOW}Step 6/8: Creating and pushing git tag v${VERSION}...${NC}"
if [ "$DRY_RUN" = true ]; then
echo "[DRY RUN] Would run: git tag v${VERSION}"
echo "[DRY RUN] Would run: git push origin v${VERSION}"
else
if git rev-parse "v${VERSION}" >/dev/null 2>&1; then
echo -e "${YELLOW}⚠ Tag v${VERSION} already exists, skipping tag creation${NC}"
else
git tag "v${VERSION}"
fi
if ! git push origin "v${VERSION}"; then
echo -e "${RED}✗ Tag push failed${NC}"
exit 1
fi
fi
echo -e "${GREEN}✓ Tag v${VERSION} pushed${NC}\n"
# Wait for GitHub to generate tarball
if [ "$DRY_RUN" = false ]; then
echo -e "${YELLOW}Waiting 10 seconds for GitHub to generate release tarball...${NC}"
sleep 10
fi
# Step 7: Update Homebrew formula
echo -e "${YELLOW}Step 7/8: Updating Homebrew formula...${NC}"
if [ "$DRY_RUN" = true ]; then
echo "[DRY RUN] Would run: $SCRIPT_DIR/update-homebrew.sh ${VERSION}"
else
if ! $SCRIPT_DIR/update-homebrew.sh "$VERSION"; then
echo -e "${RED}✗ Homebrew update failed${NC}"
exit 1
fi
fi
echo -e "${GREEN}✓ Homebrew formula updated${NC}\n"
# Step 8: Upgrade local installation
echo -e "${YELLOW}Step 8/8: Upgrading local Homebrew installation...${NC}"
if [ "$DRY_RUN" = true ]; then
echo "[DRY RUN] Would run: brew update"
echo "[DRY RUN] Would run: brew upgrade bd"
else
brew update
# Check if bd is installed via brew
if brew list bd >/dev/null 2>&1; then
brew upgrade bd || brew reinstall bd
else
echo -e "${YELLOW}⚠ bd not installed via Homebrew, skipping upgrade${NC}"
echo "To install: brew install steveyegge/beads/bd"
fi
fi
echo -e "${GREEN}✓ Local installation upgraded${NC}\n"
# Final verification
echo -e "${BLUE}═══════════════════════════════════════════════════════════════${NC}"
echo -e "${GREEN}✓ Release Complete!${NC}\n"
if [ "$DRY_RUN" = false ]; then
echo "Verification:"
echo " Installed version: $(bd version 2>/dev/null | head -1 || echo 'Error getting version')"
echo ""
echo "Next steps:"
echo " • GitHub Actions is building release binaries"
echo " • Monitor: https://github.com/steveyegge/beads/actions"
echo " • PyPI publish happens automatically"
echo " • Update CHANGELOG.md if not done yet"
echo ""
echo "Your system is now running v${VERSION}!"
else
echo "[DRY RUN] No changes were made."
echo "Run without --dry-run to perform the actual release."
fi
echo -e "${BLUE}═══════════════════════════════════════════════════════════════${NC}"