Github ActionsとSemantic ReleaseでUnityの自作パッケージのリリースを自動化する
概要
GitHubにPushしたら
- コミットログを解析して
- CHANGELOG.mdを更新
- package.jsonのバージョン欄を更新
- npmにパブリッシュ
- gitにtagを追加、変更したファイルを改めてPush
- GitHubのReleaseページを追加
という自動化をします。
Scoped Registryのススメ
npm?と気になった方もいらっしゃるかもしれません。
Unity Package Managerでパッケージをインストールする方法はローカルファイルの指定、GitURLの指定、Scoped Registry経由の3つです。
このうちScoped Registryには次の利点があります。
- 依存パッケージも自動的にインストールしてくれる
- PackageManagerが公開済みのバージョンを認識する
Updateボタンが出たり、バージョンを選択してのインストールできる
反面、次のような手間がかかります。
- リリース担当者はパッケージをScoped Registryにパブリッシュする必要がある
- インストールする方もScoped Registryの設定が必要
はじめはよくわからないし手間もかかるしと敬遠してたのですが、使ってみるとPackageManagerが本気を出してくれるのが思ったりよりも快適でおすすめです。
Scoped Registryは自前でサーバーを建てるのもありなのですが、公開前提であれば次の2つがメジャーな選択肢のようです。
-
npmjs.com
node.jsのパッケージマネージャnpm本家のレジストリ。
本来Unityに向けたものではないですが、UnityPackageManagerが同じプロトコルを採用していてnpmの規約的もオッケーらしく使えるみたい、です。 -
OpenUPM
Unity向けのオープンな非公式レジストリ。
GitHubのリポジトリを登録しておくと定期的に監視してtagの更新に合わせてパッケージを公開してくれます。
今回はnpmをターゲットにしています。
自動化の仕組み
全体像はこんな感じです。
GitHub Actionでsemantic-releaseを使うとやりたいことをだいたいやってくれます。すごい。
semantic-release
Semantic Versioning(SemVer)のルールベースでパッケージリリースのワークフローを自動化してくれるツールです。
デフォルトの動作ではnpmへのパブリッシュとGitHubのリリースページの更新しかしませんが、プラグインを追加することでCHANGELOG.mdの更新などが出来るようになります。
また、Angularのコミットメッセージの書式に基づいてコミット履歴から新しいバージョン番号とリリースノートの文言を生成します。
Commit message | Release type |
---|---|
fix(pencil): stop graphite breaking when too much pressure applied |
|
feat(pencil): add 'graphiteWidth' option |
|
perf(pencil): remove graphiteWidth option BREAKING CHANGE: The graphiteWidth option has been removed. The default graphite width of 10mm is always used for performance reasons.
|
(Note that the BREAKING CHANGE: token must be in the footer of the commit) |
https://github.com/semantic-release/semantic-release/blob/master/README.md より
このルールのおかげで人間がバージョン番号をつけたり、CHANGELOGの更新といった手間から解放されます。便利!
かわりにコミットにちょっとした緊張感が漂います。
設定手順
GitHub
GitHub Actionが動くように設定を確認しておきます。
GitHubのリポジトリから Settings > Actions > General で
-
Action permissionsが
Disable actions
以外のものに -
Workflow permissionsが
Read and write permissions
に
なっているか確認しておきましょう。
自分の環境ではデフォルトのままで大丈夫でした。
NPM_TOKEN
npmにパブリッシュできるように認証用のトークンを取得しGitHubに登録しておきます。
npmのアカウントが必要なのでなければ事前に取得しておきましょう。
-
npmjs.comの自身のアイコンから
Access Tokens
を選択
-
Generate New Token
をクリック -
適当な名前をつけ、Select typeの
Automation
を選択、Generate Tokenボタンを押す -
トークン(1行のランダムな文字列)が生成されます
こちらのトークンは二度と表示されないので気をつけてください。
(とはいえわからなくなったらまた作れば大丈夫です)
こちらのトークンをGitHub Actionで使えるように登録します。
GitHubのリポジトリから Settings > Secrets > Actions で
Nameに"NPM_TOKEN"、Valueにさきほど取得したトークンを入力します。
GitHub Action
- リポジトリに
.github/workflow
フォルダを作る -
.github/workflow
下にPublish.yml
を置く
name: Publish
on:
push:
branches:
- main
workflow_dispatch:
jobs:
publish:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Semantic Release
uses: cycjimmy/semantic-release-action@v3
with:
semantic_version: 19
branch: main
working_directory: ./Packages/ga.fuquna.testpublishingpackage
extra_plugins: |
@semantic-release/changelog@6
@semantic-release/git
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
mainブランチにPushされたら、最新の状態をチェックアウトしsemantic-releaseにかける、といった動作になっています。
-
on:push:branches:
はPushをトリガーにするブランチです。複数指定やフィルタ的な指定もできます。 -
on:workflow_dispatch:
は手動でGithubActionを実行できるようにするため指定しています。無くても大丈夫です。
semantic-release-action
semantic-release-actionというsemantic-releaseを動かすGitHub Actionがすでにあるのでこちらを利用しています。
- name: Semantic Release
以下が該当部分になります。
-
branch:
はデフォルトがmasterなのでmainを指定しています。 -
working_directory:
はパッケージとして公開するフォルダに置換してください。 -
extra_plugins:
ではsemantic-releaseの追加プラグインを指定しています。
今回はCHANGELOG.mdの更新と、更新したファイル(package.json、CHANGELOG.md)のPushをするために、semantic-release/changelog、semantic-release/gitの2つのプラグインを指定しています。このままでは動作せず後述の.releaserc.ymlでも指定が必要です。 -
env:
で先程設定したNPM_TOKENを教えています。GITHUB_TOKENは自動的に使えるのでここで指定するだけでOKです。
記述していないですがdry-run
オプションもあるので最初は指定しておくと安心かもしれません。
semantic-release
最後にsemantic-release用の設定ファイルを作ります。
リポジトリのルートフォルダに.releaserc.yml
を置きます。
{
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
"@semantic-release/changelog",
"@semantic-release/npm",
"@semantic-release/git",
"@semantic-release/github"
]
}
plugins
でプラグインを指定しています。
実行順もこの順にしたがっているのでで注意が必要です。
ちなみに、何も指定しないデフォルトでは次のようになっているようです。
{
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
"@semantic-release/npm",
"@semantic-release/github"
]
}
semantic-releaseは単体ではなにもせずプラグインの集合として動作してるみたいですね。
上記.releaserc.ymlはこちらにsemantic-release/changlogとsemantic-release/gitを良きタイミングのところに追加した形になっています。
動作確認
以上でリリースの自動化が出来ているはずです。
とはいえ結構typoなどで途中でエラーになっていたりするのでGitHubのActionsタブでうまく動いているか確認しましょう。
Angular書式のコミットメッセージがないと最初のリリースも行われないので注意してください。
使ってみて
semantic-releaseではバージョンが1.0.0スタートで0.0.0スタートにはできないところにちょっとひっかかりました。これはSemVer的にはメジャーバージョン0以下は1以上のルールが適応されない(破壊的変更しまくる開発初期扱い)ため良くないよ、とのことです。やるならかわりにpre-releaseの作法がおすすめみたいです。
semantic-relase自体はただのnode.jsプログラムなので、オンライン上の動作がよくわからないときはローカルで動かしてみるのもいい作戦だと思います。またコンフィグが豊富でいろいろできそうなので、困ったらドキュメントを漁ってみるのもいいと思います。
参考
Discussion