PR TIMESフロントエンドのCI パイプラインを改善して、CI 処理時間とBillable Time を50%を削減した話

  • URLをコピーしました!

ここんにちはPR TIMES開発本部のインターンの Chanoknan です。

PR TIMESについてフロントエンドのCI パイプラインを改善についてお話しします。

PR TIMESでは、Reactで書かれたすべてのフロントエンドのコードのコードはMonorepo として管理しています。 そのMonorepoのCI パイプラインは、システム全体のLint、Type Check、Test、Buildを行うようにCIパイプラインが設定されており、これにはかなりの時間がかかり、GitHub ActionsのBillable Timeにも影響を与えます。これを緩和するため、CI処理時間を減らすためのいくつかの戦略を実施しています。詳細については、以下の記事を参照してください。

あわせて読みたい
フロントエンドのGitHub Actions実行時間を削減するために取り組んだこと こんにちは、フロントエンドエンジニアの小張です。GitHub Actionsの実行時間を削減するために取り組んだことについて紹介します。 【経緯】 PR TIMESではReactに関する...

しかし、リポジトリが大きくなるにつれて、CIの時間も長くなりました。これに対処するために、CIパイプラインをさらに改善しました。何を行ったかをお話します。

目次

改善できる点を特定する

この作業に取り組む前、私はCIパイプラインやGitHub Actionsについて詳しくありませんでした。そのため、調査は先輩エンジニアによって行われました。分析の結果、改善すべき2つの領域を特定しました。

  1. Pull Requestに差分がある場合にのみStorybookのテストを実行するようにする
  2. 必要な場合にのみPR TIMES EditorをIntegration testを実行するようにする

先輩エンジニアにPR TIMES EditorのIntegration testを確認してもらい、自分はPull Requestに差分がある場合にのみStorybookのテストを実行するように設定を任されました。

Pull Requestに差分がある場合にのみStorybookのテストを実行するようにする

PR TIMESでは、StorybookをUI開発ツールとしてだけでなく、UIコンポーネントのUnit test にも使用しています。

現在は500以上の*.stories.tsxファイルを持っており、Storybookのテスト実行にはCIパイプラインで9〜10分かかります。これを改善するために行った方法は次の通りです。

まず、StorybookのテストがPull requestに変更がある場合にのみ実行されるようにする必要があります。元々の設定では、WorkflowをTriggerされるとき、dependneciesをインストール、Playwrightのインストール、Storybookのビルド、そしてテストの実行を行っています。以下は、公式ドキュメントで紹介されているワークフローの例です。

# .github/workflows/storybook-tests.yml
name: 'Storybook Tests'
on: push
jobs:
  test:
    timeout-minutes: 60
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version-file: '.nvmrc'
      - name: Install dependencies
        run: yarn
      - name: Install Playwright
        run: npx playwright install --with-deps
      - name: Build Storybook
        run: yarn build-storybook --quiet
      - name: Serve Storybook and run tests
        run: |
          npx concurrently -k -s first -n "SB,TEST" -c "magenta,blue" \
            "npx http-server storybook-static --port 6006 --silent" \
            "npx wait-on tcp:6006 && yarn test-storybook"

テストが必要なときだけ実行されるようにすることで、CIパイプラインでのテストにかかる時間を大幅に削減できます。

これを実現するために、tj-actions/changed-files を使用して変更のないディレクトリを除外し、変更のあるディレクトリでのみStorybookのテストを実行するようにしました。実装方法は以下の通りです。

 steps:
      - name: Assess need for feature tests
        id: filter
        uses: tj-actions/changed-files@v44
        with:
          files_yaml: |
            src/features/company-detail:
              - apps/prtimes/src/features/company-detail/**
            src/features/company-registration:
              - apps/prtimes/src/features/company-registration/**
            src/features/dashboard:
              - apps/prtimes/src/features/dashboard/**
            src/features/dashboard-renewal:
              - apps/prtimes/src/features/dashboard-renewal/**  
            src/features/media-list:
              - apps/prtimes/src/features/media-list/**
            src/features/media-list-renewal:
              - apps/prtimes/src/features/media-list-renewal/**
            src/features/press-release-editor:
              - apps/prtimes/src/features/press-release-editor/**
            src/features/press-release-editor-v3:
              - apps/prtimes/src/features/press-release-editor-v3/**
            src/features/press-release-list:
              - apps/prtimes/src/features/press-release-list/**
            src/features/preview-press-release:
              - apps/prtimes/src/features/preview-press-release/**
            src/features/price:
              - apps/prtimes/src/features/price/**
            src/components:
              - apps/prtimes/src/components/**
            src/templates:
              - apps/prtimes/src/templates/**
            src/layouts:
              - apps/prtimes/src/layouts/**
- name: Build Storybook
        if: steps.filter.outputs.modified_keys != ''
        working-directory: ./apps/prtimes
        run: pnpm build-storybook --quiet

- name: Install Playwright
  if: steps.filter.outputs.modified_keys != ''
  run: pnpm exec  playwright install --with-deps chromium
  
 - name: List all changes
   if: steps.filter.outputs.modified_keys != ''
   id: changed_dirs
   run: |
      CHANGED_DIRS=$(echo "${{ steps.filter.outputs.modified_keys }}")
      echo "changed_dirs=$CHANGED_DIRS" >> $GITHUB_OUTPUT
      
- name: Test Storybook
  if: steps.filter.outputs.modified_keys != ''
  env:
		CHANGED_DIRS: ${{ steps.changed_dirs.outputs.changed_dirs }}
	run: |
     pnpm concurrently -k -s first -n "SB,TEST" -c "magenta,blue" \
     "pnpm http-server storybook-static --port 6006 --silent" \
     "pnpm wait-on tcp:6006 && pnpm test-storybook $CHANGED_DIRS"

この設定により、変更のある機能に対してのみStorybookのテストが実行されるため、CIでのテストにかかる時間が3~4分に削減されます。

必要な場合にのみPR TIMES EditorをIntegration testを実行するようにする

新しいUIと機能を含む新PR TIMES Editorがリリースされて以来、Integration testのカバレッジが大幅に増加しました。その結果、各テストの実行には現在14〜15分かかり、CIパイプラインの最大のボトルネックとなっています。

このタスクは私が担当したわけではありませんが、エディタに関連する変更がある場合にのみテストを実行することがわかります。これも tj-actions/changed-filesを使用して実現されています。

 - name: Assess need for all tests
        id: filter-editor
        uses: tj-actions/changed-files@v44
        with:
          files: |
            pnpm-lock.yaml
            common/press-release-ui/**
            common/prtimes-company-admin-components/**
            packages/openapi/**
            packages/prtimes-basis/**
            apps/prtimes/src/features/press-release-editor/**           
            apps/prtimes/src/features/press-release-editor-v3/**
            apps/prtimes/src/features/press-release-list/**
            apps/prtimes/src/components/unfixed-new-ui/**
            tests/prtimes/**
editor-integration-test:
    timeout-minutes: 30
    runs-on: ubuntu-22.04
    needs: [install-deps]
    if: steps.filter-editor.outputs.any_modified != 'true'
    steps:
      - name: Get installed Playwright version
        working-directory: tests/prtimes
        id: playwright-version
        run: echo "PLAYWRIGHT_VERSION=$(node -e "console.log(require('./package.json').devDependencies['@playwright/test'])")" >> $GITHUB_OUTPUT

      - name: Cache playwright binaries
        uses: actions/cache@v4
        id: playwright-config-cache
        with:
          path: ~/.cache/ms-playwright
          key: playwright-config-cache-${{ steps.playwright-version.outputs.PLAYWRIGHT_VERSION }}

      - name: Install Playwright
        if: steps.playwright-config-cache.outputs.cache-hit != 'true'
        working-directory: tests/prtimes
        run: pnpm dlx playwright@${{ steps.playwright-version.outputs.PLAYWRIGHT_VERSION }} install --with-deps chromium

      - name: Run Playwright
        run: pnpm test:ci:editor
        working-directory: tests/prtimes

これにより、エディタのIntegretion Testが必要な場合にのみ実行されることが保証され、CI時間とBillable Timeを大幅に削減することができます。

結果

これらの変更を実装した後、CI時間とBillable timeの両方で大幅な削減を確認しました。

エディタの統合テストが必要ない場合、CI時間は16分から8分に、Billable timeは40分から17分に減少しました。

Before

After

まとめ

XOのcache実装にはいくつかの課題があって作業保留していますが、それでもCIの時間とBillable timeを大幅に削減することができました。CIパイプラインを改善し、必要な場合にのみStorybookとエディタのIntegration Testを実行することで、CI時間とBillable timeを半減させることに成功しました。この作業を通じて、GitHub Actionsについての理解を深めることができました。

この記事をお読みいただき、ありがとうございました。少しでも皆さんの参考になれば幸いです。

  • URLをコピーしました!

この記事を書いた人

PR TIMES 開発本部インターン生

目次