Automate 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.
When to Use This Skill
Invoke when:
Setting up local releases for a new project (any language)
Creating shareable semantic-release configuration for organization-wide use
Migrating existing projects to 2025 semantic-release patterns
Troubleshooting semantic-release setup or version bumps
Setting up Python projects (use Node.js semantic-release, NOT python-semantic-release)
Configuring GitHub Actions (optional backup, not recommended as primary due to speed)
Rust workspaces using release-plz (see Rust reference)
Why Node.js semantic-release
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.
Release Workflow Philosophy: Local-First
Default approach: Run releases locally, not via GitHub Actions.
Why Local Releases
Primary argument: GitHub Actions is slow
⏱️ GitHub Actions: 2-5 minute wait for release to complete
⚡ Local release: Instant feedback and file updates
🔄 Immediate workflow continuity - no waiting for CI/CD
Additional benefits:
✅ Instant local file sync -
package.json
,
CHANGELOG.md
, tags updated immediately
✅ No pull required - Continue working without
git pull
after release
✅ Dry-run testing -
npm run release:dry
to preview changes before release
✅ Offline capable - Can release without CI/CD dependency
✅ Faster iteration - Debug release issues immediately, not through CI logs
GitHub Actions: Optional Backup Only
GitHub Actions workflows are provided as optional automation, not the primary method:
Use for team consistency if required
Backup if local environment unavailable
Not recommended as primary workflow due to speed
Authentication Setup
bash
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.
Multi-Account Authentication via mise [env]
For multi-account GitHub setups, use mise
[env]
to set per-directory GH_TOKEN:
toml
# ~/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.
mise Task Detection
When
.mise.toml
has release tasks, prefer
mise run
over
npm run
:
Priority
Condition
Command
1
.mise.toml
has
[tasks.release:*]
mise run release:version
2
package.json
has
scripts.release
npm run release
3
Global semantic-release
semantic-release --no-ci
See Python Guide for complete mise workflow example.
GitHub Actions Policy
CRITICAL: No testing or linting in GitHub Actions. See CLAUDE.md for full policy.
Forbidden
Allowed
pytest, npm test, cargo test
semantic-release
ruff, eslint, clippy, prettier
CodeQL, npm audit
mypy
Deployment, Dependabot
Separation of Concerns (4-Level Architecture)
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 -
# .releaserc.ymlplugins:--"@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.
MANDATORY: Every Release Must Increment Version
Pre-release validation: Before running semantic-release, verify releasable commits exist since last tag. A release without version increment is invalid.
Autonomous check sequence:
List commits since last tag: compare HEAD against latest version tag
Identify commit types: scan for
feat:
,
fix:
, or
BREAKING CHANGE:
prefixes
If NO releasable commits found → STOP - do not proceed with release
Inform user: "No version-bumping commits since last release. Use
feat:
or
fix:
prefix for releasable changes."
Commit type selection guidance:
Use
fix:
for any change that improves existing behavior (bug fixes, enhancements, documentation corrections that affect usage)
Use
feat:
for new capabilities or significant additions
Reserve
chore:
,
docs:
,
refactor:
for changes that truly don't warrant a release
Why 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.
MAJOR Version Breaking Change Confirmation
Trigger:
BREAKING CHANGE:
footer or
feat!:
/
fix!:
prefix in commits.
When MAJOR is detected, this skill runs a 3-phase confirmation workflow:
Detection: Scan commits for breaking change markers
Analysis: Spawn 3 parallel subagents (User Impact, API Compat, Migration)
Confirmation: AskUserQuestion with proceed/downgrade/abort options
See MAJOR Confirmation Workflow for complete details including subagent prompts, decision tree, and example output.
Examples
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.
entirely if your task runner already handles post-release steps. See Troubleshooting: Lodash Template Conflicts.
Quick Start
Prerequisites
Check
Command
Fix
gh CLI authenticated
gh auth status
gh auth login
GH_TOKEN for directory
gh api user --jq '.login'
See Authentication
Git remote is HTTPS
git remote get-url origin
git-ssh-to-https
semantic-release global
command -v semantic-release
See Troubleshooting
Initialize Project
bash
./scripts/init-project.mjs --project# Initialize current project./scripts/init-project.mjs --user# Create user-level shareable config./scripts/init-project.mjs --help# See all options
Run Release
Priority
Condition
Commands
1
.mise.toml
has release tasks
mise run release:version
/
mise run release:full
2
package.json
has scripts
npm run release:dry
(preview) /
npm run release
3
Global CLI
semantic-release --no-ci
See Local Release Workflow for the complete 4-phase process.
Python Projects
semantic-release handles versioning. For PyPI publishing, see
pypi-doppler
skill.
Version pattern (importlib.metadata - never hardcode):
python
from importlib.metadata import PackageNotFoundError, version
try: __version__ = version("your-package-name")except PackageNotFoundError: __version__ ="0.0.0+dev"
See Python Projects Guide for complete setup including Rust+Python hybrids.
GitHub Actions (Optional)
Not recommended as primary (2-5 minute delay). Repository Settings → Actions → Workflow permissions → Enable "Read and write permissions".
Reference Documentation
Category
Reference
Description
Setup
Authentication
HTTPS-first setup, multi-account patterns
Workflow
Local Release Workflow
4-phase process (PREFLIGHT → RELEASE → POSTFLIGHT)
Languages
Python Projects
Python + Rust+Python hybrid patterns
Rust Projects
release-plz, cargo-rdme README SSoT
Config
Version Alignment
Git tags as SSoT, manifest patterns
Monorepo Support
Polyglot monorepo with Pants + mise, pnpm/npm workspaces
Advanced
MAJOR Confirmation
Breaking change analysis workflow
Doc Release Linking
Auto-link ADRs/specs in release notes
Help
Troubleshooting
All common issues consolidated
Evolution Log
Skill change history
Cross-skill references:
mise-tasks
skill: polyglot-affected - Complete Pants + mise integration guide