Snapshot Releases
October 18, 2025 ยท View on GitHub
Temporary test versions for PR testing. Version format:
0.0.0-{tag}-{timestamp}-{sha}
๐ฏ Quick Cheatsheet
# Most common usage - just copy & paste:
pnpm exec changeset # 1. Create changeset (select packages)
./scripts/snapshot-release.sh my-feature # 2. Publish snapshot (asks for confirmation)
# Other options:
./scripts/snapshot-release.sh # Use branch name as tag
./scripts/snapshot-release.sh --dry-run # Preview only, no publishing
./scripts/snapshot-release.sh --yes # Skip confirmation (for CI)
That's it! The script handles everything else - versions, publishing, cleanup.
Prerequisites
You need at least one changeset for packages to publish. If you forget, the script will remind you.
๐ก Why snapshots instead of prerelease mode?
| Snapshots | Prerelease Mode |
|---|---|
| โ No state files | โ Manages pre.json |
| โ No commits | โ Requires commits |
| โ Branch stays clean | โ Branch has version changes |
| โ One command | โ Enter/exit commands |
| โ Can't hit "latest" | โ ๏ธ Risk of "latest" publish |
Installation
The script outputs exact install commands at the end - just copy and paste!
Example output:
npm install @pgflow/core@0.0.0-my-feature-20240101120000-abc1234
npm install pgflow@0.0.0-my-feature-20240101120000-abc1234
npm install @pgflow/client@0.0.0-my-feature-20240101120000-abc1234
npm install @pgflow/dsl@0.0.0-my-feature-20240101120000-abc1234
# For Deno/Supabase Edge Functions:
import { EdgeWorker } from "jsr:@pgflow/edge-worker@0.0.0-my-feature-20240101120000-abc1234"
Note
npm packages are published with dist-tag "snapshot" to protect the "latest" tag.
Always use exact versions - never install with @snapshot.
Available Scripts
snapshot-release.sh
Main script for creating snapshot releases locally or in CI.
Options:
| Flag | Description | Default |
|---|---|---|
[tag] | Custom snapshot tag | Branch name |
--dry-run | Preview only, don't publish | false |
--yes, -y | Skip confirmation prompt | false |
--no-cleanup | Don't restore files after publishing | false |
--help | Show usage | - |
Examples:
./scripts/snapshot-release.sh # Uses branch name, asks for confirmation
./scripts/snapshot-release.sh my-feature # Custom tag, asks for confirmation
./scripts/snapshot-release.sh my-feature --dry-run # Preview only, no publishing
./scripts/snapshot-release.sh my-feature --yes # Skip confirmation
Output:
- Shows formatted version breakdown with timestamp and commit SHA
- Lists all packages being published with exact versions
- Interactive confirmation prompt before publishing (unless --yes)
- Prints ready-to-use install commands with colored output
- Uses "snapshot" dist-tag to protect "latest" (but you always install by version)
snapshot-release-ci.sh
CI-specific wrapper that auto-detects environment and generates PR comments.
Features:
- ๐ Auto-detects PR number/branch from CI environment
- ๐ Generates installation instructions
- ๐ฌ Outputs to GitHub Actions summary
- ๐ค Supports GitHub Actions, GitLab CI, CircleCI
Usage:
./scripts/snapshot-release-ci.sh # No arguments needed
Output: Creates markdown file with installation instructions for PR comments.
How It Works
๐ง Technical Details
- Creates versions:
changeset version --snapshotโ0.0.0-{tag}-{timestamp}-{sha} - Syncs JSR: Runs
update-jsr-json-version.sh - Publishes: npm with "snapshot" tag (protects "latest"), then JSR
- Cleans up: Automatically reverts all version changes via trap (even on errors!)
- Uses
git restore --source=HEADfor reliable cleanup (falls back togit checkoutfor older git) - Branch always stays clean
- Works in CI and locally
- Uses
Best Practices
Tip
- Test with
--dry-runfirst - Use descriptive tags:
fix-auth,feature-api - Document snapshot version in PR description
- Clean up old snapshots periodically
Troubleshooting
๐ "No unreleased changesets found"
Snapshot releases require changesets to work. Create one first:
pnpm exec changeset # Select packages and describe changes
๐ "Changesets CLI not found"
pnpm add -D @changesets/cli
๐ "You have uncommitted changes"
Changesets will warn about uncommitted changes. You can:
- Answer "y" to continue anyway (recommended for local testing)
- Or commit your changes first:
git add . && git commit -m 'Your message'
๐ JSR publish fails
- Run
jsr login - Check edge-worker has jsr.json
- Script already uses
--allow-slow-types
๐ Versions not updated
- Make
update-jsr-json-version.shexecutable - Install jq:
brew install jqorapt install jq