はじめに
GitHubのプライベートリポジトリを参照するために、別のOrganizationのプライベートリポジトリに定期的に同期したい場合がありました。
フォーク元・フォーク先がともにプライベートリポジトリの場合の自動同期手順です。
リファレンスが見つからなかったので共有します。Fine-grained personal access token(PAT)を使います。
前提
- フォーク元:
<元のOrg>/<リポジトリ名>(読み取り専用) - フォーク先:
<先のOrg>/<リポジトリ名>(書き込み先)
手順
1. フォーク元用 PAT を作成(読み取り専用)
GitHub → Settings → Developer settings → Personal access tokens → Fine-grained tokens → Generate new token
- Resource owner: フォーク元の Organization
- Repository access: フォーク元リポジトリのみ選択
- Permissions: Contents → Read-only
Organization の場合、管理者の承認が必要なことがある。承認されると「Active tokens」に表示される。
2. フォーク先用 PAT を作成(読み書き)
同様に Fine-grained tokens → Generate new token
- Resource owner: フォーク先の Organization
- Repository access: フォーク先リポジトリのみ選択
- Permissions: Contents → Read and write
Organization の Workflow permissions が「Read only」に制限されている場合、
GITHUB_TOKENでは push できないためこの PAT が必要。
3. Secrets に登録
フォーク先リポジトリ → Settings → Secrets and variables → Actions
| Name | 値 |
|---|---|
UPSTREAM_PAT |
フォーク元用 PAT(読み取り専用) |
FORK_PAT |
フォーク先用 PAT(読み書き) |
4. ワークフローファイルを作成
.github/workflows/sync-fork.yml をフォーク先リポジトリに作成:
name: Sync Fork
on:
schedule:
- cron: '0 0 * * *' # 毎日UTC 0時(JST 9時)に実行
workflow_dispatch: # 手動実行も可能
jobs:
sync:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
repository: <元のOrg>/<リポジトリ名>
token: ${{ secrets.UPSTREAM_PAT }}
path: upstream
fetch-depth: 0 # 完全な履歴が必要(shallow cloneだとマージ失敗)
- uses: actions/checkout@v4
with:
repository: <先のOrg>/<リポジトリ名>
token: ${{ secrets.FORK_PAT }}
path: fork
fetch-depth: 0
- run: |
git config --global user.email "github-actions[bot]@users.noreply.github.com"
git config --global user.name "github-actions[bot]"
cd fork
git remote set-url origin https://x-access-token:${{ secrets.FORK_PAT }}@github.com/<先のOrg>/<リポジトリ名>.git
git remote add upstream ../upstream
git fetch upstream
git merge upstream/main
git push origin main
注意点
-
fetch-depth: 0は必須。省略するとshallow roots are not allowedエラーが発生する -
git remote set-url originで push 先を明示しないと、フォーク元に push しようとして 403 エラーになる -
git configのコミッター情報設定は必須。未設定だとマージコミット作成時にエラーになる - スケジュール実行は混雑時に数分〜1時間遅れることがある。「Run workflow」で手動実行して動作確認すること
- GitHub Free プランでもプライベートリポジトリで月2,000分まで無料で利用可能
おわりに
ほぼkiroがやりましたが、トライ&エラーで1時間くらいかかりました。