背景
GitHubのブランチ保護ルール(Ruleset)を使って main
ブランチへの直接pushを禁止している場合、通常の github-actions[bot]
ではpushできません。
さらに、GitHub Pagesの自動ビルドがPRマージ後に重複して実行される問題も発生してました。
このQiita記事では、以下の2点を両立する方法のメモです:
- GitHub Actionsでmainブランチにpushできるようにする
- GitHub Pagesのデプロイを1回だけ実行する
GitHub Appを作成してpush権限を持たせる
- GitHub Developer Settings にアクセス
- 「New GitHub App」を作成
- 以下の権限を付与:
- Repository permissions:
- Contents: Read & Write
- Repository permissions:
- アプリをリポジトリにインストール(「Only select repositories」で対象を限定)
- 「Generate a private key」で
.pem
ファイルを取得
GitHub Secretsへの追加
GitHub Appの APP_ID
と PRIVATE_KEY
を GitHub Actions で使うには、リポジトリの Secrets に登録する必要があります。
リポジトリの「Settings > Secrets and variables > Actions」で以下を登録:
-
APP_ID
: GitHub AppのID -
PRIVATE_KEY
:.pem
の内容(改行含めて)
これで、GitHub Actions内で secrets.APP_ID
と secrets.PRIVATE_KEY
を使ってトークンを生成できるようになります。
GitHub Pagesの設定
- リポジトリの「Settings > Pages」
- 「Build and deployment」→「Source」を「GitHub Actions」に変更
GitHub ActionsでGitHub Appトークンを使ってpush
- name: Create GitHub App token
id: app-token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ secrets.APP_ID }}
private-key: ${{ secrets.PRIVATE_KEY }}
- name: Checkout repository
uses: actions/checkout@v3
with:
token: ${{ steps.app-token.outputs.token }}
- name: Commit and push
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
run: |
git config --global user.name 'your-app-name[bot]'
git config --global user.email 'your-app-id+your-app-name[bot]@users.noreply.github.com'
git add docs/
git diff --cached --quiet || git commit -m "ci: build site"
git push https://x-access-token:${GH_TOKEN}@github.com/${{ github.repository }} HEAD:main
GitHub Pagesのデプロイを workflow_run
で制御
.github\workflows\pages-deploy.yml
name: Deploy to GitHub Pages
on:
workflow_run:
workflows: ["Build and Commit to docs"] # Build and Commit to docs が完了したら実行
types:
- completed
permissions:
contents: read
pages: write
id-token: write
jobs:
deploy:
if: ${{ github.event.workflow_run.conclusion == 'success' }}
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Pages
uses: actions/configure-pages@v5
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: './docs'
- name: Deploy
uses: actions/deploy-pages@v4
※ permissions
に id-token: write
を忘れると OIDC 認証エラーになります。
Build and Commit to docs の内容は以下のようになっています。
.github\workflows\deploy.yml
name: Build and Commit to docs
on:
push:
branches:
- main
paths-ignore:
- 'docs/**'
- 'Readme.md'
pull_request:
branches:
- main
paths-ignore:
- 'docs/**'
- 'Readme.md'
schedule:
- cron: '0 0 * * *'
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Create GitHub App token
id: app-token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ secrets.APP_ID }}
private-key: ${{ secrets.PRIVATE_KEY }}
- name: Checkout repository
uses: actions/checkout@v3
with:
token: ${{ steps.app-token.outputs.token }}
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Install dependencies
run: npm install
- name: Build with Eleventy
run: |
npm install -D cross-env
npx cross-env ELEVENTY_ENV=production npm run build
- name: Commit and push to docs
if: github.event_name == 'push'
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
run: |
git config --global user.name 'your-app-name[bot]'
git config --global user.email 'your-app-id+your-app-name[bot]@users.noreply.github.com'
git add docs/
git diff --cached --quiet || git commit -m "ci: build site on $(date -u +'%Y-%m-%d %H:%M:%S')"
git push https://x-access-token:${GH_TOKEN}@github.com/${{ github.repository }} HEAD:main
参考文献
- GitHub Docs: Installing your own GitHub App
- GitHub Docs: workflow_run
- GitHub Docs: GitHub Pages deployment
- Zenn: GitHub Actionsで保護されたブランチにpushする方法
まとめ
課題 | 解決方法 |
---|---|
mainブランチが保護されていてpushできない | GitHub Appを使ってトークン認証 |
GitHub Pagesが2回実行される |
workflow_run による制御で1回に |
OIDC認証エラー |
permissions に id-token: write を追加 |
これで、セキュアにGitHub Pages運用が可能になる、はず。