仕事でGitHubのリリース周りを触る機会があり、せっかくならと思い、個人で開発しているリポジトリたちにも導入しました🚀
結論から
完成形のフローは以下のとおりです。
- featureブランチをmainブランチにマージ
- タグを作成
- タグからリリースを作成
1をトリガーにGitHubActionsを動かして、2・3を実施します。
GitHubActionsの完成形は以下のとおりです。
.github/workflows/generate-release.ymlname: Generate Release on: pull_request: branches: - main types: - closed jobs: build: if: github.event.pull_request.merged == true runs-on: ubuntu-22.04 permissions: contents: write steps: - uses: actions/checkout@v4 with: ref: ${{ github.event.pull_request.merge_commit_sha }} fetch-depth: '0' - name: Generate Tag uses: anothrNick/github-tag-action@1.67.0 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} WITH_V: true DEFAULT_BUMP: patch INITIAL_VERSION: 1.0.0 - name: Set Tag Name run: | latest_tag=$(git describe --tags) echo "TAG_NAME=${latest_tag}" >> $GITHUB_ENV - name: Generate Release Note uses: softprops/action-gh-release@v1 with: name: ${{ env.TAG_NAME }} tag_name: ${{ env.TAG_NAME }} generate_release_notes: true
やったこと
タグの自動作成
https://github.com/anothrNick/github-tag-action を使いました。
調べるといろいろな選択肢がありますが、とりあえず以下のことができれば不自由はしなさそうだったので、これに決めました。
- 基本動作として、patchがインクリメントされる
- コミットメッセージでmajor, minorのインクリメントを制御できる
オプションで制御するようになっていて、↑のコードだと以下の部分が該当します。
WITH_V: true DEFAULT_BUMP: patch INITIAL_VERSION: 1.0.0
この設定をしておくと、リリースタグは以下のようになります。
タグの取得
リリースを作成するステップで使えるように、タグを取得する必要があります。
latest_tag=$(git describe --tags) echo "TAG_NAME=${latest_tag}" >> $GITHUB_ENV
describeでタグを取得して、ENVに書き込んでいます。
リリースの自動作成
READMEにあるように設定を書けば特にハマることもなく動きます。
リリースノートのテンプレ
「自動生成リリースノート」というのを設定しておくと、よくライブラリなどで見るキラキラした感じのやつを作れます。
基本的にGitHubの公式どおりですが、一応自分が書いた設定を置いておきます。
.github/release.ymlchangelog: categories: - title: 🚀 Features labels: - '*' exclude: labels: - dependencies - bug - title: 🐉 Bug Fixes labels: - bug - title: 👒 Dependencies labels: - dependencies
dependenciesとbug以外のラベル(ラベルなしも含む)はfeature扱いにしています。
以前gitmojiをコミットメッセージに含める運用をしているチームで開発をしたことがあり、そこではバグを🐛ではなく🐉にしていて、虫嫌いな自分にとってとても快適だったので今回は🐉を採用しました
ちなみに、そのチームで🐉を使っていた由来は以下の記事だったそうです。
動かしてみる
こんな感じでリリースが作成されます
Flutterで開発しているリポジトリでは・・
Flutterで個人開発をしているのですが、それらのリポジトリでは少しだけ設定を変えています。
.github/workflows/generate-release.yml... jobs: generate: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Generate tag run: | export TAG_NAME=$(sed -n 4P pubspec.yaml | sed 's/version: //') git tag $TAG_NAME git push origin $TAG_NAME echo "TAG_NAME=$TAG_NAME" >> $GITHUB_ENV - name: Generate release note uses: softprops/action-gh-release@v1 with: name: ${{ env.TAG_NAME }} tag_name: ${{ env.TAG_NAME }} generate_release_notes: true
Flutterの場合、pubspec.ymlでバージョンを管理しているので、そのバージョンでタグを生成するようにしています。
(個人開発のリポジトリだといずれもpubspec.yamlの4行目にバージョンを書いているので、その行を取得し、不要なversion:文字列を削除しています。行数に依存するの脆いので微妙ですね。。)
おわりに
インクリメントの様子が可視化されるので、個人開発のモチベーションアップにも繋がっています!
今回はコミットメッセージをちゃんとするところまで手が回らなさそうだったので諦めましたが、semantic-releaseを使うのもよさそうだなーと思いました。