GitHub Actionsでフォークしたリポジトリを自動更新(git diffして差分の有無でexit codeを変える)
GitHubでリポジトリをフォークした後、どうやってオリジナルを追従していますか?(この記事ではフォーク元をオリジナル、フォークにより出来たリポジトリをコピーと呼ぶことにします。)
フォークしたリポジトリ、mainは勝手に更新され続けて欲しい
— よこな / Ayana (@ihcomega) November 3, 2022
(願望)
以前はローカルでマージやプッシュをしていたものの、最近面倒になってきたのですごく雑にGitHub Actionsで定期的な更新をかけるようにしました。オリジナルのマージをフックに…とかやると完璧ですが、ひとまずないよりあった方がいいかなということでしゅっと用意したものです。pyrsia/pyrsia
がオリジナルのリポジトリです。
name: Update forked repos on: schedule: - cron: '*/30 * * * *' workflow_dispatch: jobs: build: runs-on: ubuntu-latest steps: - name: Check out repos uses: actions/checkout@master with: repository: ihcomega56/pyrsia token: ${{secrets.gh_token}} - name: Update repo run: | git remote add pyrsia https://github.com/pyrsia/pyrsia.git git fetch pyrsia git merge pyrsia/main git push origin main
対象はmainブランチのみですが
- コピーのリポジトリをチェックアウトする
- リモート(
git remote
)としてオリジナルを追加する - オリジナルのmainを取り込んでコピーを更新する
というシンプルな流れを実現しており、これを30分に一度回します。こんなんで役に立つかなぁと思ったけど、ローカルで時々コピーをプルするだけなので結構楽になりました。GitHub Actionsは負荷によってcronが遅れたりするようですが、今のところ快適です。あくまで、better than nothingの精神です。
なお、現状はすべてをベタ書きしているのでリポジトリ数が増えたら工夫しないと面倒ですね。
git diffして差分の有無でexit codeを変える
これを実現しようとしている最中に学んだことは1つ。
git diff --exit-code
このオプションにより、git diff
の結果、差分があればプログラムのexit codeを1, なければ0という風に結果を切り替えることができます。
実は、はじめyamlの後半を次のようにしていました。
## (チェックアウトまで中略) - name: Check the diff run: | git remote add pyrsia https://github.com/pyrsia/pyrsia.git git fetch pyrsia git diff --exit-code --quiet pyrsia/main - name: Update repo if: ${{ failure() }} run: | git merge pyrsia/main git push origin main
差分に応じてexit codeを変えて、Actionsの記法if: ${{ failure() }}
と合わせることで「diffがあるときのみマージする」を愚直に実現していたわけです(どうしてこうなったのか自分でも分からない)。冷静に考えて差分がない場合はマージとプッシュを空振りさせておけばいいじゃんということに気付き、よりシンプルな設定となったのでした。
webからワンクリックでも更新できるよね
このボタンもありますね。しばらくGitHubを使っていなかった間に実装されていました。ただ、コピーの方をブラウザで開くのが地味に面倒だったので上記に至りました。もっと良い追従の方法があれば教えてくださーい!