https://tanaka.world/ のパッケージ更新とリリースを自動化した。パッケージ更新時に CI のジョブが全て成功したら master に自動マージし、本番リリースされるようにしている。

例: リリース時のワークフロー

Renovate (Package Update)

Renovate

GitHub App - Renovate からリポジトリを選択して設定する。

Cypress (E2E)

Cypress

手動でやっていた動作確認を Cypress で自動化した。各ページごとにざっくりテストしている。(テストコード)

Cypress のテストコードも TypeScript で記述する。Cypress の型定義ファイルを読み込むと、アプリケーション側の Jest の型定義と競合するため tsconfig.cypress.json を別途追加している。

GitHub Actions (CI/CD)

Merge 前に実行する用と、リリース用の2つのワークフローがある。

before-merge.yml は、Lint, Unit Test, Build, E2E Test を実行し、release.yml はそれに加えて Deploy を実行する。両者の違いは実行の起点となる branch と Deploy の有無だけなので、YAML インポート的なことがやりたいが、公式にはそのような仕組みは存在しないようだ。冗長だが一旦同じ内容を記述している。

大枠の処理は次の通り。

  1. lint-test-build ジョブで生成されたアプリケーションビルド対して、E2E テストを実行
  2. 対象ブラウザは最低限 chrome, firefox, edge、それぞれ並列で実行される
  3. テストに失敗したら、スクリーンショットと動画をアップロード
  4. (release.yml の場合) テスト済みのビルドをデプロイ
  test-e2e:
    needs: lint-test-build

    strategy:
      matrix:
        node-version: [ 14.15.3 ]
        browser: [ chrome, firefox, edge ]

    steps:
      - uses: actions/checkout@v2
      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v2
        with:
          node-version: ${{ matrix.node-version }}
      - name: Download Artifact
        uses: actions/download-artifact@master
        with:
          name: dist
          path: dist
      - name: E2E by Cypress
        uses: cypress-io/github-action@v2
        with:
          browser: ${{ matrix.browser }}
          command: npm run e2e:ci
      - uses: actions/upload-artifact@v2
        if: failure()
        with:
          name: cypress-${{ matrix.browser }}
          path: |
            cypress/videos
            cypress/screenshots            

a-workflow-for-release.png

Auto Merge Setting

GitHub リポジトリの設定で Allow auto-merge を有効にする。 P-R の merge requirements が全て完了したら自動でマージしてくれるようになる。

github-repo-allow-auto-merge.png

商用のアプリケーションであれば人間がリリース判定した方がいいかもしれない。tanaka.worldはそうではなく、E2E で動作は担保されているのでカジュアルにリリースすることにした。