変更があるときだけコミット [GitHub Actions]
概要
以前書いたこの記事のリライトです。
continue-on-error が使えるようになったので綺麗に書けるようになりました。
コード
name: Commit
on:
pull_request:
jobs:
commit:
runs-on: ubuntu-20.04
timeout-minutes: 5
steps:
- run: cat $GITHUB_EVENT_PATH
- uses: actions/checkout@v2.4.0
with:
ref: ${{ github.head_ref }}
- run: ./script.sh
- name: Diff
id: diff
run: |
git add -N .
git diff --name-only --exit-code
continue-on-error: true
- name: Commit & Push
run: |
set -x
git config user.name github-actions[bot]
git config user.email 41898282+github-actions[bot]@users.noreply.github.com
git add .
git commit --author=. -m 'generated'
git push
if: steps.diff.outcome == 'failure'
解説
checkout
PR が作成されたときに何かしらツールを実行してそのブランチにコミットすることが多いのではないかと思います。
pull_request イベントの場合 GITHUB_REF にはマージブランチ (refs/pull/:prNumber/merge) が入ります。
マージブランチだとマージ先の変更も含んでしまうので head ブランチにチェックアウトします。
push イベントの場合は GITHUB_REF に head ブランチが入るので ref は指定不要です。
script
ツール等を実行します。
diff
git diff に --exit-code を付けると差分があった場合に終了コード 1 を返します。
差分がない場合は 0 で正常終了します。
--name-only は付けても付けなくても構いません。
標準出力が不要な場合は代わりに --quiet を付けます。
通常の git diff だと新規ファイルが認識されないので git add -N . しておきます。
continue-on-error: true を設定し終了コードに依らず処理を続行します。
全体の結果を failure にしたい場合
全体の結果を failure にしたい場合は continue-on-error は不要です。
代わりに commit の if に failure() を追加してください。
- name: Diff
id: diff
run: |
git add -N .
git diff --name-only --exit-code
- name: Commit & Push
run: |
set -x
git config user.name github-actions[bot]
git config user.email 41898282+github-actions[bot]@users.noreply.github.com
git add .
git commit --author "$(git log --pretty=format:"%an <%ae>")" -m 'generated'
git push
if: failure() && steps.diff.outcome == 'failure'
もしくは continue-on-error: true のまま push の後で exit 1 します。
- name: Diff
id: diff
run: |
git add -N .
git diff --name-only --exit-code
continue-on-error: true
- name: Commit & Push
run: |
set -x
git config user.name github-actions[bot]
git config user.email 41898282+github-actions[bot]@users.noreply.github.com
git add .
git commit --author "$(git log --pretty=format:"%an <%ae>")" -m 'generated'
git push
exit 1
if: steps.diff.outcome == 'failure'
commit
Committer として github-actions[bot] を設定します。
メールを 41898282+github-actions[bot]@users.noreply.github.com にしておくとアイコンが表示されるようです。
Author として head コミットの Author を設定します。(最終コミットに依存した自動生成を想定)
--author=. は直近のコミットの情報を取得します。
--author="$(git log --pretty=format:"%an <%ae>")" などでも良さそうです。
push イベントの場合にペイロードから取得する例
ペイロードから取得することもできます。
run: |
set -x
git config user.name github-actions[bot]
git config user.email 41898282+github-actions[bot]@users.noreply.github.com
git add .
git commit --author="$AUTHOR" -m 'generated'
env:
AUTHOR: ${{ github.event.head_commit.author.name }} <${{ github.event.head_commit.author.email }}>
diff ステップの結果が steps.diff.outcome に入っています。
failure だった場合に実行することで差分があるときにだけコミットします。
余談: steps.diff.conclusion
全体の結果は steps.diff.conclusion に依存します。
continue-on-error が true のときは常に success ですが false のときは差分があれば failure になります。
Discussion
--author=.は直前がマージコミットだったときに意図しないユーザーが author になる問題がある。PR の作成者を author とするか、なくしてしまって github-actions[bot] としてコミットする方がいいのかもしれない。