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

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

この記事からわかること

  • GitHub Actions2つリポジトリ同期させる方法
  • 特定ブランチだけをコピーするには?

index

[open]

\ アプリをリリースしました /

みんなの誕生日

友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-

posted withアプリーチ

リポジトリが2つありリポジトリAに反映した特定の内容をリポジトリBにも反映させたい場面があると思います。今回はGitHub Actionsを使用してリポジトリAの内容をまるまるリポジトリBにコピーする方法をまとめていきます。基本のこの流れが実装できれば特定のファイルやブランチのみ同期させるみたいなこともできるようになると思います。

GitHub Actionsで2つのリポジトリを同期させる方法

GitHub Actionsを使用してリポジトリAとリポジトリBの内容を同期させる方法をまとめていきます。まずは手順を確認します。

  1. GitHubにリポジトリAを用意
  2. GitHubにリポジトリBを用意
  3. Personal Access Token (PAT)を発行
  4. PATをリポジトリAのSecrets and variablesに登録
  5. アクションフローの実装
  6. リポジトリAにプッシュ
  7. リポジトリBに同期される

今回は動作確認方法も含めて0から実装していきます。

1.GitHubにリポジトリAを用意

まずはGitHubにリポジトリAを用意します。名前は「Test-GitHubActions-Original-Repository」としておきました。最初は空の状態なので一旦ローカルにリポジトリの中身を作成します。

GitHubからリモートリポジトリを作成する手順

ローカルに「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)を発行しておきます。

  1. GitHub >「自分のアイコン」>「Settings」>「Developer settings」をクリック
  2. 「Personal Access Token」>「Fine-grained tokens」をクリック
  3. 「Generate new token」をクリック
  4. Token名を入力
  5. 「Repository access」設定=>「Only select repositories」>リポジトリBを選択
  6. 「Permissions」設定「Repository permissions」をクリック
  7. 「Contents」を Read and Writeに変更
  8. 「Workflows」を Read and Writeに変更
  9. 「Generate token」 をクリック

生成されたトークンは一度しか表示されないのでコピーしておいてください。詳しい発行方法は以下の記事を参考にしてください。

4.PATをリポジトリAのSecrets and variablesに登録

続いてリポジトリAのSecrets and variablesに先ほど発行したPATを登録していきます。Secrets and variablesは一度登録した内容を再度確認することができないので公開リポジトリでも問題ありません。

  1. GitHub >「リポジトリA」>「Settings」をクリック
  2. 「Secrets and variables」>「Actions」をクリック
  3. 「New Repository secret」をクリック
  4. 「Name」にSecret名(今回はPAT)、「Secret」にPATを入力
  5. 「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 statusgit 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

まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。

ご覧いただきありがとうございました。

searchbox

スポンサー

ProFile

ame

趣味:読書,プログラミング学習,サイト制作,ブログ

IT嫌いを克服するためにITパスを取得しようと勉強してからサイト制作が趣味に変わりました笑
今はCMSを使わずこのサイトを完全自作でサイト運営中〜

New Article

index