WitNote / RELEASE.md
AUXteam's picture
Upload folder using huggingface_hub
6a7089a verified
# Release Process
**⚠️ CRITICAL:** The npm package depends on Go binaries being in the GitHub release. The release pipeline will fail hard if goreleaser doesn't upload binaries β€” npm users won't get a working binary.
Pinchtab uses an automated CI/CD pipeline triggered by Git tags. When you push a tag like `v0.7.0`, GitHub Actions:
1. **Builds Go binaries** β€” darwin-arm64, darwin-x64, linux-x64, linux-arm64, windows-x64
2. **Creates GitHub release** β€” with checksums.txt for integrity verification
3. **Publishes to npm** β€” TypeScript SDK with auto-download postinstall script
4. **Builds Docker images** β€” linux/amd64, linux/arm64
## Prerequisites
### Secrets (configure once in GitHub)
Go to **Settings β†’ Secrets and variables β†’ Actions** and add:
- **NPM_TOKEN** β€” npm authentication token
- Create at https://npmjs.com/settings/~/tokens
- Scope: `automation` (publish + read)
- **DOCKERHUB_USER** β€” Docker Hub username (if using Docker Hub)
- **DOCKERHUB_TOKEN** β€” Docker Hub personal access token
### Local setup
```bash
# 1. Ensure main branch is up to date
git checkout main && git pull origin main
# 2. Merge feature branches
# (all features should be on main before tagging)
# 3. Verify version consistency
cat package.json | jq .version # npm package
cat go.mod | grep "module" # Go module
git describe --tags # latest tag
```
## Pre-Release Checklist
Goreleaser is already configured correctly. Verify before tagging:
```bash
# 1. Check builds section (compiles for all platforms)
grep -A 8 "^builds:" .goreleaser.yml
# Should output: linux/darwin/windows + amd64/arm64
# 2. Check archives use binary format (required for npm)
grep -A 5 "^archives:" .goreleaser.yml
# Should show: format: binary (not tar/zip)
# 3. Verify checksums enabled
grep "checksum:" .goreleaser.yml
# Should output: name_template: checksums.txt
# 4. Check release config
grep -A 2 "^release:" .goreleaser.yml
# Should output: GitHub owner/repo
```
**Configuration status:**
- βœ… `builds:` section compiles all platforms (darwin-arm64, darwin-amd64, linux-arm64, linux-amd64, windows-amd64, windows-arm64)
- βœ… `archives:` outputs binaries directly: `pinchtab-darwin-arm64`, `pinchtab-linux-x64`, etc.
- βœ… `checksum:` generates `checksums.txt` (used by npm postinstall verification)
- βœ… `release:` points to GitHub (uploads everything automatically)
**Ready to release.** Just tag and push.
## Releasing
### For patch/minor versions (recommended)
```bash
# 1. Bump version in all places
npm version patch # or minor, major
git push origin main
# 2. Create tag
git tag v0.7.1
git push origin v0.7.1
```
### For manual releases
```bash
# 1. Tag directly
git tag -a v0.7.1 -m "Release v0.7.1"
git push origin v0.7.1
# 2. Or via GitHub UI: Releases β†’ Create from tag
# (workflow will auto-create if not present)
```
### Using workflow_dispatch (manual trigger)
If you need to re-release an existing tag:
1. Go to **Actions β†’ Release**
2. **Run workflow**
3. Enter tag (e.g. `v0.7.1`)
For a no-side-effects dry run from `main` or any other ref:
1. Go to **Actions β†’ Release**
2. **Run workflow**
3. Leave `tag` empty
4. Set `ref` to the branch, tag, or commit you want to test
5. Set `dry_run` to `true`
Dry-run behavior:
- GoReleaser runs in snapshot mode, so artifacts are built but not published
- npm runs `npm publish --dry-run`
- Docker runs a multi-arch `buildx` build with `push=false`
- ClawHub skill publishing is not part of this workflow and is therefore skipped
## Pipeline details
### 1. Goreleaser (Go binary) β€” CRITICAL for npm
Triggered on `v*` tag push. Builds binaries and creates GitHub release.
**What it does:**
- βœ… Compiles for all platforms (darwin-arm64, darwin-x64, linux-x64, linux-arm64, windows-x64)
- βœ… Generates `checksums.txt` (SHA256)
- βœ… **Uploads binaries to GitHub Releases** ← Required by npm postinstall!
- Also: Docker images, changelog, etc.
**⚠️ CRITICAL:** npm postinstall script downloads binaries from GitHub Releases. If the release doesn't have the binaries (e.g., only Docker images), `npm install pinchtab` will fail silently and the binary won't be available.
**Configured in:** `.goreleaser.yml`
**Verify release has binaries:**
```bash
curl -s https://api.github.com/repos/pinchtab/pinchtab/releases/v0.7.0 | jq '.assets[].name'
# Should output: pinchtab-darwin-arm64, pinchtab-darwin-x64, etc.
```
### 2. npm publish
Depends on: `release` job (waits for goreleaser to finish)
**What it does:**
- Syncs version from tag (v0.7.0 β†’ 0.7.0)
- Builds TypeScript (`npm run build`)
- Publishes to npm registry
- Users get postinstall script that downloads binaries from GitHub Releases
**User flow on `npm install pinchtab`:**
```
1. npm downloads @pinchtab/cli package
2. Runs postinstall script
3. Script detects OS/arch (darwin-arm64, linux-x64, etc.)
4. Downloads binary from GitHub release
5. Verifies SHA256 checksum
6. Stores in ~/.pinchtab/bin/0.7.0/pinchtab-<os>-<arch>
7. Makes executable
8. If ANY STEP fails β†’ npm install fails (exit 1)
```
**⚠️ REQUIRES:** Goreleaser must have successfully uploaded binaries to GitHub release. The npm postinstall will verify this and fail hard if binaries are missing.
### 3. Docker
GitHub Actions builds the release image directly from the tagged source with `docker buildx`.
The workflow pushes the same multi-arch build to both GHCR and Docker Hub, so Docker no longer depends on GoReleaser's temporary build context.
### 4. ClawHub skill
The main `Release` workflow publishes the Pinchtab skill to ClawHub only after both npm and Docker complete successfully.
The standalone `Publish Skill` workflow is manual-only and is intended for retries or one-off recovery publishes.
## Troubleshooting
### npm publish fails (403)
- Check **NPM_TOKEN** is set in secrets
- Verify token has `automation` scope
- Check you're not already published (can't overwrite existing version)
### Binary checksum mismatch
- goreleaser must generate `checksums.txt`
- Verify `.goreleaser.yml` has `checksum:` section
- Check GitHub release includes `checksums.txt`
### Docker push fails
- Verify DOCKERHUB_USER and DOCKERHUB_TOKEN
- Check token has permission to push
## Rolling back
If something goes wrong:
```bash
# Delete the tag locally and on GitHub
git tag -d v0.7.1
git push origin :refs/tags/v0.7.1
# Delete npm version (requires owner permission)
npm unpublish pinchtab@0.7.1
# Revert any commits
git revert <commit>
git push origin main
# Retag when ready
git tag v0.7.1
git push origin v0.7.1
```
## Version strategy
- Use **semantic versioning**: v0.7.0 (major.minor.patch)
- Tag on main branch only
- One tag = one release (all artifacts)
- npm version must match Go binary tag
## See also
- `.github/workflows/release.yml` β€” GitHub Actions workflow
- `.goreleaser.yml` β€” Go binary release config
- `npm/package.json` β€” npm package metadata