All Articles

Github Free ユーザーでも公開記事以外のファイルを Private リポジトリで管理したい!

今回はGatsbyとGithub Pagesで運用しているこのブログで、公開する記事以外のファイルをPrivateリポジトリで管理する運用方法についてまとめます。

GithubのPro以上のサブスクリプションであれば、Privateリポジトリでも特定のブランチのみをGithub Pagesで公開することができますが、Github Actionsを使うことでFreeのユーザーでも公開記事以外のファイルをPrivateリポジトリで管理できるようにしたいと思い、この記事の手順を使用しました。

もくじ

事前準備

この手順を実施するために、事前に以下の準備が必要になります。

  • Freeユーザーで登録されているGithubアカウント
  • 公開ページを作成するためのファイルとGithub Actionsを管理するPrivateリポジトリ
  • 静的サイトジェネレータにより生成された公開記事のみを配置し、Github Pagesで公開するPublicリポジトリ

静的サイトジェネレータの使用方法やGithub Pagesの設定については本記事の対象外としています。

ローカルでGatsbyを使用し、デプロイされた記事をGithub Pagesで公開する方法については以下をご参照ください。

参考:Gatsbyで作成したSPAブログをGitHubPagesに公開する環境を作る備忘録 - かえるのひみつきち

Gatsbyの自動デプロイを構成する

まずはGatsbyやマークダウンを管理するPrivateリポジトリにて以下のGithub Actionsを追加します。

name: deploy-and-push
on:
  push:
    branches:
      - main
jobs:
  deploy-and-push:
    runs-on: ubuntu-latest
    container: kashiwabayuki/gatsby-env

    steps:
    - uses: actions/checkout@v2
      with:
        submodules: true

    - name: Install npm
      env:
        NODE_OPTIONS: "--max_old_space_size=4096"
      run: npm install

    - name: Deploy
      run: gatsby clean && gatsby build --prefix-paths && echo 'kashiwaba-yuki.com' > public/CNAME

    - name: Pushes to public repository
      uses: cpina/github-action-push-to-another-repository@main
      env:
        SSH_DEPLOY_KEY: ${{ secrets.SSH_DEPLOY_KEY }}
      with:
        source-directory: './public'
        destination-github-username: 'kash1064'
        destination-repository-name: 'Kaeru-no-Himitsukichi-Public'
        user-email: kashiwabayuki@gmail.com
        target-branch: public

自動デプロイのためのGithub Actionについて

上から順に見ていきます。

まず、以下の箇所は、アクションの名前と実行されるタイミングを定義しています。

今回は、mainリポジトリにpushされたタイミングで実行するようにします。

name: deploy-and-push
on:
  push:
    branches:
      - main

続いて、jobの中でubuntu-latestのワークフローを使用し、kashiwabayuki/gatsby-envという自作のデプロイ用のコンテナを用意させています。

deploy-and-push:
  runs-on: ubuntu-latest
  container: kashiwabayuki/gatsby-env

このコンテナイメージは、以下の記事の手順で作成したものです。

参考:Gatsbyで作成したSPAブログをGitHubPagesに公開する環境を作る備忘録 - かえるのひみつきち

そして、actions/checkout@v2を使用してPrivateリポジトリ内のmainブランチのファイルをコンテナにcloneし、actions/checkout@v2で依存関係のnode moduleをインストール、最後にgatsbyコマンドで記事をビルドしています。

ちなみに、nom installgatsby buildの完了までに、合わせて10分程度要しています。リソース的にも無駄が多いですし、Privateリポジトリの場合は2000分/月の実行時間制限もあるのでこの時間は短縮したいのですが、中々いいアイデアが浮かびませんでした。

記事の公開時にしかこのActionsは動かないですし、2000分はどう考えても超えないはずなので一旦保留にしてます。

また思いついたら修正しようと思います。

steps:
- uses: actions/checkout@v2
  with:
    submodules: true

- name: Install npm
  env:
    NODE_OPTIONS: "--max_old_space_size=4096"
  run: npm install

- name: Deploy
  run: gatsby clean && gatsby build --prefix-paths && echo 'kashiwaba-yuki.com' > public/CNAME

この時、NODE_OPTIONS: "--max_old_space_size=4096"をセットしないとnpm installがタイムアウトで失敗しました。

これでコンテナ内の./publicディレクトリに公開用のファイルがビルドされたので、生成されたファイルをPublicリポジトリにpushします。

Github Actionsで他のリポジトリにファイルをPushする

Github Actionsで他のリポジトリにファイルをPushする場合は、Push先のリポジトリに対して書き込み可能なDeploy Keyをセットする必要があります。

このキーを登録するために、事前にssh-keygenコマンドで公開鍵と秘密鍵のペアを生成しておきます。

Github Actionsを実行するリポジトリ(ソースリポジトリ)に秘密鍵を登録する

まずは、Github Actionsを実行するリポジトリに秘密鍵を登録します。

GithubのリポジトリページのSettingsにて、[Secrets]>[Actions]から新しいSecretoを登録できます。

この時、Secretの名前はSSH_DEPLOY_KEYとしておきます。

image-20221029005654913

SSH_DEPLOY_KEYは、以下の通りcpina/github-action-push-to-another-repository@mainの処理で使用されます。

name: Pushes to public repository
	uses: cpina/github-action-push-to-another-repository@main
    env:
    	SSH_DEPLOY_KEY: ${{ secrets.SSH_DEPLOY_KEY }}

Push先のリポジトリに公開鍵を登録する

次に、公開用のリポジトリのSettingsからDeploy keyに公開鍵を登録します。

このTitleは任意の名前でOKですが、[Allow write access]のチェックは有効にする必要があります。

image-20221029010004464

これで、ソースのリポジトリと公開用のリポジトリに秘密鍵と公開鍵のペアが登録されました。

Github Actionsで他のリポジトリにファイルをPushする

ここまでですべての準備が整ったので、最後にデプロイされたGatsbyのファイルを公開用のPulicリポジトリにPushします。

処理を自作してもいいのですが、今回はcpina/github-action-push-to-another-repositoryを使わせてもらうことにしました。

以下の処理をstepの最後に追加しています。

name: Pushes to public repository
  uses: cpina/github-action-push-to-another-repository@main
  env:
    SSH_DEPLOY_KEY: ${{ secrets.SSH_DEPLOY_KEY }}
  with:
    source-directory: './public'
    destination-github-username: 'kash1064'
    destination-repository-name: 'Kaeru-no-Himitsukichi-Public'
    user-email: kashiwabayuki@gmail.com
    target-branch: public

詳しくは以下のドキュメントにある通りですが、cpina/github-action-push-to-another-repositoryではSecretにセットされた秘密鍵を使用して、コンテナ内の任意のディレクトリを指定のリポジトリにPushすることができます。

参考:Overview — github-action-push-to-another-repository documentation

今回は、Gatsbyのデプロイされたファイルが配置される./publicディレクトリを、公開用のリポジトリのpublicブランチにPushするよう構成しています。

これでActionが最後まで完了すると、Privateリポジトリの更新をトリガーにビルドされた記事がPublicリポジトリの公開用ブランチにPushされ、Github Pages上のブログが更新されます。

まとめ

Github Actionsは便利。