LoginSignup
14
7

GitHub Actions で Fork 元に自動追従する(Cron で自動的に Upstream を Rebase & Merge するスケジュールを組む)

Last updated at Posted at 2020-07-28

GitHub Actions の schedule + cron で本家に追従したい

GitHub で fork したリポジトリで、フォーク元に変更があった場合にフォーク先も自動で追随させたい。

しかも GitHub だけで完結させたい

つまり、ローカルでの cron 実行や、他の外部サーバーやサービスに依存させたくないのです。

具体的な追随方法はシンプルです。現在の master に、フォーク元である upstream/master の変更を rebasemerge して、リモート先の origin/master に反映(push)することでフォーク元に追随させたいのです。

この時、外部の CI サービスなどを使わずに GitHub Actionsschedule イベントで cron を使って変更をマージさせたいのです。

TL; DR (action、追随の同期息切れに cron)

./.github/workflows/scheduled_sync.yml
# Follow Changes of Forked/Upstream Repository.
#
# This workflow rebase-marge changes from upstream's master to origin's master. 
# - Ref:
#   - https://stackoverflow.com/a/61574295/12102603 by N1ngu @ StackOverflow (EN)
#   - https://qiita.com/KEINOS/items/3bcaa6cea853f6b63475 by KEINOS @ Qiita (JA)

name: Merge upstream branches

# Triggers the action as scheduled
on:
  # Runs on 10 minutes past every hour(毎 n 時 10 分に実行)
  schedule:
    # Ref: 
    #   - https://help.github.com/en/actions/reference/events-that-trigger-workflows#scheduled-events-schedule
    #   - https://crontab.guru/examples.html
    # Cron format:
    #         ┌───────────── minute (0 - 59)
    #         │ ┌───────────── hour (0 - 23)
    #         │ │ ┌───────────── day of the month (1 - 31)
    #         │ │ │ ┌───────────── month (1 - 12 or JAN-DEC)
    #         │ │ │ │ ┌───────────── day of the week (0 - 6 or SUN-SAT)
    #         │ │ │ │ │                                   
    #         │ │ │ │ │
    #         │ │ │ │ │
    #         * * * * *
    - cron:  '10 */1 * * *'

jobs:
  merge:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Merge upstream
        # 以下の設定を変更してください。REPO_FORK が fork 元です。
        env:
          NAME: KEINOS
          EMAIL: github+fork-qiita-news@keinos.com
          REPO_FORK: https://github.com/yyano/Qiita-News.git
        # 追従処理
        run: |
          git config --global user.name ${NAME}
          git config --global user.email ${EMAIL}
          
          : # git rebase をデフォルトに設定
          git config --global pull.rebase merges

          : # "git checkout master" は不要です。デフォルトで設定されます。
          : # しかし下記の設定は重要です。過去のコミットが取得されないと、コミット歴に不統合が
          : # 発生した旨のエラーが出ます。
          git pull --unshallow

          : # フォーク元のリポジトリをリモート先として "upstream" に命名
          git remote add upstream ${REPO_FORK}
          
          : # upstream のブランチをローカルに取得
          git fetch upstream
          
          : # marster ブランチの変更をマージし、clone 元の master に push
          : # ブランチ名を main などに変更していたり、別のブランチにしている場合は注意
          git checkout master
          git merge --no-edit upstream/master
          git push origin master

🐒 【注意点】コンフリクトとクォータ

自分の masterorigin/master) をいじりすぎてフォーク元と異なる場合、かなりの高い頻度でコンフリクトを起こします。ブランチを切ってから作業する習慣がない(master に直接コミットしている)場合には、余計な操作が増えるだけなのでオススメしません。

また、当然ですが、自分の masterorigin/master) からブランチを切ると、この GitHub Action のワークフロー(YAML ファイル)も一緒に付いてきます。

その状態でフォーク元(upstream/master)に PR をするとワークフローも一緒に PR してしまうことになります。相手がよくわからないでマージすると、勝手にアクションが実行されエラーになるので、相手に迷惑をかけないように注意します。フォーク元には PR しないで、同期だけが必要なリポジトリで使うことをオススメします。

俺様カスタム用のリポジトリの場合、筆者は masteroriginal とリネームし、orphan ブランチを main(もしくは master)で作成して、追随は original ブランチにするようにしています。

なお、GitHub Actions で無料で使える実行時間は約 33 時間/月です。これを越えると、翌月まで使えなくなります。

動作サンプル・リポジトリ

GitHub App

GitHub Actions でなく、サードパーティーが提供している GitHub Apps を使うなら wei/pull も簡単。

TS; DR

設定方法

  1. リポジトリをフォークして、フォーク元のリポジトリ URL(HTTPS.git 付き URL)をコピーしておきます。
  2. フォークしたリポジトリの GitHub 上にある "Actions" タブから "set up a workflow yourself" を選び、上記(TL; DR)の YAML の内容を設置(コピペ)します。ファイル名は、わかりやすければ何でも構いませんが、拡張子は .yml である必要があります。
  3. cron を実行するタイミング/ユーザー/メールアドレス/フォーク元のリポジトリ URL を変更します。
  4. Start commitCommt new file でコミットします。

フォークしたリポジトリの ./.github/workflows ディレクトリにワークフローが追加され、cron で指定したタイミングで同期が始まるので、GitHub の Action タブで成功しているか確認します。

YAML ファイルの設定内容の概要

ワークフローの名前
name: Merge upstream branches

on:
(以下略)
scheduleイベントにcronの実行タイミングを指定する
name: Merge upstream branches

on:
  schedule:
    # cron の設定: https://crontab.guru/examples.html
    # GitHub にはユーザーごとに実行可能な時間の制限があります。合計時間が制限を
    # 超えないように必要最低限のインターバルで実行するようにします。
    - cron:  '10 */1 * * *'

jobs:
(以下略)
mergeジョブをubuntu上で実行する
name: Merge upstream branches

on:
  schedule:
    - cron:  '10 */1 * * *'

jobs:
  merge:
    runs-on: ubuntu-latest
    steps:
      - (以下略)
checkoutアクションを使ってリポジトリのclone/checkoutを行う
name: Merge upstream branches

on:
  schedule:
    - cron:  '10 */1 * * *'

jobs:
  merge:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: (以下略)
同期処理(pull,rebase,mergeからのpush)
name: Merge upstream branches

on:
  schedule:
    - cron:  '10 */1 * * *'

jobs:
  merge:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Merge upstream
        run: |
      # コミット/マージの実行ユーザー情報
      # NAME、EMAIL は下記 env 項目で設定。
      # なお、GitHub のパスワード/トークンは checkout アクションで設定済み。
          git config --global user.name ${NAME}
          git config --global user.email ${EMAIL}
          
      # デフォルトで git rebase の --rebase-merges を付加
          git config --global pull.rebase merges
          
      # "git checkout master" は checkout アクションで実行済みなので不要。
          
      # unshallow オプションで更新情報のみを pull してくる。これを設定しないと、
      # アップストリーム(Fork 元)から pull するときにも、すべてのブランチデータを
      # 持ってきてしまう。
          git pull --unshallow
          
      # フォーク元のリポジトリの URL をリモート先として登録し、"upstream" と名付ける。
      # REPO_FORK は env で設定。
          git remote add upstream ${REPO_FORK}
          
      # アップストリームのブランチ情報を取得
          git fetch upstream
                    
      # upstream/master の変更をマージして origin/master にプッシュ
          git checkout master
          git merge --no-edit upstream/master
          git push origin master
        env:
          # コミット/マージを行うユーザー情報とフォーク元の git リポジトリの URL(要変更)
          NAME: KEINOS
          EMAIL: github+fork-qiita-news@keinos.com
          REPO_FORK: https://github.com/yyano/Qiita-News.git

参考文献

14
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
7