変更があるときだけコミット [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] としてコミットする方がいいのかもしれない。