はじめに
個人でiOSのアプリを開発しています。毎回アップデートするたびにタグを自分でつけるのだるいな〜。と思っていたので、Github Actionsを使用して、自動化しました。Github Actionsに関してはほぼ知識ないので、もっとこういう書き方できるよ〜とかあれば教えてください!
実際にやってみよう
今回作るものの詳細
- mainブランチに
release/ver⚪︎.⚪︎.⚪︎
というブランチがマージされた時に、ver⚪︎.⚪︎.⚪︎
というタグが自動でつく。
Github Actionsのファイルの置き場所
自分のプロジェクトファイルに.github/workflows
というディレクトリを作成します。
そして、このディレクトリ配下にGithub Actionsで処理したい内容を書いたyml
ファイルを配置しておくことで、処理が行われるようになります。
以下画像のような構成です。
これ以外に特にGithub Actionsを始めるために必要な準備は必要ありません。
ymlファイルの内容
では次にymlファイルを作成して、tagを自動でつけるための処理を書いていきましょう。
書き込む内容は以下のとおりです。
name: add_tag
on:
push:
branches:
- main
permissions:
contents: write
jobs:
add_tag:
runs-on: ubuntu-latest
steps:
- name: Checkout branch
uses: actions/checkout@v4
with:
fetch-depth: 2
- name: Extract version and add tag
uses: actions/github-script@v7
with:
script: |
const { execSync } = require('child_process');
// 最新のマージメッセージの取得
const mergeCommit = execSync('git log --merges -1 --pretty=format:"%s"').toString().trim();
console.log(`Merge commit message: ${mergeCommit}`);
// バージョンの抽出
const versionMatch = mergeCommit.match(/Merge pull request .* from .*release\/ver(.*)/);
if (!versionMatch) {
throw new Error('No version extracted.');
}
const version = versionMatch[1];
console.log(`version: ${version}`);
// タグ付け
execSync(`git tag ver${version} ${process.env.GITHUB_SHA}`);
execSync(`git push origin ver${version}`);
これをリモートにプッシュして、release/ver1.0.0のようなブランチをmainブランチにマージしてみてください!おそらくタグが自動でつくはず!
Github Actionsの処理の成功失敗はリポジトリのActoinsタブで見れます。
緑のマークが付いていればtagもついてるはずです!
ちょっとだけ詳細を説明
name
処理を分割してちょっとだけ詳細を説明していこうと思います。
まず以下のnameの部分はこのActionの名前です。なんでもいいです。
name: add_tag
on
次に以下のon
の部分です。
ここではいつ、このActionを行うかを定義します。
今回はmainブランチにマージされた時なので、以下のように設定しています。
この他にもissueがopenされたときなどさまざまなタイミングでActionは行うことができます。
僕はtagをつけるのの他に、リリースブランチがリモートにプッシュされた時には自動でPRを作成するという使い方もしています。
on:
push:
branches:
- main
permission
次に以下の部分ですが、今回tagをつける作業を行います。
リポジトリに変更を加えるため、writeの権限を持たせています。
これがないと、権限がなくてタグをつけられなかったというエラーが出てしまいます。
permissions:
contents: write
jobとstep
Github Actionsは1つのjobの中に複数のstepが含まれる形になっています。
今回の場合は、Checkout branch
とExtract version and add tag
というstepを1つのjobの中に入れています。
以下の画像にあるようにstepごとの実行結果もわかります。
runs-on
runs-on
ではActionをどのような環境で動かすかを指定します。
こんかいは最新のubuntuを指定しています。macos
で動かすこともできるので、アプリxcode関連のコマンドを実行したいときは変えると良さそうです。
jobs:
add_tag:
runs-on: ubuntu-latest
steps:
- name: Checkout branch
... 省略 ...
- name: Extract version and add tag
... 省略 ...
checkout
1つ目のstepはそのままですがブランチのチェックアウトをしています。
withの部分でfetch-depthを指定していますが、これはブランチの履歴をどれだけ取得するかを指定するところです。デフォルトでは1になっているので、例えば10個くらい前の履歴を使用したい場合には指定する必要があります。
0
を指定することで全ての履歴を取得することもできます。
ただ、プロジェクトが大きい場合には取得に時間がかかってしまうみたいです。
自分のプロジェクトで0にしてみた感じは、全然時間かからなかったので個人でやってる分には0でいいかもしれません。
今回は2にしておきます。
steps:
- name: Checkout branch
uses: actions/checkout@v4
with:
fetch-depth: 2
versionの抽出とtag付け
以下のようにusesには何を使ってscriptを書くかを宣言できます。
github-script@v7を使うとJavaScriptっぽくscriptをかけます。他にもシェルコマンドっぽくかけるものがあったりします。
この辺まだ何があるのかとか、何が書きやすいのかとか分かってません。swiftっぽく書くやつとかないんかなぁ。
uses: actions/github-script@v7
script内には実際にtagをつけるための処理を書きます。
どこで何をしているのかはコメントでざっくりと書いておきます。
with:
script: |
# シェルコマンドを実行するために必要なモジュールを取得
const { execSync } = require('child_process');
# 最新のマージメッセージの取得
const mergeCommit = execSync('git log --merges -1 --pretty=format:"%s"').toString().trim();
# 取得したメッセージを出力
console.log(`Merge commit message: ${mergeCommit}`);
# バージョンの抽出
const versionMatch = mergeCommit.match(/Merge pull request .* from .*release\/ver(.*)/);
# もしバージョンが取得できなかったらエラーで終了する
if (!versionMatch) {
throw new Error('No version extracted.');
}
# 取得したバージョンをを出力
const version = versionMatch[1];
console.log(`version: ${version}`);
# タグをつけてプッシュ
execSync(`git tag ver${version} ${process.env.GITHUB_SHA}`);
execSync(`git push origin ver${version}`);
おわりに
まだまだGithub Actionsについてはわからないことだらけです、
でもちょっと個人開発で使うようになって、便利さがわかりました!
ではまた!!