Automate versioning with Node.js semantic-release v25+. TRIGGERS - npm run release, version bump, changelog, conventional commits, release automation.
/plugin marketplace add terrylica/cc-skills/plugin install terrylica-itp-plugins-itp@terrylica/cc-skillsThis skill is limited to using the following tools:
assets/templates/doppler.yamlassets/templates/github-workflow.ymlassets/templates/package.jsonassets/templates/releaserc-pypi-doppler.jsonassets/templates/releaserc.ymlassets/templates/shareable-config/README.mdassets/templates/shareable-config/index.jsassets/templates/shareable-config/package.jsonreferences/2025-updates.mdreferences/authentication.mdreferences/doc-release-linking.mdreferences/local-release-workflow.mdreferences/monorepo-support.mdreferences/pypi-publishing-with-doppler.mdreferences/python-projects-nodejs-semantic-release.mdreferences/resources.mdreferences/troubleshooting.mdreferences/version-alignment.mdreferences/workflow-patterns.mdscripts/create_org_config.shAutomate semantic versioning and release management using semantic-release v25+ (Node.js) following 2025 best practices. Works with all languages (JavaScript, TypeScript, Python, Rust, Go, C++, etc.) via the @semantic-release/exec plugin. Create shareable configurations for multi-repository setups, initialize individual projects with automated releases, and configure GitHub Actions workflows with OIDC trusted publishing.
Important: This skill uses semantic-release (Node.js) exclusively, NOT python-semantic-release, even for Python projects. Rationale: 23.5x larger community, 100x+ adoption, better future-proofing.
Invoke when:
22,900 GitHub stars - Large, active community
1.9M weekly downloads - Proven adoption
126,000 projects using it - Battle-tested at scale
35+ official plugins - Rich ecosystem
Multi-language support - Works with any language via @semantic-release/exec
Do NOT use python-semantic-release. It has a 23.5x smaller community (975 vs 22,900 stars), ~100x less adoption, and is not affiliated with the semantic-release organization.
Default approach: Run releases locally, not via GitHub Actions.
Primary argument: GitHub Actions is slow
Additional benefits:
package.json, CHANGELOG.md, tags updated immediatelygit pull after releasenpm run release:dry to preview changes before releaseGitHub Actions workflows are provided as optional automation, not the primary method:
gh auth login
# Browser authentication once
# Credentials stored in keyring
# All future releases: zero manual intervention
This is the minimum manual intervention possible for local semantic-release with GitHub plugin functionality.
For multi-account GitHub setups, use mise [env] to set per-directory GH_TOKEN:
# ~/your-project/.mise.toml
[env]
GH_TOKEN = "{{ read_file(path=env.HOME ~ '/.claude/.secrets/gh-token-accountname') | trim }}"
GITHUB_TOKEN = "{{ read_file(path=env.HOME ~ '/.claude/.secrets/gh-token-accountname') | trim }}"
This overrides gh CLI's global authentication, ensuring semantic-release uses the correct account for each directory.
See the mise-configuration skill for complete setup.
This standard applies to ALL GitHub Actions workflows, not just semantic-release.
GitHub Actions workflows must NEVER include:
❌ Test execution:
# ❌ FORBIDDEN - Do not add to any workflow
- run: pytest
- run: npm test
- run: cargo test
- uses: actions/upload-test-results # Implies testing
❌ Linting/Formatting:
# ❌ FORBIDDEN - Do not add to any workflow
- run: ruff check
- run: eslint .
- run: cargo clippy
- run: prettier --check
- run: mypy
✅ Semantic-release (this workflow):
- run: npm run release # Version, changelog, GitHub release only
✅ Security scanning:
- run: npm audit signatures
- uses: github/codeql-action/analyze@v3
✅ Deployment:
- run: docker build && docker push
- run: aws s3 sync ./build s3://bucket
✅ Dependency updates:
- uses: dependabot/fetch-metadata@v2
Documentation-based: This standard is enforced through CLAUDE.md instructions, not pre-commit hooks.
When creating or modifying GitHub Actions workflows, Claude Code will check CLAUDE.md and this skill to ensure compliance.
semantic-release configuration follows a hierarchical, composable pattern:
Level 1: Skill - ${CLAUDE_PLUGIN_ROOT}/skills/semantic-release/ (Generic templates, system-wide tool)
Level 2: User Config - ~/semantic-release-config/ (@username/semantic-release-config)
Level 3: Organization Config - npm registry (@company/semantic-release-config)
Level 4: Project Config - .releaserc.yml in project root
Level 4 (Project) → overrides → Level 3 (Org) → overrides → Level 2 (User) → overrides → Defaults
semantic-release analyzes commit messages to determine version bumps:
<type>(<scope>): <subject>
feat: → MINOR version bump (0.1.0 → 0.2.0)fix: → PATCH version bump (0.1.0 → 0.1.1)BREAKING CHANGE: or feat!: → MAJOR version bump (0.1.0 → 1.0.0)docs:, chore:, style:, refactor:, perf:, test: → No version bump (by default)Warning: The @semantic-release/release-notes-generator (Angular preset) only includes these types in release notes:
feat: → Features sectionfix: → Bug Fixes sectionperf: → Performance Improvements sectionOther types (docs:, chore:, refactor:, etc.) trigger releases when configured but do NOT appear in release notes.
Recommendation: For documentation changes that should be visible in release notes, use:
fix(docs): description of documentation improvement
This ensures the commit appears in the "Bug Fixes" section while still being semantically accurate (fixing documentation gaps is a fix).
For Claude Code marketplace plugins, every change requires a version bump for users to receive updates.
Option A: Shareable Config (if published)
# .releaserc.yml
extends: "@terryli/semantic-release-config/marketplace"
Option B: Inline Configuration
# .releaserc.yml
plugins:
- - "@semantic-release/commit-analyzer"
- releaseRules:
# Marketplace plugins require version bump for ANY change
- { type: "docs", release: "patch" }
- { type: "chore", release: "patch" }
- { type: "style", release: "patch" }
- { type: "refactor", release: "patch" }
- { type: "test", release: "patch" }
- { type: "build", release: "patch" }
- { type: "ci", release: "patch" }
Result after configuration:
| Commit Type | Release Type |
|---|---|
feat: | minor (default) |
fix:, perf:, revert: | patch (default) |
docs:, chore:, style:, refactor:, test:, build:, ci: | patch (configured) |
Why marketplace plugins need this: Plugin updates are distributed via version tags. Without a version bump, users running /plugin update see no changes even if content was modified.
Pre-release validation: Before running semantic-release, verify releasable commits exist since last tag. A release without version increment is invalid.
Autonomous check sequence:
feat:, fix:, or BREAKING CHANGE: prefixesfeat: or fix: prefix for releasable changes."Commit type selection guidance:
fix: for any change that improves existing behavior (bug fixes, enhancements, documentation corrections that affect usage)feat: for new capabilities or significant additionschore:, docs:, refactor: for changes that truly don't warrant a releaseWhy this matters: A release without version increment creates confusion - users cannot distinguish between releases, package managers may cache old versions, and changelog entries become meaningless.
Feature (MINOR):
feat: add BigQuery data source support
Bug Fix (PATCH):
fix: correct timestamp parsing for UTC offsets
Breaking Change (MAJOR):
feat!: change API to require authentication
BREAKING CHANGE: All API calls now require API key in Authorization header.
Automatically include links to all documentation changes in release notes, with AI-friendly categorization.
Add to .releaserc.yml before @semantic-release/changelog:
- - "@semantic-release/exec"
- generateNotesCmd: "node plugins/itp/skills/semantic-release/scripts/generate-doc-notes.mjs ${lastRelease.gitTag}"
The script categorizes all changed markdown files:
| Category | Pattern | Grouping |
|---|---|---|
| ADRs | docs/adr/YYYY-MM-DD-slug.md | Status table |
| Design Specs | docs/design/YYYY-MM-DD-slug/spec.md | List with change type |
| Skills | plugins/*/skills/*/SKILL.md | Grouped by plugin (collapsible) |
| Plugin READMEs | plugins/*/README.md | Simple list |
| Skill References | plugins/*/skills/*/references/*.md | Grouped by skill (collapsible) |
| Commands | plugins/*/commands/*.md | Grouped by plugin |
| Root Docs | CLAUDE.md, README.md, CHANGELOG.md | Simple list |
| General Docs | docs/*.md (excluding adr/, design/) | Simple list |
.md files changed since the last release tagnew, updated, deleted, or renamedADR: 2025-12-06-slug in commit messagesFull HTTPS URLs are generated (required for GitHub release pages).
See Documentation Release Linking for detailed configuration.
CRITICAL: For multi-account GitHub setups, verify GH_TOKEN is set for the current directory.
Quick verification (2025-12-19+):
# Verify git remote is HTTPS
git remote get-url origin
# Expected: https://github.com/...
# Verify GH_TOKEN is set via mise [env]
gh api user --jq '.login'
# Expected: correct account for this directory
If remote is SSH (legacy):
# Convert to HTTPS
git-ssh-to-https
If wrong account:
Check mise [env] configuration:
# Verify mise config
mise env | grep GH_TOKEN
See Authentication Guide for HTTPS-first setup.
/usr/bin/env bash << 'CONFIG_EOF'
cd /path/to/project
# Environment-agnostic path
PLUGIN_DIR="${CLAUDE_PLUGIN_ROOT:-$HOME/.claude/plugins/marketplaces/cc-skills/plugins/itp}"
"$PLUGIN_DIR/skills/semantic-release/scripts/init_project.sh" --user
# Or --org mycompany/semantic-release-config
# Or --inline
CONFIG_EOF
Follow the Local Release Workflow for the complete 4-phase process (PREFLIGHT → SYNC → RELEASE → POSTFLIGHT).
Quick commands:
npm run release:dry # Preview changes (no modifications)
npm run release # Create release (auto-pushes via successCmd + postrelease)
What happens automatically:
CHANGELOG.md updatedOne-time setup (recommended for macOS):
# Install globally to avoid macOS Gatekeeper issues with npx
npm install -g semantic-release @semantic-release/changelog @semantic-release/git @semantic-release/github @semantic-release/exec
# Clear quarantine (required on macOS after install or node upgrade)
xattr -r -d com.apple.quarantine ~/.local/share/mise/installs/node/
Note: Use
semantic-releasedirectly (notnpx semantic-release) to avoid macOS Gatekeeper blocking.nodenative modules. See Troubleshooting.
For Python packages: semantic-release handles versioning, use the pypi-doppler skill for local PyPI publishing.
Quick setup:
/usr/bin/env bash << 'SETUP_EOF'
# Install Doppler CLI for secure token management
brew install dopplerhq/cli/doppler
# Store token in Doppler (one-time)
doppler secrets set PYPI_TOKEN='your-pypi-token' --project claude-config --config prd
# Copy publish script from pypi-doppler skill (environment-agnostic)
PLUGIN_DIR="${CLAUDE_PLUGIN_ROOT:-$HOME/.claude/plugins/marketplaces/cc-skills/plugins/itp}"
cp "$PLUGIN_DIR/skills/pypi-doppler/scripts/publish-to-pypi.sh" scripts/
chmod +x scripts/publish-to-pypi.sh
# After semantic-release creates GitHub release:
./scripts/publish-to-pypi.sh # 30 seconds vs 3-5 minutes with GitHub Actions
SETUP_EOF
See pypi-doppler skill for complete workflow with CI detection guards.
Only if you want CI/CD backup (not recommended as primary due to 2-5 minute delay):
Repository Settings → Actions → General → Workflow permissions → Enable "Read and write permissions"
Symptom: After release, git status shows version files as modified with OLD versions.
Cause: Files were staged before release started. semantic-release commits from working copy, but git index cache may show stale state.
Prevention: Always start with clean working directory:
# Check before release
git status --porcelain
# Should output nothing
# If dirty, either:
git stash # Stash changes
git commit -m "..." # Commit changes
git checkout -- . # Discard changes
Recovery: If you see stale versions after release:
git update-index --refresh
git status # Should now show clean
Automated guards: The cc-skills .releaserc.yml includes:
Before running npm run release:
git diff --cached is empty)For detailed information, see:
pypi-doppler skill - Local PyPI publishing with Doppler credentials and CI detection guardsThis skill should be used when the user asks to "create an agent", "add an agent", "write a subagent", "agent frontmatter", "when to use description", "agent examples", "agent tools", "agent colors", "autonomous agent", or needs guidance on agent structure, system prompts, triggering conditions, or agent development best practices for Claude Code plugins.
This skill should be used when the user asks to "create a slash command", "add a command", "write a custom command", "define command arguments", "use command frontmatter", "organize commands", "create command with file references", "interactive command", "use AskUserQuestion in command", or needs guidance on slash command structure, YAML frontmatter fields, dynamic arguments, bash execution in commands, user interaction patterns, or command development best practices for Claude Code.
This skill should be used when the user asks to "create a hook", "add a PreToolUse/PostToolUse/Stop hook", "validate tool use", "implement prompt-based hooks", "use ${CLAUDE_PLUGIN_ROOT}", "set up event-driven automation", "block dangerous commands", or mentions hook events (PreToolUse, PostToolUse, Stop, SubagentStop, SessionStart, SessionEnd, UserPromptSubmit, PreCompact, Notification). Provides comprehensive guidance for creating and implementing Claude Code plugin hooks with focus on advanced prompt-based hooks API.