🤖
GitHub Actionsで自動的にセマンティックバージョニングでタグを切る
前提
タイトル通りですが前提条件です。
- GitのホスティングサービスはGitHubを想定しています。
- バージョンの指定はセマンティックバージョニングを想定しています。
- Gitのベースブランチがmain、mainから派生したdevelop、開発はdevelopから派生したブランチで行います。
- 最初にmainで
v1.0.0
というタグを切った状態を想定しています。- バージョン以外のタグは切らない想定です。
概要
Gitのmainブランチにpushされたらマイナーバージョンアップ、developブランチにpushされたらパッチバージョンアップとして自動でタグを切ります。
タグを打つだけで、リリースは別物として考えています。
なぜmainだけでタグを切らないのか
一般的にはmainブランチのみでタグを切ってリリースを行うと思います。
しかし自動でタグを切る都合上mainはマイナーバージョン、developはパッチバージョンとしました。
developブランチについて
セマンティックバージョニングの考え方とは少し乖離があります。
パッチバージョンアップはバグFixやセキュリティパッチに当たりますが、合流ブランチにマージされたコードはすぐにリリースする可能性あると思っています。
開発生産上developへマージしたら自動的にタグを切る運用にしました。
mainブランチについて
セマンティックバージョニングの考え方に基づいています。
新しい機能開発やツール導入を行ったらmainへマージしてマイナーバージョンを上げます。
Actions Workflow
トリガーイベント
main、developブランチへのpushとします。
on:
push:
branches:
- main
- develop
ジョブ
- 最新のGitTagを取得しバージョン情報を抽出
-
- ref_nameがmainだったら
- マイナーバージョンを上げてtagをpush
- ref_nameがdevelopだったら
- パッチバージョンを上げてtagをpush
- ref_nameがmainだったら
ジョブのフロー
1. 最新のGitTagを取得しバージョン情報を抽出
workflowファイル
jobs:
extract-semantic-version:
runs-on: ubuntu-latest
defaults:
run:
shell: bash
outputs:
major: ${{ steps.extract_version.outputs.major }}
minor: ${{ steps.extract_version.outputs.minor }}
patch: ${{ steps.extract_version.outputs.patch }}
steps:
- uses: actions/checkout@v4
with:
fetch-tags: true
- name: Fetch all tags
run: git fetch --tags
- name: Describe latest tag
id: describe_latest_tag
run: |
tag=$(git describe --tags `git rev-list --tags --max-count=1`)
echo "tag=$tag" >> "$GITHUB_OUTPUT"
- id: extract_version
run: |
tag=${{ steps.describe_latest_tag.outputs.tag }}
tag_without_v=${tag#v}
IFS='.' read -r major minor patch <<< "$tag_without_v"
echo "major=$major" >> "$GITHUB_OUTPUT"
echo "minor=$minor" >> "$GITHUB_OUTPUT"
echo "patch=$patch" >> "$GITHUB_OUTPUT"
注意点
- リポジトリのtagが必要なので、
actions/checkout
の設定でfetch-tags: true
を指定。 -
actions/checkout
だけではtag情報の取得はできていないので、git fetch --tags
を行う。
2-1. ref_nameがmainだったらマイナーバージョンを上げてtagをpush
workflowファイル
jobs:
# 省略
minor-update:
if: github.ref_name == 'main'
permissions:
contents: write
runs-on: ubuntu-latest
defaults:
run:
shell: bash
needs: extract-semantic-version
env:
MAJOR: ${{ needs.extract-semantic-version.outputs.major }}
MINOR: ${{ needs.extract-semantic-version.outputs.minor }}
PATCH: ${{ needs.extract-semantic-version.outputs.patch }}
steps:
- uses: actions/checkout@v4
- name: New Tag
id: new_tag
run: echo "tag=v$MAJOR.$((MINOR + 1)).0" >> "$GITHUB_OUTPUT"
- name: Push Tag
env:
TAG: ${{ steps.new_tag.outputs.tag }}
run: |
git tag $TAG
git push origin $TAG
注意点
- 依存関係として
extract-semantic-version
を指定し、バージョン情報を利用できるようにする。 - tagをpushするために
contents: write
の権限が必要。 - jobの条件
if: github.ref_name == 'main'
でpushされたブランチ情報を比較。 - マイナーバージョンを上げる場合はパッチバージョンは0にする。
2-2. ref_nameがdevelopだったらパッチバージョンを上げてtagをpush
workflowファイル
jobs:
# 省略
patch-update:
if: github.ref_name == 'develop'
permissions:
contents: write
runs-on: ubuntu-latest
defaults:
run:
shell: bash
needs: extract-semantic-version
env:
MAJOR: ${{ needs.extract-semantic-version.outputs.major }}
MINOR: ${{ needs.extract-semantic-version.outputs.minor }}
PATCH: ${{ needs.extract-semantic-version.outputs.patch }}
steps:
- uses: actions/checkout@v4
- name: New Tag
id: new_tag
run: echo "tag=v$MAJOR.$MINOR.$((PATCH + 1))" >> "$GITHUB_OUTPUT"
- name: Push Tag
env:
TAG: ${{ steps.new_tag.outputs.tag }}
run: |
git tag $TAG
git push origin $TAG
注意点
- 2-1とほぼ同じだが、job実行の条件変更とパッチバージョンのみ上げるようにする。
上記をまとめると自動的に最新のtagを取得しバージョンアップを行うことができます。
終わりに
タグを自動で切ることでリリース時にセレクトボックスでタグを選択でき、オペレーションミスを防ぐことができるようになりました。
Discussion