🍭

Github ActionsでプルリクにStorybookのプレビューURLを発行する時短ハック

6 min read 1

1. はじめに

「やつはとんでもないものを盗んでいきました。…私の時間です」

2. やりたいこと

フロントエンドのレビュー時間の削減、また変更点が他の場所へ悪影響を与えていないかをチェックするのは大変な作業です。
今回は、プルリクを送ったときに、Cloud storageを活用してStorybookのプレビューのURLを発行するGithub Actionsを作成したいと思います。

下のようなラベルを用意して、このラベルがついているプルリクエストを検知したときに、動作するアクションを作りたいと思います。

3. 作ったワークフローファイル

.github/workflows/storybook.yml
name: Storybook preview deploy

on:
  pull_request:
    types: [labeled, synchronize, closed]

jobs:
  Preview-Deploy:
    if: ${{ contains(toJson(github.event.pull_request.labels), '[Preview] Storybook') && github.event.action != 'closed' }}
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v1

      - name: Enable node
        uses: actions/setup-node@v1
        with:
          node-version: 12.x

      - name: Install dependencies
        run: yarn install

      - name: Build storybook
        run: yarn build-storybook

      - name: Rename storybook-static folder
        run: |
          mv storybook-static pr_${{github.event.pull_request.number}}

      - id: upload-files
        uses: google-github-actions/upload-cloud-storage@main
        with:
          credentials: ${{ secrets.GCP_CREDENTIALS }}
          path: ./pr_${{github.event.pull_request.number}}
          destination: ${{ secrets.BUCKET_NAME }}

      - name: Comment PR
        uses: thollander/actions-comment-pull-request@master
        with:
          message: |
            Hi there :wave:
            I've deployed the latest preview for you!

            https://storage.googleapis.com/${{ secrets.BUCKET_NAME }}/pr_${{github.event.pull_request.number}}/index.html
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

  Clean-Up:
    if: ${{ contains(toJson(github.event.pull_request.labels), '[Preview] Storybook') && github.event.action == 'closed' }}
    runs-on: ubuntu-latest
    steps:
      - name: Set up Cloud SDK
        uses: google-github-actions/setup-gcloud@master
        with:
          service_account_key: ${{ secrets.GCP_CREDENTIALS }}
          export_default_credentials: true

      - name: Delete storybook preview bucket
        run: gsutil rm -r gs://storybook-preview/pr_${{github.event.pull_request.number}}

      - name: Comment PR
        uses: thollander/actions-comment-pull-request@master
        with:
          message: |
            ✅ Clean up was successful.
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

4. 細かい部分の解説

上のワークフローをもっと細かく見ていきましょう。

● Actionが起動する条件

name: Storybook preview deploy

on:
  pull_request:
    types: [labeled, synchronize, closed]

on: pull_request はプルリクエストに関する全てのイベントを対象に起動する条件です。今回はさらに、typesによってプルリクエストの特定のイベントを対象とするように絞り込んでいます。

  • labeled はプルリクエストに新しいラベルがつけられた時に発生するイベントです。
  • synchronize はコードが更新された時に発生するイベントです。
  • closed はプルリクエストが閉じられた時に発生します。

今回は、labeledで新しいStorybookのURLを用意し、synchronizeのときに更新、closedの時にクリーンアップを行うようにしました。

● Preview Deploy

GCP_CREDENTIALSは、コントロールパネルの方であらかじめ発行しておきましょう。
BUCKET_NAMEには、作成したCloud storageのバケット名を指定します。バケットはWeb上からアクセスできるように権限を編集する必要があります。

そして、上の二つのシークレットをGithub上で保存しておきます。

jobs:
  Preview-Deploy:
    if: ${{ contains(toJson(github.event.pull_request.labels), '[Preview] Storybook') && github.event.action != 'closed' }}
    runs-on: ubuntu-latest
    steps:
      - name: Checkout #省略
      - name: Enable node #省略
      - name: Install dependencies  #省略
      - name: Build storybook # storybookの静的ファイルを生成
        run: yarn build-storybook
	
      - name: Rename storybook-static folder # ディレクトリ名をPR番号に変更する
        run: |
          mv storybook-static pr_${{github.event.pull_request.number}}

      - id: upload-files # Clous storageにアップロードする
        uses: google-github-actions/upload-cloud-storage@main
        with:
          credentials: ${{ secrets.GCP_CREDENTIALS }}
          path: ./pr_${{github.event.pull_request.number}}
          destination: ${{ secrets.BUCKET_NAME }}
	  
      - name: Comment PR # URLをPRにコメントする
        uses: thollander/actions-comment-pull-request@master
        with:
          message: |
            Hi there :wave:
            I've deployed the latest preview for you!

            https://storage.googleapis.com/${{ secrets.BUCKET_NAME }}/pr_${{github.event.pull_request.number}}/index.html
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

今回は、labeled=新規デプロイ・synchronize=更新 という感じですので、If条件により Closed 以外のアクションが行われた場合に発動させます。

また、ディレクトリ名をPR番号にすることで、他のPRとの干渉を避けます。

● Clean Up (オプション)

PRがクローズ後に、プレビューを見ることがない場合にはクリーンアップの処理を書いておくといいと思います。

jobs:
  Clean-Up:
    if: ${{ contains(toJson(github.event.pull_request.labels), '[Preview] Storybook') && github.event.action == 'closed' }}
    runs-on: ubuntu-latest
    steps:
      - name: Set up Cloud SDK
        uses: google-github-actions/setup-gcloud@master
        with:
          service_account_key: ${{ secrets.GCP_CREDENTIALS }}
          export_default_credentials: true

      - name: Delete storybook preview bucket
        run: gsutil rm -r gs://storybook-preview/pr_${{github.event.pull_request.number}}

      - name: Comment PR
        uses: thollander/actions-comment-pull-request@master
        with:
          message: |
            ✅ Clean up was successful.
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}	  

If条件により アクションがClosedの場合に発動させます。 gsutilで該当のPR番号のディレクトリを削除します。

4. まとめ

以上です。
ちょっと今回は文章が乱雑ですがお許しください。 >_<

いつもご支援ありがとうございます!

Discussion

contains は配列と文字列の両方が扱えるので
contains(toJson(github.event.pull_request.labels), '[Preview] Storybook') の部分は contains(github.event.pull_request.labels.*.name, '[Preview] Storybook') と書けますよ。

ログインするとコメントできます