setup-semantic-release について
Conventional Commits、commitlint、Husky、semantic-release を使い、Node.js リポジトリにリリースパイプラインを設定するスキルです。コミット検証からバージョン管理、変更履歴、GitHub Actions でのリリースまで扱い、既存設定との競合も確認します。
主な機能
- 01Conventional Commits の検証設定
- 02Husky のコミットフック設定
- 03セマンティックバージョニングの自動化
- 04変更履歴の生成とコミット
- 05GitHub Actions のリリースワークフロー作成
- 06既存リリースツールとの競合確認
活用シーン
- 01Node.js リポジトリに自動リリースを追加
- 02不正なコミット件名をコミット前に拒否
- 03コミットから変更履歴を生成
- 04GitHub Actions のリリース自動化を設定
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ antjanus/ skillbox --skill setup-semantic-releaseインストール後、Claude Code で/setup-semantic-releaseを入力して読み込まれたか確認します。
同梱ファイルreferences/EVAL.mdreferences/REFERENCE.md
詳細
Semantic Release と Conventional Commits のセットアップ
概要
自動バージョン管理をエンドツーエンドで設定します:conventional commits → commitlint → husky → semantic-release。バージョン番号、CHANGELOG.md、Git タグ、GitHub リリースはすべてコミットメッセージから生成されるため、人が記述するリリース情報はコミットの件名だけです。作成時に形式を適用すれば、残りは自動で処理されます。
次の場合は作業を中断して、その旨を伝えてください。 リポジトリにすでに .releaserc* がある、別のリリースツール(changesets、release-it、standard-version)を使っている、または package.json がない場合です。既存のパイプラインにリリースパイプラインを重ねると、タグや変更履歴の項目が重複して生成されます。
前提条件: package.json、GitHub リモート、Node ≥22.14 — または 24.x 系では ≥24.10(Node 20/21/23 のサポートを終了した semantic-release@^25 の engines の下限。@commitlint/*@^21 には ≥22.12 が必要)— および GitHub Actions。
セットアップの手順
フェーズ 1:インストール
npm install --save-dev \
@commitlint/cli@^21.0.0 @commitlint/config-conventional@^21.0.0 \
semantic-release@^25.0.0 @semantic-release/changelog@^6.0.0 \
@semantic-release/git@^10.0.0 husky@^9.0.0
| パッケージ | 目的 |
|---|---|
@commitlint/cli + config-conventional | conventional rules に照らしてコミットメッセージを検証します |
semantic-release | バージョン更新、変更履歴、リリースを自動化します |
@semantic-release/changelog | CHANGELOG.md を生成・更新します |
@semantic-release/git | リリース成果物をリポジトリにコミットします |
husky | Git フックを管理します |
確認:上記のすべてのパッケージが devDependencies にあり、npm install が終了コード 0 で終了していること。
フェーズ 2:Commitlint
commitlint.config.js を作成します。package.json に "type": "module" がない場合は、export default ではなく module.exports = {...} を使用します。
export default {
extends: ['@commitlint/config-conventional'],
rules: {
'type-enum': [2, 'always', [
'feat', 'fix', 'docs', 'style', 'refactor',
'perf', 'test', 'build', 'ci', 'chore', 'revert',
]],
'subject-case': [2, 'always', 'lower-case'],
'header-max-length': [2, 'always', 100],
'body-max-line-length': [0], // disable — conflicts with semantic-release notes
},
};
確認:ルートに commitlint.config.js があり、そのモジュール構文が package.json の "type" と一致していること。
フェーズ 3:Semantic-release
.releaserc.json を作成します。プラグインの順序は実行順であり、branches にはリポジトリの実際のデフォルトブランチを指定する必要があります。
{
"branches": ["main"],
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
["@semantic-release/changelog", { "changelogFile": "CHANGELOG.md" }],
["@semantic-release/git", {
"assets": ["CHANGELOG.md", "package.json", "package-lock.json"],
"message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
}],
"@semantic-release/github"
]
}
プレリリースおよび複数ブランチの設定例は、references/REFERENCE.md を参照してください。
確認:ルートに .releaserc.json があり、branches にデフォルトブランチが指定され、プラグインの順序が analyzer → notes-generator → changelog → git → github であること。
フェーズ 4:Husky フック
npx husky init # creates .husky/, adds "prepare": "husky"
echo 'npx --no -- commitlint --edit $1' > .husky/commit-msg # validate every commit message
質問せずに、プロジェクト自身の package.json のスクリプトから pre-commit チェックを選びます。最初に一致したものを使用します:lint と test の両方がある場合 → npm run lint && npm test、それ以外で test がある場合 → test、それ以外で lint がある場合 → lint、それ以外 → build。
echo 'npm run lint && npm test' > .husky/pre-commit # substitute the matched command
該当するスクリプトがない場合は、rm .husky/pre-commit を実行します。存在しないスクリプトを実行するフックがあると、すべてのコミットが失敗します。また、空のフックではチェックが何も行われていないことがわかりません。
"prepare": "husky" が package.json の scripts に追加されていることを確認し、husky init で追加されていなければ追加します。これにより npm install のたびにフックが再インストールされます。これがないと、新しいクローンでは検証なしでコミットできてしまいます。
確認:.husky/commit-msg に commitlint コマンドが含まれ、.husky/pre-commit が設定または削除され、package.json の scripts に "prepare": "husky" があること。
フェーズ 5:初期 CHANGELOG
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
Semantic-release は各リリースの内容をこのヘッダーの上に追加します。
確認:ルートに CHANGELOG.md があること。
フェーズ 6:CI ワークフロー
.github/workflows/release.yml を作成します。
name: Release
on:
push:
branches: [main]
permissions:
contents: write
issues: write
pull-requests: write
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # required — semantic-release needs full history
- uses: actions/setup-node@v4
with:
node-version: 'lts/*'
- run: npm ci
- run: npx semantic-release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }} # drop unless you added @semantic-release/npm
GITHUB_TOKEN は Actions によって自動的に提供されます。デフォルトブランチが main でない場合は、ここおよび .releaserc.json の branches を合わせて更新してください。
確認:.github/workflows/release.yml があり、branches が .releaserc.json と一致し、@semantic-release/npm がプラグインリストにある場合に限り NPM_TOKEN が設定されていること。
クイックリファレンス
コミット種別 → リリース:
| コミット | リリース |
|---|---|
feat: … | マイナー |
fix: … | パッチ |
feat!: … または BREAKING CHANGE: フッター | メジャー |
docs style refactor perf test build ci chore revert | なし |
作成されるファイル: commitlint.config.js · .releaserc.json · .husky/commit-msg · .husky/pre-commit(または削除)· CHANGELOG.md · .github/workflows/release.yml、および package.json の devDependencies と prepare スクリプト。
スモークテスト: echo "feat: test" | npx commitlint は終了コード 0、echo "bad" | npx commitlint は終了コードが 0 以外になります。
例
✅ リリースが正常に行われる件名 — 種別の接頭辞、任意のスコープ、小文字:
feat(auth): add OAuth login # minor bump
fix(api): handle null response # patch bump
feat!: drop the v1 endpoints # major bump
❌ 拒否される件名、またはバージョンがまったく付かずに機能をリリースする件名:
updated auth stuff # no type prefix — commitlint rejects the commit
feat: Add OAuth login # capitalized — the subject-case rule rejects it
chore: add OAuth login # accepted, but chore never releases; the feature ships unversioned
✅ フッターで破壊的変更を宣言し、生成されるリリースノートで変更点を説明する例:
feat(api): add pagination
Adds offset/limit to all list endpoints.
BREAKING CHANGE: removed `page` in favor of `offset`
✅ パッケージのモジュールシステムに合わせた commitlint.config.js の構文:
// package.json has no "type": "module"
module.exports = { extends: ['@commitlint/config-conventional'] };
❌ 同じパッケージ内に同じファイルがある場合 — commitlint は設定の読み込み時にエラーをスローし、ルールが実行される前にすべてのコミットが失敗します:
export default { extends: ['@commitlint/config-conventional'] };
注意点
plugins配列を明示すると、デフォルトのプラグインが拡張されるのではなく、置き換えられます。 semantic-release のデフォルト一覧には@semantic-release/npmが含まれますが、Phase 3 の設定では省略されているため、npm には何も公開されません。パッケージを公開する場合は"@semantic-release/github"の前に"@semantic-release/npm"を追加してください。そうでなければ、ワークフローからNPM_TOKENを削除してください。これは何もしません。(ドキュメント)@semantic-release/changelogは@semantic-release/gitより前に配置する必要があります。 順序が逆だと、git プラグインはまだ書き込まれていないCHANGELOG.mdをコミットします。body-max-line-length: [0]は意図的な設定であり、雑な設定ではありません。 semantic-release は完全なリリースノートを独自のリリースコミットの本文に書き込みます。これによりデフォルトの 100 文字制限を超え、リリースコミットが自身のフックで失敗します。subject-case: lower-caseは大文字で始まる件名を拒否します。feat: Add featureは失敗し、feat: add featureは成功します。「メッセージに問題はなさそうなのに」と感じるケースで、最もよくある拒否理由です。- CI では
fetch-depth: 0が必要です。 Actions はデフォルトで shallow clone を行うため、semantic-release がタグの履歴を取得できず、ENOGITHEADまたはEGITNOBRANCHで失敗します。 - git プラグインの
messageに[skip ci]を指定すると、無限ループを防げます。 リリースコミットはリリースブランチに追加されますが、この指定がないとワークフローが再度実行されます。 commitlint.config.jsはパッケージのモジュールシステムに合わせてください — 最後の例の組み合わせを参照してください。一致しない場合、ルールが実行される前にすべてのコミットが失敗します。
詳細リファレンス
プレリリースブランチの設定とトラブルシューティング(husky フックが動作しない、変更履歴の重複、CI ループ、ENOGITHEAD)は references/REFERENCE.md にあります。最初から読み込むのではなく、フェーズの Check 行が失敗したときに読み込んでください。
参考資料
Conventional Commits · SemVer · semantic-release · commitlint · Husky。複数回に分けてセットアップする場合は、track-session と組み合わせてください。