Release Please Action v4 でリリースを自動管理する
CHANGELOG 生成やバージョン管理など、release-please-action v4 でリリースを自動化する手順を紹介します。
目次
Release Please とは
Release Please はコミットの履歴を解析して
- CHANGELOG の生成
- バージョン書き換え
- リリースノート
を自動化してくれる CLI ツールです。npm i -g release-please でインストールして npx release-please <コマンド> で使うことができます。
例:


Release Please Action とは
Release Please Action はコミット毎に Release Please を自動実行するための GitHub Action です。
例:

Release Please はそれが直接使われることはあまりなく、CI/CD パイプラインの一部として活用されることが多いです。Release Please Action は次のような挙動をします:
- コミットとプルリクエストの監視 コードがコミットされる度に、Release Please がその内容を確認します。コミットメッセージを元に、次のバージョンがどのように更新されるべきか(patch, minor, major)を判断します。
- リリースブランチの作成 重要なコミットがあった時、Release Please は自動的にリリースブランチを作成し、その中でバージョン番号を更新します。
- リリースノートの生成 コミットメッセージの内容に基づいて、自動でリリースノートを生成します。これにより、手動でリリース内容をまとめる手間が省けます。
- GitHub リリースの作成 リリースブランチがマージされると、GitHub 上で新しいリリースタグを自動的に作成します。このタグにはリリースノートが含まれ、バージョンも更新されています。
- パッケージの公開(任意, 要設定) 例えば npm などのパッケージマネージャーと連携している場合、新しいバージョンが自動的にパッケージリポジトリーに公開されます。
今回やること
- JavaScript 製の単一のパッケージ (モノレポではない) のリリースを管理する。
- v0 から始めて、アルファ版のリリースを行ったうえで、安定版である v1 リリースまでの一連の流れを確認する。
リポジトリを用意する
GitHub リポジトリを作成します。今回は「rp-test」という名前で進めて行きます。リポジトリを作成したら、Settings > Actions > General > Workflow permissions から「Allow GitHub Actions to create and approve pull requests」にチェックを入れて Save します。

今回は簡単のために設定から権限を変更していますが、別途アクセストークンを作成して、それを使用しても大丈夫です。Release Please は「contents: write」と「pull-requests: write」の権限を必要とします。
最初のコミット
必要なファイルを準備します:
rp-test/
├── .config/
│ ├── rp-manifest.json
│ └── rp.json
├── .github/
│ └── workflows/
│ └── release-please.yml
└── package.json{
".": "0.0.1"
}{
"packages": {
".": {
"release-type": "node",
"changelog-sections": [
{ "type": "change", "section": "Changes" },
{ "type": "feat", "section": "Features" },
{ "type": "fix", "section": "Bug Fixes" },
{ "type": "revert", "section": "Reverts" },
{ "type": "docs", "section": "Documentation", "hidden": true },
{ "type": "perf", "section": "Performance Improvements", "hidden": true },
{ "type": "chore", "section": "Miscellaneous Chores", "hidden": true },
{ "type": "test", "section": "Tests", "hidden": true },
{ "type": "style", "section": "Styles", "hidden": true },
{ "type": "refactor", "section": "Code Refactoring", "hidden": true },
{ "type": "ci", "section": "Continuous Integration", "hidden": true }
],
"include-component-in-tag": false
}
},
"$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json"
}name: Release Please
on:
push:
branches:
- main
jobs:
release-please:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- uses: googleapis/release-please-action@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
config-file: .config/rp.json
manifest-file: .config/rp-manifest.json
target-branch: ${{ github.ref_name }}
id: rp
- name: outputs
run: |
echo "${{ steps.rp.outputs.releases_created }}"
echo "${{ steps.rp.outputs.paths_released }}"
echo "${{ steps.rp.outputs.prs_created }}"{
"name": "rp-test",
"version": "0.0.1"
}.config/rp-manifest.json は現在のパッケージ (".") のバージョンが v0.0.1 であることを記録しています。Release Please はこの値に基づいて次のバージョンを決定します。
.config/rp.json で各パッケージ (今回は単一なので "." のみ) に対する Release Please の設定を行います。今回は Node.js で JavaScript パッケージの開発を行うので、release-type は node としています。changelog-sections ではリリースノートに書くコミット一覧のグループの設定を行います。type がコミットメッセージの接頭辞で、section がリリースノートのセクションタイトルになります。例えばコミットメッセージに「fix: A を B に修正」とあれば次のバージョンは「v0.0.2」になります。「feat: C を追加」とあれば次のバージョンは「v0.1.0」になります。また「change!: C を D に改名」のように ! が付いていれば破壊的変更となり、もし現在のバージョンが「v1.2.3」なら、次のバージョンは「v2.0.0」になります。hidden が true だとリリースノートには記載されなくなります。include-component-in-tag を false にすることでパッケージ名がタグやリリースノートに記載されることを防ぎます。これがないとタグ名に「v0.1.0」と期待するところを「rp-test-v0.1.0」のようにダグ付けされてしまいます。モノレポであればパッケージ名をプレフィクスにするのが良いと思いますが、今回は単一パッケージなので、false にします。
.github/workflows/release-please.yml では Release Please Action に設定ファイルへのパスを必ず指定します。target-branch は任意です。今回はデバッグ用に outputs ステップでこの Action が出力するパラメーターを見ていますが、実際にはこれらのパラメーターを元に npm などのパッケージレジストリーに公開するかどうかを決定します (paths_released は JSON 文字列なので表示の際は要注意)。全パラメーターの詳細は Release Please Action の Outputs で見れます。なお今回は単一パッケージなので、ルートコンポーネントの出力 も使うことができます。
最初のコミットの Release Please Action のログです:

最新リリースが見つからないと警告されますが、最初なので無視して大丈夫です。.releases_created と .prs_created は共に false です。
コミットを追加してみる
README を追加する
ファイルを用意します:
rp-test/
├── .config/
│ ├── rp-manifest.json
│ └── rp.json
├── .github/
│ └── workflows/
│ └── release-please.yml
├── package.json
+└── README.md# rp-testコミット & プッシュ:
git add README.md
git commit -m "chore: README を追加"
git pushこのコミットでは Release Please Action はコミット履歴の確認だけして何もしません。というのも、chore はバージョン番号の更新に値するコミットメッセージとはみなされないからです。したがって ${{ steps.rp.outputs.prs_created }} は false で、プルリクエストは作成されません。
add 関数を実装する
ファイルを用意します:
rp-test/
├── .config/
│ ├── rp-manifest.json
│ └── rp.json
├── .github/
│ └── workflows/
│ └── release-please.yml
+├── src/
+│ └── index.js
├── package.json
└── README.mdexports.add = function add(a, b) { return a + b; }コミット & プッシュ:
git add src/index.js
git commit -m "feat: add 関数を実装"
git pushfeat は新機能を表すため、Release Please がマイナーバージョンを上げる必要があると判定します。Release Please Action の ${{ steps.rp.outputs.prs_created }} は true となり、github-actions(bot) から次のようなプルリクエストが来ます:

このプルリクエストによる変更点には .config/rp-manifest.json と package.json のバージョン番号の更新と、CHANGELOG.md の更新 (追加) が含まれます。これをマージすると Release Please Action の ${{ steps.rp.outputs.releases_created }} は true となり、v0.1.0 のタグと、そのリリースノートが作成されます:


今回はコミットメッセージのタイプに feat が含まれていたのでマイナーバージョンが上がって v0.0.1 から v0.1.0 になりましたが、もし feat が無く fix があったら v0.0.2 になっていました。
プレリリース
開発を進めていき、v0.x.x から安定版の v1.0.0 をリリースする前に、v1.0.0-alpha.1 のようなプレリリースをしたい場合、Release Please の設定ファイルを変更する必要があります:
{
"packages": {
".": {
"versioning": "prerelease",
"prerelease": true,
"prerelease-type": "alpha.1",
// 省略
}
}
}"versioning" は Release Please の Versioning Strategies で、これを "prerelease" にします。v1.0.0-alpha.1 がリリースされた後、バージョン番号は v1.0.0-alpha.2, v1.0.0-alpha.3, … と更新されていきます。
"prerelease" を true にすることで GitHub のリリースノートをプレリリースとして作成します。
"prerelease-type" はプレリリースのバージョンの部分が存在しない場合、この値を設定します。.config/rp-manifest.json に、例えばすでに 1.0.0-alpha.2 のようなプレリリースのバージョンの部分が設定されていれば、次のバージョンは 1.0.0-alpha.3 になりますが、例えば 0.9.1 からアルファ版のリリースを有効にすると、プレリリースのバージョンの部分が設定されていないので、次のバージョンはこの "prerelease-type" が付いた 1.0.0-alpha.1 になります。
プレリリースの設定を反映させたところで、ファイルを更新します:
-exports.add = function add(a, b) { return a + b; }
+exports.add = function add(a, b) { return String(a + b); }コミット & プッシュ:
git add src/index.js
git commit -m "change!: add 関数は文字列を返す"
git puchange の後に ! が付いているので、Release Please から破壊的変更とみなされます。

このプルリクエストをマージすると、リリースノートはプレリリースとして作成されます:

安定版のリリース
例えば main ブランチの最新リリースが v0.9.1 で、プレリリースの最新版 v1.0.0-alpha.3 を v1.0.0 にして正式にリリースする場合、Release Please の設定ファイルとマニフェストファイルの 2 箇所を変更する必要があります:
{
"packages": {
".": {
"// versioning": "prerelease",
"// prerelease": true,
"// prerelease-type": "alpha.1",
// 省略
}
}
}{
- ".": "1.0.0-alpha.3"
+ ".": "0.9.1"
}.config/rp.json のプレリリースに関する設定は項目の先頭に // を付けて無効化しています。完全に消してしまっても良いともいますが、いずれ v2.0.0-alpha.1 が来ることを考えれば残しても良いと思います。
.config/rp-manifest.json のバージョン番号は main ブランチの最新リリースのバージョン番号と一致させています。少なくとも "1.0.0-alpha.3" のままでは、たとえプレリリースに関する設定項目を消したとしても、破壊的な変更が含まれていれば次のバージョン番号が v1.0.0 を飛ばして "2.0.0-alpha.3" になってしまう (単にメジャーバージョンが上げられただけ) ので、プレリリースの部分は消す必要があります。プレリリースが付いていない最新のリリースに手動で一旦戻してから Release Please にコミット履歴を解析させることで、上記の問題を回避します。また v1.0.0 のリリースノートには v0.9.1 からの変更をすべて記載されることになるため、プレリリースの変更差分まで熱心に追っていない人でもメジャーアップデートによる変更点を一覧できるという利点もあります。

あとはいつも通りプルリクエストをマージするだけです。
パッケージレジストリーに公開する
通常バージョン更新のプルリクエストをマージしてリリースノートを作成したら、パッケージをレジストリーに公開する必要があります。リリースノートを作成したかどうかを GitHub Actions 上で判定するには、これまでも所々出てきた ${{ steps.rp.outputs.releases_created }} を使います。
name: Release Please
on:
push:
branches:
- main
jobs:
release-please:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- uses: googleapis/release-please-action@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
config-file: .config/rp.json
manifest-file: .config/rp-manifest.json
target-branch: ${{ github.ref_name }}
id: rp
- uses: actions/checkout@v4
if: ${{ steps.rp.outputs.releases_created }}
- uses: actions/setup-node@v4
with:
node-version: 20.x
registry-url: "https://registry.npmjs.org"
if: ${{ steps.rp.outputs.releases_created }}
- name: 依存関係をインストール
run: npm ci
if: ${{ steps.rp.outputs.releases_created }}
- name: ビルド
run: npm run build
if: ${{ steps.rp.outputs.releases_created }}
- name: 公開
run: |
ver="$(jq -r .version <package.json)"
suf="${ver#*-}"
if [[ "$suf" == "$ver" ]]; then
npm publish --access=public
else
tag="${suf%%.*}"
npm publish --access=public --tag="$tag"
fi
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
if: ${{ steps.rp.outputs.releases_created }}パッケージのビルドと公開のプロセスを ${{ steps.rp.outputs.releases_created }} (または今回の場合は ${{ steps.rp.outputs.release_created }}) が true にセットされたときに実行するようにします。「公開」ステップでは 1.0.0 のようにプレリリースのバージョン部分が無ければデフォルトの latest タグで公開し、あればその名前 (例えば alpha.1 なら alpha の部分) をタグ名にして公開しています。
コミットメッセージのフォーマット
release-please/src/commit.ts に書いてあります。例を列挙すれば、
- 非破壊的な変更
feat: メッセージfeat(scope/name): メッセージ
- 破壊的な変更
feat!: メッセージfeat(scope/name)!: メッセージ
といったところでしょうか。スコープ付きの場合、! はスコープの後に指定するようです。