Tech Racho エンジニアの「?」を「!」に。
  • Ruby / Rails以外の開発一般

GitHub Pagesでフロントエンド開発のステージング環境を手軽に構築する(翻訳)

概要

元サイトの許諾を得て翻訳・公開いたします。

日本語タイトルは内容に即したものにしました。

GitHub Pagesでフロントエンド開発のステージング環境を手軽に構築する(翻訳)

はじめに

ステージング(staging)環境のセットアップは、Web開発プロセスにおいて重要な部分であり、開発者は「新機能のお試し」「共同作業」「ランスルーテスト」「バグ修正」をここで行います。ステージング環境の構築方法はさまざまですが、本記事では、予算が限られている小規模プロジェクトを対象にして、財布に優しいステージング環境のセットアップ方法を解説します。他にも、プルリクを別のWebドメインにデプロイするなどの実用的な方法についても解説します。

フロントエンド開発用のステージング環境は、多種多様な選択肢の中から選んで実装できます。

Webアプリケーションをボタン1つでデプロイできるVercelやNotifyなどのホスティングサービスを使う方法もその1つですが、このオプションを利用できるのは、自分たちがホスティングサービスの顧客である場合だけです。

そうしたホスティングサービスでアプリケーションをホスティングしていないのであれば、AWSやGoogle CloudやHerokuなどのクラウドサービスでステージング環境を構築する方法もあります。こちらの方が柔軟性に優れているものの、場合によってはかなりの専門知識とカスタマイズの労力を必要とします。

しかし、追加費用を出す余裕のない小規模プロジェクト用にステージング環境を手軽に実装する方法は他にもいくつかあります。本記事ではその中から、GitHub Pagesを用いてプロジェクトのフロントエンド部分のstagingブランチを簡単に作成する方法を検討することにします。この方法では、stagingブランチをmainブランチにマージするときに、ブランチでの変更や削除を自動的に伝播させるプロセスも含まれます。これにより、プロジェクトへの変更内容と、変更したユーザーを明確に把握できるようになります。なお私は個人的にStorybookをこの種の目的に利用していますが、皆さんの好みのツールを自由に利用できます。

🔗 基本部分のセットアップ

最初に、プロジェクトで空のブランチを1つ作成します。これからこのブランチで魔法が行われます。作成したら、GitHubのリポジトリ設定ページを開き、サイドメニューの[Settings]でGitHub Pagesをそのブランチに対して有効にします。なお、私の場合はstorybook-pagesというブランチにしています。

作成したブランチでGitHub Pagesを有効にした様子

作成したブランチでGitHub Pagesを有効にした様子

なお、カスタムドメインが必要な場合は以下のガイドを利用できます。

参考: GitHub Pages サイトのカスタムドメインを設定する - GitHub Docs


次のステップでは、プロジェクトのrootディレクトリに.githubフォルダを作成し、さらに.githubフォルダの下に workflowsフォルダも作成します。この後で、 workflowsフォルダの中にGitHub Actions用のファイルを2つ追加する必要があります。ファイル1はデプロイ用、ファイル2はブランチ削除用です。

GitHub上の環境を正常に削除するには、GitHubのパーソナルアクセストークン(Personal Access Token)を取得しておく必要があります。このトークンを生成するには、GitHubサイトで自分のアカウントページを開き、サイドメニューの[Developer settings]をクリックします。表示されたページで、サイドメニューの[Personal Access Tokens]を展開して[Fine-grained personal access tokens]を選択し、パーソナルアクセストークンを作成します。

"fine-grained"トークン

新規トークンを生成するときには、有効期間を指定しておくことが重要です(作成日から最長で1年)。さらに、このトークンに付与する権限も指定しなければなりません。ステージング環境を削除するには、[Read access to metadata](メタデータの読み取り)パーミッションに加えて[Read and Write access to administration and deployment](管理とデプロイの読み取りと書き込み)パーミッションも必要です。また、トークンの作成中に、どのリポジトリで環境を削除するかを指定する必要もあります。

ヒント: トークンを作成するときに与える権限は最小限にとどめましょう。またデジタル衛生(digital hygiene)のためにも、トークンを複数のリポジトリで使い回さず、リポジトリごとにトークンを作成しましょう。

トークンのパーミッション

トークンのパーミッション

GitHub上の環境を削除するうえでは、パーソナルアクセストークンを取得しておくことが重要なステップである点にご注意ください。このトークンがなければ、環境を削除することも、デプロイを効率よく管理することもできません。上の手順に沿って新しいトークンを適切な権限で作成しておけば、環境を正常に削除してデプロイを合理化できるようになります。


作成が終わったら、作成したパーソナルアクセストークンをリポジトリの設定に追加する必要があります。リポジトリの[Settings]タブでサイドメニューの[Secrets and variables]を展開して[Actions]をクリックします。次に[New repository secret]ボタンをクリックして、[Name]フィールドに名前を入力し、[Secret]フィールドにトークンそのものを貼り付けます。入力する名前は後で必要になるので、どこかにメモしておきましょう。

トークンを追加する

トークンを追加する

ヒント: ビルド内のファイル名にアンダースコア_が使われていると、デプロイ時にそれらのファイルにアクセスできない(=リクエスト時に404エラーが表示される)場合があります。その理由は、GitHub Pagesではアンダースコアを含むファイル名がサポートされていないからです(参考)。この問題を解決するには、GitHub Pagesのブランチのrootディレクトリに.nojekyllファイルを作成してからGitHubで実行する必要があります。これにより、GitHub PagesでJekyll固有の機能がバイパスされ、アンダースコアを含むファイル名をデプロイできるようになります。

🔗 ファイル1: ビルドとデプロイ用

.github/workflows/preview.ymlというファイルを作成します。GitHub Actionsで使う最初のファイルを見てみましょう。

name: Build and Deploy
on:
  push:
  pull_request:
    types: [reopened]

permissions:
  contents: write
  pull-requests: write
  deployments: write

env:
  BRANCH_NAME: ${{ github.head_ref || github.ref_name }}

jobs:
  build-and-deploy:
    concurrency: ci-${{ github.ref }}
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Create deployment
        uses: bobheadxi/deployments@v1
        id: deployment
        with:
          step: start
          token: ${{ secrets.GITHUB_TOKEN }}
          env: staging-${{ env.BRANCH_NAME }}

      - uses: actions/setup-node@v3
        with:
          node-version: 18

      - name: Building Storybook
        run: |
          yarn
          STORYBOOK_BUILD_PATH=${{ env.BRANCH_NAME }} yarn run build-storybook

      - name: Create a version mark
        run: |
          touch ./storybook-static/${{ github.sha }}.txt

      - name: Pushing to pages branch
        uses: JamesIves/github-pages-deploy-action@v4
        with:
          branch: storybook-pages
          folder: storybook-static
          target-folder: ${{ env.BRANCH_NAME }}

      - name: Wait for GitHub Pages to be deployed
        uses: mydea/action-wait-for-api@v1
        with:
          url: https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}/${{ env.BRANCH_NAME }}/${{ github.sha }}.txt
          expected-status: 200
          timeout: 600
          interval: 15

      - name: Update deployment status
        uses: bobheadxi/deployments@v1
        if: always()
        with:
          step: finish
          token: ${{ secrets.GITHUB_TOKEN }}
          status: ${{ job.status }}
          env: ${{ steps.deployment.outputs.env }}
          deployment_id: ${{ steps.deployment.outputs.deployment_id }}
          env_url: https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}/${{ env.BRANCH_NAME }}

deploymentsというGitHub Actionのおかげで、プルリクのデプロイステータスを手軽に表示できます。[View deployment]ボタンをクリックすれば、プルリクのビルドをブラウザの別ウィンドウで開けます。

bobheadxi/deployments - GitHub

いくつかの仕様により、rootブランチのデプロイが完了するまでデプロイへのリンクは有効になりません。プルリクデプロイのステータスが正しいことを確認するために、Create a version tagステップを作成することにします。このステップでは、storybook-staticフォルダ内に、コミットのハッシュを名前に持つファイルを作成します。これにより、rootブランチがデプロイされるのを待ってから、プルリクにデプロイのステータスが表示されるようになります。

なお、Storybookを使わない場合は、Pushing to pages branchステップのfolderで指定したフォルダ内に、コミットのハッシュを名前に持つファイルを作成する必要があります(つまりこれをビルドディレクトリのrootにする必要があります)。

'Deployment status'ページ

"Deployment status"ページ

なお、envフィールドやenv_urlフィールド内のリンクは自動生成されるので、変更は不要です。

ここで注目いただきたいのは、このリポジトリでは以下のようにすべてのアクティブな環境が表示されるので、環境の個数を管理することも、ビルドに素早くアクセスすることも可能になる点です。

アクティブな環境のリスト

アクティブな環境のリスト

この.github/workflows/preview.ymlファイル内では、BRANCH_NAME変数を使うことが重要です。この変数には、プルリクが行われたブランチ名を代入します。これは、後でプルリクがmainブランチにマージされるときにデプロイブランチを削除可能にするために必要となります。

また、github.head_ref変数も必要です。

  • (forkからではなく)このブランチからプルリクが行われると、プルリクが行われたブランチ名をこの変数に渡します。
  • forkからプルリクが作成された場合はgithub.head_ref変数が使われ、プルリクを行ったブランチ名をこの変数に渡します。
    これは、後でプルリクがmainブランチにマージされるときにデプロイブランチを削除可能にするために必要となります。

特定ファイルが変更された場合にのみデプロイブランチを作成したい場合は、.github/workflows/preview.ymlファイルのonセクションに以下のコードを追加します。

on:
  push:
    paths:
      - 'root/path_to_file'

🔗 ファイル2: ブランチ削除用

2番目の.github/workflows/cleanup.ymlファイルは、プルリクがmainブランチにマージされるときにデプロイブランチを削除する役割があります。

name: Cleanup Stale Pages
on:
  pull_request:
    types: [closed]
permissions:
  contents: write
  pull-requests: write
  deployments: write

env:
  BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
jobs:
  remove_stale_pages:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - uses: actions/setup-node@v3
        with:
          node-version: 18

      - name: Create an empty dir
        run: |
          mkdir storybook-dummy
          touch storybook-dummy/.gitkeep

      - name: Pushing to pages branch
        uses: JamesIves/github-pages-deploy-action@v4
        with:
          branch: storybook-pages
          folder: storybook-dummy
          target-folder: ${{ env.BRANCH_NAME }}

      - name: Delete deployment
        uses: bobheadxi/deployments@v1
        if: always()
        with:
          step: delete-env
          token: ${{ secrets.REMOVE_ENV_TOKEN }}
          env: staging-${{ env.BRANCH_NAME }}

このファイルのtokenフィールドには、GitHubリポジトリ設定の[Actions secrets and variables]セクションで追加したトークン名を指定する必要があります(トークン名をメモするよう指示したのを覚えていますか?)

このファイル2を使って、storybook-pagesブランチに空のフォルダを1個作成し、プルリクを行ったブランチ名を使ってブランチにプッシュします。これにより、デプロイブランチが削除されます。

Storybookを正しいブランチでビルドするには、.storybook/main.jsファイルで以下の変数を設定します。

const { STORYBOOK_BUILD_PATH } = process.env;
const REPO_NAME = 'YOUR_REPO_NAME';

リポジトリ名を含めるときの例

利用するコンフィグ(プロジェクトのコンフィグとStorybookのコンフィグ)に接続するメソッドでは、以下のようにViteConfigのメソッドを利用して以下のコードを書きます。

if (configType === 'PRODUCTION') {
  config.base = `/${REPO_NAME}/${STORYBOOK_BUILD_PATH}`;
}

これにより、「プルリクが作成されたブランチ名」を名前に持つフォルダを作成するようStorybookに指示されます。

🔗 試してみる

すべての設定が完了したら、次のステップはプルリクを作成することです。新しいプルリクを作成するオプションを選択して、必要な情報を入力するだけで済みます。

プルリクが作成されると、ブランチのデプロイビルドへのリンクを含むコメントがそのプルリクに追加されていることがわかります。他の人がこのリンクを使って変更内容を確認したり、必要に応じてフィードバックしたりできます。

以上でおしまいです!このプロセスは全般的に、共同作業を効率化して、チームの全メンバーが最新の変更内容を確実に把握可能にするうえで有用です。


Evil Martiansは、成長段階のスタートアップ企業をユニコーン企業に飛躍させるためにサポートいたします。開発ツールの構築やオープンソース製品の開発も行っています。ワープの準備が整ったお客様、ぜひフォームまでご相談をお寄せください!

関連記事

GitHub ActionsにVercelのGitHub連携っぽいことをやらせてみる


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。