【GitHub Actions】2つのリポジトリを同期させる方法!ブランチ単位

この記事からわかること
- GitHub Actionsで2つのリポジトリを同期させる方法
- 特定のブランチだけをコピーするには?
index
[open]
\ アプリをリリースしました /
リポジトリが2つありリポジトリAに反映した特定の内容をリポジトリBにも反映させたい場面があると思います。今回はGitHub Actionsを使用してリポジトリAの内容をまるまるリポジトリBにコピーする方法をまとめていきます。基本のこの流れが実装できれば特定のファイルやブランチのみ同期させるみたいなこともできるようになると思います。
GitHub Actionsで2つのリポジトリを同期させる方法
GitHub Actionsを使用してリポジトリAとリポジトリBの内容を同期させる方法をまとめていきます。まずは手順を確認します。
- GitHubにリポジトリAを用意
- GitHubにリポジトリBを用意
- Personal Access Token (PAT)を発行
- PATをリポジトリAのSecrets and variablesに登録
- アクションフローの実装
- リポジトリAにプッシュ
- リポジトリBに同期される
今回は動作確認方法も含めて0から実装していきます。
1.GitHubにリポジトリAを用意
まずはGitHubにリポジトリAを用意します。名前は「Test-GitHubActions-Original-Repository」としておきました。最初は空の状態なので一旦ローカルにリポジトリの中身を作成します。

ローカルに「Test-GitHubActions-Original-Repository」というディレクトリを作成しておき、適当なファイル(index.html)を作成してコミット、プッシュまでしておきます。
$ cd Test-GitHubActions-Original-Repository
$ git init
$ touch index.html
これでGitHubのリポジトリAには「index.html」のみがプッシュされている状態です。
2.GitHubにリポジトリBを用意
続いてGitHubにリポジトリBを用意します。名前は「Test-GitHubActions-Sync-Repository」としておきました。こちらも最初は空の状態ですが、空の状態のままだと後続の同期処理が正しく動作しないのでGitHubからREADMEファイルなどを一旦追加して空ではない状態にしておきます。
同期されるタイミングで追加したREADMEファイルは無くなります。
3.Personal Access Token (PAT)を発行
GitHub Actionsで実行するコマンド上からリポジトリにアクセスできるようにPersonal Access Token (PAT)を発行しておきます。
- GitHub >「自分のアイコン」>「Settings」>「Developer settings」をクリック
- 「Personal Access Token」>「Fine-grained tokens」をクリック
- 「Generate new token」をクリック
- Token名を入力
- 「Repository access」設定=>「Only select repositories」>リポジトリBを選択
- 「Permissions」設定「Repository permissions」をクリック
- 「Contents」を Read and Writeに変更
- 「Workflows」を Read and Writeに変更
- 「Generate token」 をクリック
生成されたトークンは一度しか表示されないのでコピーしておいてください。詳しい発行方法は以下の記事を参考にしてください。
4.PATをリポジトリAのSecrets and variablesに登録
続いてリポジトリAのSecrets and variablesに先ほど発行したPATを登録していきます。Secrets and variablesは一度登録した内容を再度確認することができないので公開リポジトリでも問題ありません。
- GitHub >「リポジトリA」>「Settings」をクリック
- 「Secrets and variables」>「Actions」をクリック
- 「New Repository secret」をクリック
- 「Name」にSecret名(今回はPAT)、「Secret」にPATを入力
- 「Add Secret」をクリック
これでリポジトリAのGitHub Actionsからsecret.PAT
で指定したPATが取得できるようになります。
5.アクションフローの実装
リポジトリAにGitHub Actionsのフローを記述するための「main.yml」を用意します。GitHub Actions自体の使い方は以下の記事を参考にしてください。
中にはリポジトリAをクローンしてリポジトリBへ同期するための処理を記述していきます。
name: Sync to Repository B
on:
push:
branches:
- main # main ブランチの変更を検知
jobs:
sync:
runs-on: ubuntu-latest
steps:
- name: リポジトリAをクローンしてリポジトリBへ同期する
run: |
# リポジトリA(Test-GitHubActions-Original-Repository)を bare モードでクローン
git clone --bare https://github.com/ユーザー名/Test-GitHubActions-Original-Repository.git repo-b
# クローンしたリポジトリに移動
cd repo-b
# `--mirror` を使って、リポジトリAの全てのブランチ・タグ・リモート設定を
# リポジトリB(Test-GitHubActions-Sync-Repository)に完全同期
git push --mirror https://x-access-token:${{ secrets.PAT_TOKEN }}@github.com/ユーザー名/Test-GitHubActions-Sync-Repository.git
6.リポジトリAにプッシュ / 7.リポジトリBに同期される
これでセットアップは完了です。あとはリポジトリAのmain
ブランチにプッシュしたタイミングでリポジトリAの内容がまるまるリポジトリBにコピーされます。この方法だとソースコードだけでなくブランチなどもまるまるコピーされるので注意してください。
特定のブランチだけを同期する
特定のブランチに更新があるたびに同期させることも可能です。例えばfeature/releaseX.X.X
という形式のブランチを検知対象する場合で実装してみます。リポジトリAに「release.yml」という新しいファイルを作り中に以下のように記述します。
name: Sync Specific Branches to Repository B
on:
push:
branches:
- "feature/release*" # `feature/release*` に一致するブランチの変更を検知
jobs:
sync:
runs-on: ubuntu-latest
steps:
- name: Git をセットアップ
run: |
# GitHub Actions の環境では、通常のユーザーアカウントの代わりに GitHub Actions Bot を使ってコミットやプッシュを実行する必要がある
git config --global user.name "github-actions[bot]"
git config --global user.email "github-actions[bot]@users.noreply.github.com"
- name: リポジトリAのブランチ情報を取得
run: |
set -x # デバッグ用(実行するコマンドを出力)
# リポジトリAをクローン
git clone --bare https://github.com/ユーザー名/Test-GitHubActions-Original-Repository.git repo-a
cd repo-a
echo "すべてのブランチを表示"
git branch -a
# `feature/release*` にマッチするブランチのみ取得
echo "'feature/release*'にマッチするブランチを全て取得"
BRANCHES=$(git branch -a | grep -E 'feature/release.*')
# 取得したブランチ名を出力
echo "見つかったブランチ: $BRANCHES"
# リモートリポジトリBを追加
git remote add target https://x-access-token:${{ secrets.PAT_TOKEN }}@github.com/ユーザー名/Test-GitHubActions-Sync-Repository.git
# 各ブランチを個別にプッシュ
for BRANCH in $BRANCHES; do
git fetch origin $BRANCH
git push target $BRANCH
done
これでfeature/release*
形式でブランチがプッシュされるたびにこのワークフローが動作し、リポジトリAに存在するfeature/release*
形式のブランチをリポジトリBにコピーすることができます。
Git コマンドのおさらい
git clone --bare
git clone --bare
コマンドはワーキングツリー(作業ツリー)を持たないリポジトリのコピーを作成します。ワークツリーがないのでgit status
やgit add
などの作業はできませんがgit push
は可能です。
$ git clone --bare https://github.com/ユーザー名/Test-GitHubActions-Original-Repository.git repo-b
git push --mirror
git push --mirror
コマンドは全てのブランチとタグを別のリポジトリに完全コピーします。
$ git push --mirror https://x-access-token:${{ secrets.PAT_TOKEN }}@github.com/ユーザー名/Test-GitHubActions-Sync-Repository.git
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。