Zenn
💰

prepare-release: リリース用の Pull Request を作成し、マージされたら自動でタグを打ってリリースする仕組み

2025/03/29に公開

小さなパッケージなのにリリース手順を書き出してみたら13 stepsあったので、自動化したい。
リリース周りを自動化するrelease-pleaseやtagprは良い発想で好きなのですが、若干責務が多いなあと感じます。

そこで、必要な部分だけを GitHub Actions に落とし込み、最低限の自動化を組みました。便宜上prepare-releaseという名前にします。


概要

  • リリース用の Pull Request を GitHub Actions で作成する(versionファイルを更新)
  • PR をマージすると(versionに差分があると)、自動でタグを打ち、GitHub Release や npm publish を行う

設計の方針

  • タグ push に反応する当初の構成は、GITHUB_TOKEN 制約でうまく動かない
  • versionファイルの更新をトリガーとすることで回避した
  • Actions が使えない場合でもリリースできる構成にする

リリースするかどうかの判断が不要になる、という自動化はopinionatedで好きですが、いったんそれは無しでいいかなあと。


フロー

  1. 手動で Actions を実行して PR を作成

  2. PR 作成時に下記を実行:

    • npm version でバージョン更新(major / minor / patch 選択)
    • conventional-changelog で changelog を作成
    • changelog 整形、commit、PR 作成
  3. PR をマージすると別の Action が起動し、以下を実行:

    • git tag, push
    • build
    • checksum ファイル生成
    • npm publish
    • GitHub Releases にアセットをアップロード

これらが手でkickできるような脱出ハッチを作っているのがお気に入りのところです。
まとめると、version bumpするPR作成actionと、version bumpを見ているactionの二段構えです。


実行時の様子

PR作成

実際のPR

release


キモ: バージョン差分の確認

main の前のコミットと現在の package.json を比較して、バージョンが変わっているかを確認している。

git fetch origin main --depth=2
PREV=$(git show origin/main~1:package.json | node -p "JSON.parse(require('fs').readFileSync(0)).version") || PREV=""
CURR=$(node -p "require('./package.json').version")

変更がある場合のみ、次の処理に進む。

mergeまえのmainの状態と比較する、が一手間あったのですが、ちょっとこういうの詳しかったので、ほどほどの試行錯誤で実現出来ました。


使用言語・ツール

プロジェクトが css のため、スクリプトを Node.js で書いている。
他の言語を使っている場合は、同様の構成をそれぞれの言語・ツールで書けばよい。


CI が走らない件について

GITHUB_TOKEN で作成された PR に対しては、CI が自動で起動しない。
PRにNotice書いてあるので手動実行するか、Pull Request にコミットを追加することで回避している。


脱出ハッチ

完全自動にせず、必要なときに手動で処理を再実行できるようにしている。
CI が走らないとき、リリースに失敗したときなどに使っている。

on:
  workflow_dispatch:

苦戦したこと、発想の転換

いつもgit push tagに反応するこういうactionを作っていました。今回、GITHUB_TOKENの制約のため、この発想から離れることが必要でした。

on:
  push:
    tags:
      - "v[0-9]+.[0-9]+.[0-9]+"

実際の例


参考

Discussion

ログインするとコメントできます