ブランチの作成者を追跡するための GitHub Actions ワークフロー
課題
誰がブランチやタグを作成(プッシュ)したのか知りたいときってありますよね?
ですが Git ではコミット単位でしか Author が管理されないためブランチやタグをプッシュしたユーザーを調べる方法はありません。
解決策
GitHub で push
イベントが発生したときに各ブランチ初回の Pusher 情報を DB へ保存します。
専用の DB を用意するのは手間なので Git リポジトリを DB 代わりにします。
Gist でも良かったのですが actions/checkout が Gist に対応していなかったのでやめました。
ワークフローを実行するリポジトリとは別の空リポジトリを用意するか、ワークフローを実行するリポジトリを使用します。
後者は履歴に残りますので注意してください。
Personal Access Token を発行しなくて済むメリットはあります。
今回のサンプルコードは後者で実装します。
Gist を使う場合
Gist を使う場合
README.md だけ追加した Gist を用意してクローン URL を取得します。
[Embed] のプルダウンから [Clone via HTTPS] または [Clone via SSH] を選択することで URL をコピーできます。
Personal Access Token も発行してワークフローを実行するリポジトリの [Settings] > [Secrets] に PAT
で登録しておきます。
ワークフロー内で actions/checkout にあたる処理を自前で書きましょう。
GitHub Actions ワークフロー
まずは全体のワークフローです。説明は後述します。
実際の動作は SnowCait/branch-authors-example をご参照ください。
name: Branch authors
on:
push:
delete:
jobs:
push:
runs-on: ubuntu-20.04
if: github.event_name == 'push'
steps:
- run: cat $GITHUB_EVENT_PATH
- uses: actions/checkout@v2
with:
ref: main # DB 代わりにするブランチ
- name: Config
run: |
git config user.name github-actions
git config user.email github-actions@github.com
- name: Pusher
run: |
if [ ! -d $REF ]
then
mkdir -p $REF
echo $AUTHOR >> ${REF}/author
git add .
git commit -m "${REF} is pushed"
fi
env:
REF: ${{ github.event.ref }}
AUTHOR: ${{ github.event.pusher.name }}
- name: Push
run: git push
delete:
runs-on: ubuntu-20.04
if: github.event_name == 'delete'
steps:
- run: cat $GITHUB_EVENT_PATH
- uses: actions/checkout@v2
with:
ref: main # DB 代わりにするブランチ
- name: Config
run: |
git config user.name github-actions
git config user.email github-actions@github.com
- name: Delete branch
run: |
if [ -d $REF ]
then
git rm -r $REF
git commit -m "${REF} is deleted"
fi
env:
REF: refs/heads/${{ github.event.ref }}
if: github.event.ref_type == 'branch'
- name: Delete tag
run: |
if [ -d $REF ]
then
git rm -r $REF
git commit -m "${REF} is deleted"
fi
env:
REF: refs/tags/${{ github.event.ref }}
if: github.event.ref_type == 'tag'
- name: Push
run: git push
共通
push
と delete
でワークフローを分けても良いのですが関連付けが分かりにくくなるため1つのファイルで管理し jobs.<job_id>.if
で実行を制御しています。
別のリポジトリを使う場合は actions/checkout
に repository
と token
を追加します。
Personal Access Token も発行してワークフローを実行するリポジトリの [Settings] > [Secrets] に PAT
で登録しておいてください。
- uses: actions/checkout@v2
with:
ref: main # DB 代わりにするブランチ
repository: SnowCait/branch-authors
token: ${{ secrets.PAT }}
push
- name: Pusher
run: |
if [ ! -d $REF ]
then
mkdir -p $REF
echo $AUTHOR >> ${REF}/author
git add .
git commit -m "${REF} is pushed"
fi
env:
REF: ${{ github.event.ref }}
AUTHOR: ${{ github.event.pusher.name }}
github.event.pusher.name
の情報を DB に記録します。
今回は Git リポジトリなので ref でディレクトリ階層を作って author
というファイルに出力しています。
初回だけ記録できれば良いので既にディレクトリがある場合はスキップします。
github.event.pusher.name
の代わりに github.event.sender.login
を使っても良いと思うのですが違いはよく分かっていません。
ご存知の方がいましたらコメントにでも書いておいていただけると助かります。
プッシュの履歴を見たい場合は if [ ! -d $REF ]
を外して常に追記します。
delete
同名ブランチ/タグが作成されることもあるので削除されたときには DB からも消しておきます。
- name: Delete branch
run: |
if [ -d $REF ]
then
git rm -r $REF
git commit -m "${REF} is deleted"
fi
env:
REF: refs/heads/${{ github.event.ref }}
if: github.event.ref_type == 'branch'
push
で作られたディレクトリを削除します。
途中から導入したりすることを考えて if [ -d $REF ]
で囲ってあります。
push
イベントと異なり完全な ref
情報がないため ref_type
で分岐、生成しています。
まとめ
出来そうで出来なかったことの1つを解決できたのではないかと思います。
一覧性を重視するなら1つの CSV ファイルにまとめるといいかもしれませんが少し面倒くさそう。
Discussion