Zolaで作ったサイトをGitHub ActionsでGitHub PagesにDeployする

4 min read読了の目安(約4000字

ターゲット

以下の運用をしている人向けです。

  • Zolaでサイトを作成している
  • サイトをGitHub Pagesで公開している
  • サイトのソース(MarkdownなどZolaでビルドするコンテンツ)とGitHub Pagesで公開するコンテンツ(ビルドしたhtmlなど)のリポジトリを分けている

何故わざわざリポジトリを分けているのかというとMarkdownは下書きを含むため非公開にしておきたいのと、GitHub Pages用にブランチを作るのが嫌だったからです。

参考

説明の前に

今回のDeployまでの流れをを作るのにGitHub Actions で別のリポジトリに git push するという記事の内容を参考にしました。
こちらの記事はHugoを使用しているものですが大変参考になりました。ありがとうございます。

やること

  1. ローカルでssh-keygenして公開鍵を秘密鍵を作成する
  2. GitHub Pagesで公開するリポジトリでDeploy Key(公開鍵)を登録する
  3. ソースを置いているリポジトリでのSecretsにDeploy keysに対応するの秘密鍵を登録
  4. ソースのリポジトリでGitHub Actionsの設定を行う

1.ローカルでssh-keygenして公開鍵を秘密鍵を作成する

ssh-keygen -C "" -t ed25519で公開鍵と秘密鍵を作成しましょう。
-C ""の部分はなくても良いですが私は生成された鍵にホスト名が含まれるのが嫌なので書いています。
ed25519はGitHub側で対応している形式なら何でも良いと思いますが、参考にしたものと同じものを使用しています。

2.GitHub Pagesで公開するリポジトリでDeploy Key(公開鍵)を登録する

GitHub Pagesで公開しているリポジトリのSetting > Deploy Keysと進みAdd deploy keyを押します。
Titleは好きに付けて大丈夫だと思います。自分でわかりやすいものをつけてください。
Keyに作成した公開鍵の中身を貼り付けます。Deployに使用するのでAllow write accessにチェックを入れてAdd Keyを押します。

3.ソースを置いているリポジトリで秘密鍵を登録

ソースを置いているリポジトリのSetting > Secretsと進みNew repository secretを押します。
Nameは何かルールが有るのか、私のときはid_ed25519で始める必要がありました。
Valueに作成した秘密鍵の中身を貼り付けます。
Add secretを押して完了です。

4.ソースのリポジトリでGitHub Actionsの設定を行う

ソースのリポジトリに.github/workflows/main.ymlというGitHub Actionsの設定ファイルを置き、以下の中身を書きます。

name: Build And Deploy

on:
  push:
    # masterに変更があったときだけjobを実行する
    # メインのブランチ名がmainであればmainに書き換えてください
    branches: [ master ]
  pull_request:
    # 上と同じ
    branches: [ master ]

  workflow_dispatch:

jobs:
  build_and_deploy:
    runs-on: ubuntu-latest
    steps:
      # ソースのリポジトリをcheckoutする
      - name: checkout
        uses: actions/checkout@v2

      # zolaをインストールする
      - name: install zola
        run: |
          sudo apt update
          sudo apt install snapd
          sudo snap install zola --edge

      # Deploy先のリポジトリをcheckoutする
      - name: checkout deploy repository
        uses: actions/checkout@v2
        with:
          repository: username/username.github.io # GitHub Pagesで公開しているリポジトリ名
          path: public # zola buildでpublicディレクトリにビルドされる場合はpublicを、publishなど別のディレクトリであればそのディレクトリ名を書く
          fetch-depth: 2
          lfs: true # 必要であれば
          ssh-key: ${{ secrets.XXX }} # XXXには3で登録した秘密鍵のNameを書く(ssh-keyを登録しておくことで後でpushするときに特殊な操作が必要なくなる)

      # checkoutしたリポジトリの.gitをtempに逃がす
      - name: move .git to temp
        run: |
          mkdir ./temp
          mv ./public/.git ./temp

      # publicを削除
      - name: remove public
        run:
          rm -rf ./public

      # ビルド
      - name: zola build
        run:
          zola build

      # ビルドしたディレクトリに.gitを移動
      - name: move .git to public
        run:
          mv ./temp/.git ./public

      # ビルドしたものをコミットしpushする
      - name: deploy
        run: |
          cd ./public
          git add .
          if git diff --cached --quiet ; then # 変更されたファイルがあるかチェック
            # 変更されたファイルがない
            # 後でログを見たときに変更がなかったことがわかるように出力
            echo "No changes"
          else
            # 変更されたファイルがある
            echo "Has changes"
            # ソースのコミット内容と同じ内容でコミットするために一度publicから抜けコミットコメントをcommit_commentに格納
            # 複数コミットがpushされた場合は最後のコメントを格納
            cd ../
            commit_comment=`git log -n 1 --pretty="%s"`
            cd ./public
            # gitの設定
            git config --local user.name username
            git config --local user.email user_email
            git commit -m "$commit_comment"
            git push
          fi

      # 一時的に使用していたファイルを削除
      - name: remove temp and public directorys
        run: |
          rm -rf ./temp
          rm -rf ./public

ところどころコメントしてるので大体何しているかわかると思います。
ソースへのコミットのコメントとGitHub Pagesのリポジトリへのコミットのコメントを揃えたかったのでdeployの処理が若干読みづらくなっています。
不必要であれば削ってください。この処理だと複数コミットがプッシュされたときは最後のコメントしか反映されないので運用でカバーするか書き換える必要があります。

おわりに

2つのリポジトリにコミットする必要がなくなったので楽になったのですが、普段Shell Scriptを書かないのとGitHub Actionsを初めて使用したのでだいぶ苦労しました。
この記事が他の誰かや後の自分の役に立てば嬉しいです。