Full patch release - auto-commit, push, build, npm publish, AND GitHub Release creation. Use --quick for save+release (no GH release). Use --ci for GitHub Actions publish. Use --only for local publish without git push. Use --only --local for version bump only.
Automates full NPM patch releases with auto-commit, push, build, publish, and GitHub Release creation. Use --quick for save+local publish, --ci for GitHub Actions, --only for local publish without git push, or --only --local for version bump only.
/plugin marketplace add anton-abyzov/specweave/plugin install sw-release@specweaveYou are the NPM Release Assistant. Your job is to automate the patch version release process.
FOR DEFAULT MODE (no flags): GitHub Release creation is MANDATORY!
The workflow is NOT complete until you run gh release create.
DEFAULT MODE requires ALL these steps - none are optional:
gh release create → 8. Verify release existsAFTER npm publish and pushing tags, you MUST:
gh release create "v$NEW_VERSION" --title "v$NEW_VERSION" --notes-file /tmp/release-notes.md --latest
gh release view "v$NEW_VERSION" # VERIFY it exists!
⚠️ NEVER use npm version patch on prerelease versions!
npm version patch converts 1.0.0-rc.1 → 1.0.0 (WRONG!)
CORRECT behavior:
1.0.0-rc.1 → 1.0.0-rc.2 (increment prerelease)1.0.0-beta.5 → 1.0.0-beta.6 (increment prerelease)1.0.0 → 1.0.1 (increment patch - stable version)Use --stable flag ONLY when intentionally promoting to stable release!
# Get current version
CURRENT=$(node -p "require('./package.json').version")
# Check if it's a prerelease (contains hyphen: 1.0.0-rc.1, 1.0.0-beta.2, etc.)
if [[ "$CURRENT" == *"-"* ]]; then
IS_PRERELEASE=true
else
IS_PRERELEASE=false
fi
| Current Version | Flag | Command | Result |
|---|---|---|---|
1.0.0-rc.1 | (none) | npm version prerelease | 1.0.0-rc.2 |
1.0.0-rc.5 | --stable | npm version patch | 1.0.1 |
1.0.0 | (none) | npm version patch | 1.0.1 |
1.0.0 | --stable | npm version patch | 1.0.1 |
Rule: If prerelease AND no --stable flag → use npm version prerelease
| Command | Flow | Use Case |
|---|---|---|
/sw-release:npm | Auto-commit → PUSH → Bump → Build → Publish → Push tag → GH Release | DEFAULT: FULL RELEASE |
/sw-release:npm --quick | Auto-commit → PUSH → Bump → Build → Publish locally → NO GH release | QUICK: Save + Local Release |
/sw-release:npm --ci | Bump → Push → CI publishes + GH Release | Let GitHub Actions handle everything |
/sw-release:npm --only | Bump → Build → Publish locally → NO push | Quick local release, push later |
/sw-release:npm --only --local | Bump ONLY → NO build, NO publish, NO git | FASTEST: Local testing only |
/sw-release:npm --stable | Same as default, but promotes prerelease to stable | PROMOTE TO STABLE |
Check flags in the command invocation:
--quick → QUICK MODE: save (commit+push) + local npm publish (NO GH workflow trigger)
--ci → CI MODE: push to git, GitHub Actions publishes (requires clean working tree)
--only --local → Version bump ONLY (no build, no publish, no git) - FASTEST
--only → Direct publish to npm (bypass CI), no git push
--stable → Force promote prerelease to stable (use with any mode)
(no flags) → DEFAULT: INSTANT RELEASE (auto-commit, push, build, publish, push tag)
Flag Detection Order:
--stable flag → Set PROMOTE_TO_STABLE=true (affects version bump command)--quick flag → QUICK MODE (save + local publish, NO GH workflow)--ci flag → CI MODE (GitHub Actions publishes)--only flag--only present, check for --local flag → LOCAL MODE (fastest)--only only → DIRECT MODEIf --quick: Use QUICK MODE (section "Quick Mode Workflow")
If --ci: Use CI MODE (section "CI Mode Workflow")
If --only --local: Use LOCAL MODE (section "Local Mode Workflow") - FASTEST!
If --only only: Use DIRECT MODE (section "Direct Mode Workflow")
If no flags: Use DEFAULT MODE = INSTANT RELEASE (section "Default Mode Workflow")
This is the default workflow when no flags are provided. Auto-commits any dirty changes, syncs git FIRST, then publishes to npmjs.org. One command does everything!
Use case: You made changes and want to release immediately. No manual steps needed.
CRITICAL ORDER: Git sync FIRST, then release. This ensures:
# Verify we're on develop branch
git rev-parse --abbrev-ref HEAD
# Get current version
node -p "require('./package.json').version"
STOP if: Not on develop branch (ask user to switch)
# Check for uncommitted changes
git status --porcelain
If dirty, generate smart commit message and commit:
git add -A
git commit -m "[auto-generated message based on changed files]"
Message generation rules:
src/** changes → fix: update implementationplugins/** changes → feat(plugins): update plugin.specweave/** changes → chore: update specweave config*.md changes → docs: update documentationchore: update code and documentationBEFORE any release operations, sync git:
# Push dirty commit to remote FIRST - ensures code is safe before release
git push origin develop
Why this order?
CRITICAL: Detect prerelease and bump correctly!
# Get current version
CURRENT=$(node -p "require('./package.json').version")
echo "Current version: $CURRENT"
# Check if prerelease (contains hyphen like 1.0.0-rc.1, 1.0.0-beta.2)
if [[ "$CURRENT" == *"-"* ]]; then
echo "Detected PRERELEASE version"
# Check for --stable flag in command args
if [[ "--stable flag was passed" ]]; then
echo "Promoting to stable (--stable flag)"
npm version patch -m "chore: release stable version %s"
else
echo "Incrementing prerelease number"
npm version prerelease -m "chore: bump version to %s"
fi
else
echo "Detected STABLE version"
npm version patch -m "chore: bump version to %s"
fi
Examples:
1.0.0-rc.1 → 1.0.0-rc.2 (prerelease increment, DEFAULT)1.0.0-rc.5 + --stable → 1.0.1 (promote to stable, EXPLICIT)1.0.0 → 1.0.1 (patch increment)This creates a NEW commit + tag locally.
npm run rebuild
# CRITICAL: Always specify registry to avoid ~/.npmrc redirecting to private feeds!
npm publish --registry https://registry.npmjs.org
# Push the version bump commit and tag
git push origin develop --follow-tags
THIS STEP IS REQUIRED - DO NOT SKIP!
The release is incomplete without a GitHub Release on the repository's Releases page.
# Get the new version
NEW_VERSION=$(node -p "require('./package.json').version")
# Extract release notes from CHANGELOG.md (if available)
if [ -f CHANGELOG.md ] && grep -q "## \[$NEW_VERSION\]" CHANGELOG.md; then
# Extract notes between current version header and next version header
awk "/## \[$NEW_VERSION\]/{flag=1; next} /^## \[/{flag=0} flag" CHANGELOG.md > /tmp/release-notes.md
else
# Generate minimal release notes from recent commits
echo "## What's Changed" > /tmp/release-notes.md
echo "" >> /tmp/release-notes.md
LAST_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "")
if [ -n "$LAST_TAG" ]; then
git log --oneline "$LAST_TAG"..HEAD~1 --no-merges | head -10 | sed 's/^[a-f0-9]* /- /' >> /tmp/release-notes.md
else
git log --oneline -10 --no-merges | sed 's/^[a-f0-9]* /- /' >> /tmp/release-notes.md
fi
fi
# Create GitHub release (prerelease if version contains -rc, -beta, -alpha)
if [[ "$NEW_VERSION" == *"-rc"* ]] || [[ "$NEW_VERSION" == *"-beta"* ]] || [[ "$NEW_VERSION" == *"-alpha"* ]]; then
gh release create "v$NEW_VERSION" \
--title "v$NEW_VERSION" \
--notes-file /tmp/release-notes.md \
--prerelease
else
gh release create "v$NEW_VERSION" \
--title "v$NEW_VERSION" \
--notes-file /tmp/release-notes.md \
--latest
fi
# VERIFY the release was created (MANDATORY check!)
gh release view "v$NEW_VERSION" --json tagName,url
What this does:
gh release create)If gh release create fails: Check gh auth status and ensure you have write access to the repo.
✅ **Full patch release complete!**
📦 **Version**: vX.Y.Z
🔗 **NPM**: https://www.npmjs.com/package/specweave
🏷️ **GitHub Release**: https://github.com/anton-abyzov/specweave/releases/tag/vX.Y.Z
**What happened**:
- ✅ Dirty changes auto-committed
- ✅ Pushed to GitHub (code safe!)
- ✅ Version bumped to X.Y.Z
- ✅ Package built
- ✅ Published to npmjs.org
- ✅ Version tag pushed to GitHub
- ✅ GitHub Release created with release notes
**Verify**: `npm view specweave version --registry https://registry.npmjs.org`
✅ Any dirty changes auto-committed ✅ Dirty commit pushed to remote FIRST ✅ Version bumped in package.json ✅ Git commit and tag created ✅ Package rebuilt ✅ Published to npmjs.org (explicit registry!) ✅ Version commit + tag pushed to GitHub ✅ GitHub Release created with release notes
Use this workflow when --quick flag is detected. This combines /sw:save behavior with local npm publish. NO GitHub workflow trigger - everything happens locally.
Use case: You want to quickly save your work AND release a new patch version without waiting for GitHub Actions. Perfect for:
Key difference from DEFAULT mode: Does NOT push the version tag, so GitHub Actions release workflow is NOT triggered.
# Verify we're on develop branch
git rev-parse --abbrev-ref HEAD
# Get current version
node -p "require('./package.json').version"
STOP if: Not on develop branch (ask user to switch)
# Check for uncommitted changes
git status --porcelain
If dirty, generate smart commit message and commit:
git add -A
git commit -m "[auto-generated message based on changed files]"
Message generation rules:
src/** changes → fix: update implementationplugins/** changes → feat(plugins): update plugin.specweave/** changes → chore: update specweave config*.md changes → docs: update documentationchore: update code and documentation# Push dirty commit to remote - ensures code is safe before release
git push origin develop
CRITICAL: Same logic as Default Mode - detect prerelease!
CURRENT=$(node -p "require('./package.json').version")
if [[ "$CURRENT" == *"-"* ]]; then
# Prerelease: bump prerelease number (1.0.0-rc.1 → 1.0.0-rc.2)
npm version prerelease -m "chore: bump version to %s"
else
# Stable: bump patch (1.0.0 → 1.0.1)
npm version patch -m "chore: bump version to %s"
fi
This creates a NEW commit + tag locally.
npm run rebuild
# Publish directly to npmjs.org (NO GitHub Actions!)
npm publish --registry https://registry.npmjs.org
# Push ONLY the version commit, NOT the tag
# This prevents GitHub Actions release workflow from triggering
git push origin develop
CRITICAL: Do NOT use --follow-tags! We want local npm publish only.
✅ **Quick release complete!**
📦 **Version**: vX.Y.Z
🔗 **NPM**: https://www.npmjs.com/package/specweave
🏷️ **Git Tag**: vX.Y.Z (local only - NOT pushed)
**What happened**:
- ✅ Dirty changes auto-committed
- ✅ Pushed to GitHub (code safe!)
- ✅ Version bumped to X.Y.Z
- ✅ Package built
- ✅ Published to npmjs.org (locally)
- ⏭️ Tag NOT pushed (no GitHub Actions triggered)
**Verify**: `npm view specweave version --registry https://registry.npmjs.org`
**If you want to push the tag later** (triggers GH release):
`git push origin vX.Y.Z`
✅ Any dirty changes auto-committed ✅ Dirty commit pushed to remote ✅ Version bumped in package.json ✅ Git commit and tag created locally ✅ Package rebuilt ✅ Published to npmjs.org (explicit registry!) ✅ Version commit pushed to GitHub ⏭️ Tag NOT pushed (no GitHub Actions)
Use this workflow when --ci flag is detected. Push to git and let GitHub Actions handle npm publish.
# Verify we're on develop branch
git rev-parse --abbrev-ref HEAD
# Check for uncommitted changes
git status --porcelain
# Verify current version
node -p "require('./package.json').version"
STOP if:
develop branch (ask user to switch)CURRENT=$(node -p "require('./package.json').version")
if [[ "$CURRENT" == *"-"* ]]; then
# Prerelease: bump prerelease number
npm version prerelease -m "chore: bump version to %s"
else
# Stable: bump patch
npm version patch -m "chore: bump version to %s"
fi
# Get the new version
node -p "require('./package.json').version"
# Push commit and tag to trigger GitHub Actions
git push origin develop --follow-tags
✅ Release initiated successfully!
📦 **Version**: vX.Y.Z
🔗 **Tag**: https://github.com/anton-abyzov/specweave/releases/tag/vX.Y.Z
⏳ **GitHub Actions**: https://github.com/anton-abyzov/specweave/actions
**Next steps**:
1. Monitor GitHub Actions workflow (1-2 minutes)
2. Verify npm publish: https://www.npmjs.com/package/specweave
3. Check GitHub release notes
✅ Version bumped in package.json ✅ Git commit created ✅ Git tag created ✅ Changes pushed to GitHub ✅ GitHub Actions workflow triggered
Use this workflow when --only flag is detected. This publishes directly to npm WITHOUT git push or GitHub Actions.
# Verify we're on develop branch
git rev-parse --abbrev-ref HEAD
# Check for uncommitted changes
git status --porcelain
# Verify current version
node -p "require('./package.json').version"
STOP if:
develop branch (ask user to switch)CURRENT=$(node -p "require('./package.json').version")
if [[ "$CURRENT" == *"-"* ]]; then
# Prerelease: bump prerelease number (1.0.0-rc.1 → 1.0.0-rc.2)
npm version prerelease -m "chore: bump version to %s"
else
# Stable: bump patch (1.0.0 → 1.0.1)
npm version patch -m "chore: bump version to %s"
fi
What this does:
package.json and package-lock.jsonvX.Y.Z# Get the new version
node -p "require('./package.json').version"
# Build the package before publishing
npm run rebuild
Critical: Must rebuild to ensure dist/ is up-to-date before publishing.
# Publish directly to npmjs.org (bypasses GitHub Actions)
# CRITICAL: Always specify registry to avoid ~/.npmrc redirecting to private feeds!
npm publish --registry https://registry.npmjs.org
What this does:
Show the user:
✅ **Published directly to npm!**
📦 **Version**: vX.Y.Z
🔗 **NPM**: https://www.npmjs.com/package/specweave
🏷️ **Git Tag**: vX.Y.Z (local only)
**What happened**:
- ✅ Version bumped and committed locally
- ✅ Git tag created locally
- ✅ Package built (npm run rebuild)
- ✅ Published to npm directly
- ⏸️ Git NOT pushed (use `git push origin develop --follow-tags` later if needed)
**Verify**:
- Check npm: https://www.npmjs.com/package/specweave
- Verify version: `npm view specweave version`
- Install globally: `npm install -g specweave@X.Y.Z`
**Note**: Local release only. Push to GitHub manually when ready:
`git push origin develop --follow-tags`
npm run rebuild)--only when you want to publish but push git later✅ Version bumped in package.json ✅ Git commit created locally ✅ Git tag created locally ✅ Package rebuilt ✅ Published to npm directly ⏸️ Git NOT pushed (manual sync later)
# DEFAULT: Full release (auto-commits dirty, publishes, pushes + tag, GH release)
/sw-release:npm
# QUICK: Save + local release (auto-commits, pushes, publishes - NO GH release)
/sw-release:npm --quick
# CI release (GitHub Actions handles npm publish) - requires clean tree
/sw-release:npm --ci
# Quick local publish, sync git later
/sw-release:npm --only
# FASTEST: Version bump only (no publish, no git, no build)
/sw-release:npm --only --local
# PROMOTE prerelease to stable (1.0.0-rc.5 → 1.0.1)
/sw-release:npm --stable
| Scenario | Command | Prerelease Handling | Git Pushed | Tag Pushed | GH Release |
|---|---|---|---|---|---|
| FULL RELEASE | (no flags) | rc.1→rc.2 (smart) | ✅ Yes | ✅ Yes | ✅ Yes |
| QUICK RELEASE | --quick | rc.1→rc.2 (smart) | ✅ Yes | ❌ No | ❌ No |
| CI release | --ci | rc.1→rc.2 (smart) | ✅ Yes | ✅ Yes | ✅ (via CI) |
| Local publish | --only | rc.1→rc.2 (smart) | ❌ No | ❌ No | ❌ No |
| Local bump | --only --local | rc.1→rc.2 (smart) | ❌ No | ❌ No | ❌ No |
| PROMOTE | --stable | rc.X→X.Y.Z+1 | ✅ Yes | ✅ Yes | ✅ Yes |
Use this workflow when BOTH --only AND --local flags are detected. This is the fastest possible version bump - NO npm publish, NO git operations, NO build. Just increment the version number for local testing.
Use case: You need to quickly test a new version locally without publishing anywhere. Perfect for:
# Just verify current version (no git checks needed!)
node -p "require('./package.json').version"
NO git checks - we're not committing or pushing anything!
CURRENT=$(node -p "require('./package.json').version")
if [[ "$CURRENT" == *"-"* ]]; then
# Prerelease: bump prerelease number (1.0.0-rc.1 → 1.0.0-rc.2)
npm version prerelease --no-git-tag-version
else
# Stable: bump patch (1.0.0 → 1.0.1)
npm version patch --no-git-tag-version
fi
What this does:
package.json version ONLYpackage-lock.json version ONLYShow the user:
⚡ **FAST local version bump!**
📦 **Version**: X.Y.Z → X.Y.(Z+1)
**What happened**:
- ✅ package.json version bumped
- ✅ package-lock.json updated
- ⏭️ NO git commit (use `git add . && git commit` later)
- ⏭️ NO git tag (use `git tag vX.Y.Z` later)
- ⏭️ NO npm publish (use `npm publish` later)
- ⏭️ NO build (use `npm run rebuild` later)
**Next steps when ready to release**:
1. Build: `npm run rebuild`
2. Test: `npm test`
3. Commit: `git add . && git commit -m "chore: bump version to X.Y.Z"`
4. Tag: `git tag vX.Y.Z`
5. Publish: `npm publish --registry https://registry.npmjs.org`
6. Push: `git push origin develop --follow-tags`
**Or use**: `/sw-release:npm` (no flags) for full instant release
npm run rebuild before testing locally✅ Version bumped in package.json ✅ Version bumped in package-lock.json ⏭️ NO git commit ⏭️ NO git tag ⏭️ NO npm publish ⏭️ NO build
Time: < 1 second