0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Github ActionsでDockerを使ってDB+HonoのAPIとReactのSPAを動かし、CucumberでE2Eテストを行いレポートをGithubPageに出力したメモ

Last updated at Posted at 2025-04-17

概要

Azureのパイプラインで同様のことができたので、VSCode Copilot Agent(Claude 3.7 Sonet)を使ってGithub Action用に書き直してもらった。 ほとんど手直しせずに使えるものができた。

この時点のソース

デプロイしたBDDレポート

ソースコード

.github/workflows/github-pages.yml
name: Deploy Documents to Pages

on:
  push:
    branches:
      - develop
      - docs
    paths:
      - .github/workflows/**
      - docs/**
      - tests/**
      - src/**/tests/**
      - stories/**
  workflow_dispatch:
    
permissions:
  contents: read
  pages: write
  id-token: write
  
concurrency:
  group: 'pages'
  cancel-in-progress: false
  
jobs:
  # E2Eテストを実行
  e2e-tests:
    uses: ./.github/workflows/reusable-e2e-test.yml
  
  # ドキュメントを生成
  build-docs:
    needs: e2e-tests
    uses: ./.github/workflows/reusable-build-docs.yml
    with:
      build_path: ./docs/astro
  
  # GitHub Pagesにデプロイ
  deploy-pages:
    needs: build-docs
    uses: ./.github/workflows/reusable-deploy-pages.yml

Claudeはreusable/e2e-test.ymlでいけると言っていたが、ChatGPTがサブディレクトリはだめだよ、といっていた。

再利用可能なワークフローの作成

再利用可能なワークフローは、リポジトリの .github/workflows ディレクトリ内にあります。 workflows ディレクトリのサブディレクトリはサポートされていません。

これはChatGPTのほうが正しかった模様。

.github/workflows/reusable-e2e-test.yml
name: Reusable E2E Test Workflow

on:
  workflow_call:
    outputs:
      test_status:
        description: "E2Eテストの結果ステータス"
        value: ${{ jobs.bdd-test.outputs.status }}

jobs:
  bdd-test:
    name: BDD E2E Tests
    runs-on: ubuntu-latest
    outputs:
      status: ${{ steps.set-status.outputs.status }}
    
    # PostgreSQLサービスの設定
    services:
      postgres:
        image: postgres:17.4-alpine
        env:
          POSTGRES_USER: postgres
          POSTGRES_PASSWORD: postgres
          POSTGRES_DB: main
        ports:
          - 5432:5432
        options: >-
          --health-cmd="pg_isready"
          --health-interval=10s
          --health-timeout=5s
          --health-retries=5
          
    steps:
      # Node.js v22をセットアップ
      - name: Setup Node.js v22
        uses: actions/setup-node@v4
        with:
          node-version: 22

      - name: Checkout
        uses: actions/checkout@v4
        
      # Firebaseエミュレータのセットアップ
      - name: Install docker-compose
        run: |
          DOCKER_COMPOSE_PATH=/tmp/docker-compose
          sudo mkdir -p $DOCKER_COMPOSE_PATH
          sudo curl -SL https://github.com/docker/compose/releases/download/v2.35.0/docker-compose-linux-x86_64 -o $DOCKER_COMPOSE_PATH/docker-compose
          sudo chmod 755 $DOCKER_COMPOSE_PATH/docker-compose
          # バージョン確認でインストールを検証
          $DOCKER_COMPOSE_PATH/docker-compose version
          echo "$DOCKER_COMPOSE_PATH" >> $GITHUB_PATH
        
      - name: Start Firebase Emulator
        run: |
          cd infra/local/firebase
          
          # ディレクトリの内容を確認(デバッグ用)
          ls -la
          
          # docker-composeファイルの存在を確認
          if [ ! -f "docker-compose.ci.yml" ]; then
            echo "::error::docker-compose.ci.yml が見つかりません"
            exit 1
          fi
          
          # docker-composeを使用してFirebaseエミュレータを起動
          docker-compose -f docker-compose.ci.yml up -d firebase
          
          # エミュレータの起動を確認するための待機ロジック
          echo "Waiting for Firebase Auth emulator..."
          MAX_RETRIES=20
          RETRY_COUNT=0
          RETRY_INTERVAL=2
          
          while [ $RETRY_COUNT -lt $MAX_RETRIES ]; do
            RETRY_COUNT=$((RETRY_COUNT + 1))
            echo "Attempt $RETRY_COUNT/$MAX_RETRIES"
            
            # Firebase Auth エミュレータの状態確認
            if curl -s http://localhost:9099/ > /dev/null; then
              echo "Firebase Auth emulator is ready"
              break
            fi
            
            # デバッグ情報の追加
            docker ps
            docker logs $(docker ps -q --filter "name=firebase") 2>/dev/null || echo "Firebase container logs not available"
            
            # 最大試行回数に達した場合はエラー
            if [ $RETRY_COUNT -eq $MAX_RETRIES ]; then
              echo "::error::Firebase Auth emulator failed to start within timeout period"
              exit 1
            fi
            
            sleep $RETRY_INTERVAL
          done
          
      # Bunのセットアップ
      - uses: oven-sh/setup-bun@v2
        with:
          bun-version: latest
          
      - name: Install Dependencies
        run: bun install
        
      # Playwrightのセットアップ
      - name: Install Playwright
        run: npx playwright install --with-deps chromium
        working-directory: apps/frontend
        
      # 環境変数の設定
      - name: Setup Backend Environment
        run: cp .dev.vars.ci .dev.vars
        working-directory: apps/backend
        
      - name: Setup Frontend Environment
        run: cp .env.ci .dev.local
        working-directory: apps/frontend
        
      # ホスト名の設定
      - name: Setup hosts file
        run: |
          echo "127.0.0.1 db.localtest.me" | sudo tee -a /etc/hosts
        
      # PostgreSQLの起動確認
      - name: Wait for PostgreSQL
        run: |
          echo "Waiting for PostgreSQL..."
          for i in {1..20}; do
            if PGPASSWORD=postgres psql -h db.localtest.me -U postgres -d main -c "SELECT 1" &>/dev/null; then
              echo "PostgreSQL is ready"
              break
            fi
            if [ $i -eq 20 ]; then
              echo "::error::PostgreSQL failed to start within timeout period"
              exit 1
            fi
            echo "Attempt $i/20 - PostgreSQL not ready yet, waiting..."
            sleep 2
          done
          # 接続情報を表示(デバッグ用)
          PGPASSWORD=postgres psql -h db.localtest.me -U postgres -d main -c "\conninfo"
        
      # Neon Proxyの起動
      - name: Start Neon Proxy
        run: |
          echo "Starting Neon Proxy..."
          # Docker内からホストのPostgreSQLに接続するための設定
          docker run -d --name neon-proxy \
            -e PG_CONNECTION_STRING=postgres://postgres:postgres@host.docker.internal:5432/main \
            -p 4444:4444 \
            --add-host=host.docker.internal:host-gateway \
            ghcr.io/timowilhelm/local-neon-http-proxy:main
          
          # プロキシが起動したことを確認
          sleep 5
          docker ps | grep neon-proxy || { echo "::error::Neon Proxy failed to start"; exit 1; }
          
          # ログを表示(デバッグ用)
          docker logs neon-proxy
        
      # バックエンドとフロントエンドの起動
      - name: Start Backend
        run: |
          bun run dev > backend.log 2>&1 &
          echo $! > ../backend.pid
        working-directory: apps/backend
        
      - name: Start Frontend
        run: |
          bun run preview:ci > frontend.log 2>&1 &
          echo $! > ../frontend.pid
        working-directory: apps/frontend
        
      # サーバー起動待機
      - name: Wait for servers
        run: |
          echo "Waiting for frontend server..."
          for i in {1..30}; do
            if curl -s http://localhost:5173 > /dev/null; then
              echo "Frontend server is up."
              break
            fi
            if [ $i -eq 30 ]; then
              echo "::error::Frontend server failed to start within timeout period"
              echo "Frontend server logs:"
              cat apps/frontend/frontend.log
              exit 1
            fi
            echo "Attempt $i/30 - Frontend server not ready yet, waiting..."
            sleep 2
          done

          echo "Waiting for backend server..."
          for i in {1..30}; do
            if curl -s http://localhost:8787 > /dev/null; then
              echo "Backend server is up."
              break
            fi
            if [ $i -eq 30 ]; then
              echo "::error::Backend server failed to start within timeout period"
              echo "Backend server logs:"
              cat apps/backend/backend.log
              exit 1
            fi
            echo "Attempt $i/30 - Backend server not ready yet, waiting..."
            sleep 2
          done
          
        
      # データベースマイグレーション
      - name: Run database migration
        run: bun run migrate:ci
        working-directory: packages/database
        
      # BDD E2Eテストの実行
      - name: Run BDD E2E Tests
        id: run_tests
        run: bun run bdd-test-debug
        working-directory: packages/bdd-e2e-test
        env:
          CI: true
        continue-on-error: true
        
        
      # リソースのクリーンアップ
      - name: Cleanup resources
        if: always()
        run: |
          kill $(cat apps/backend/backend.pid) || true
          kill $(cat apps/frontend/frontend.pid) || true
          docker stop neon-proxy || true
          docker rm neon-proxy || true
          

      # E2Eテスト出力を次のジョブで使用するためにキャッシュに保存
      - name: Cache E2E test output for documentation
        if: always()
        uses: actions/cache@v4
        with:
          path: packages/bdd-e2e-test/output
          key: e2e-output-${{ github.run_id }}

テスト結果をキャッシュ経由で、GithubPagesへデプロイするフォルダにコピーする。

.github/workflows/reusable-build-docs.yml
name: Reusable Document Build Workflow

on:
  workflow_call:
    inputs:
      build_path:
        description: 'ドキュメントビルドパス'
        required: true
        type: string

jobs:
  build:
    name: Build Documents
    runs-on: ubuntu-latest
    # dbdoc生成のためにPostgreSQLのコンテナを立ち上げる
    services:
      postgres:
        image: postgres:17
        env:
          POSTGRES_USER: postgres
          POSTGRES_PASSWORD: postgres
          POSTGRES_DB: main
        ports:
          - 5432:5432
          
    steps:
      # Node.js v22をセットアップ
      - name: Setup Node.js v22
        uses: actions/setup-node@v4
        with:
          node-version: 22

      - name: Checkout
        uses: actions/checkout@v4
        with:
          # 後述のcode-maatでgit logを取得するために必要
          fetch-depth: 0
          
      - uses: oven-sh/setup-bun@v2
        with:
          bun-version: latest
          
      - name: Setup Pages
        id: pages
        uses: actions/configure-pages@v5

      - name: Install document dependencies
        run: bun install
        working-directory: ${{ inputs.build_path }}

      # ドキュメント作成用の依存関係をインストール
      - name: Install monorepo dependencies
        run: bun install --ignore-scripts

      # マイグレーションを実行
      - name: Migration
        run: bun run migrate:ci
        working-directory: ./packages/database

      # dbdoc作成
      - name: Build dbdoc with Schemaspy
        run: docker compose up
        working-directory: ./docs/dbdoc

      # OpenAPI ドキュメント作成
      - name: Build with OpenAPI
        run: bun install && bun run build
        working-directory: ./docs/redocly

      # build storybook
      - name: Build Storybook
        run: bun install && bun run build-storybook
        working-directory: ./packages/ui

      # ドキュメント作成
      - name: Build with Astro
        run: |
          npm run astro build \
            --site "${{ steps.pages.outputs.origin }}" \
            --base "${{ steps.pages.outputs.base_path }}"
        working-directory: ${{ inputs.build_path }}

      # eslint ドキュメント作成
      - name: Build with eslint-inspect
        run: bun run build-inspect
        working-directory: ./packages/eslint-config-custom
      
      # hotspot ドキュメント作成
      - name: Set up JDK 21
        uses: actions/setup-java@v4.5.0
        with:
          distribution: 'temurin'
          java-version: '21'

      - name: Download Code Maat
        run: wget https://github.com/adamtornhill/code-maat/releases/download/v1.0.4/code-maat-1.0.4-standalone.jar
        working-directory: ./docs/code-maat

      - name: create git log 
        run: git log --all --numstat --date=short --pretty=format:'--%h--%ad--%aN' --no-renames --after=2024-01-01 > ./logfile.log
        working-directory: ./docs/code-maat

      - name: Run Code Maat
        run: java -jar code-maat-1.0.4-standalone.jar -l logfile.log -c git2 -a revisions > ./revisions.csv
        working-directory: ./docs/code-maat

      - name: Run Cloc
        run: docker run --rm -v .:/tmp aldanial/cloc --unix --by-file --csv --quiet --timeout 20 --vcs=git --exclude-dir=docs,.vscode,.github --not-match-f=\.json --report-file=./docs/code-maat/complexity.csv

      - uses: actions/setup-python@v5
        with:
          python-version: '3.13'
          
      - run: python csv_as_enclosure_json.py --structure complexity.csv --weights revisions.csv > ../astro/dist/crime-scene-hotspots/hotspots.json
        working-directory: ./docs/code-maat
        
      # E2Eテスト出力を前のジョブからキャッシュで取得
      - name: Restore E2E test output
        uses: actions/cache@v4
        with:
          path: packages/bdd-e2e-test/output
          key: e2e-output-${{ github.run_id }}

      # E2Eテスト結果をAstroのビルドディレクトリにコピーする
      - name: Copy E2E test results to Astro build directory
        if: always()
        run: |
          mkdir -p ${{ inputs.build_path }}/dist/odyssage-e2e-output
          if [ -d "packages/bdd-e2e-test/output" ]; then
            cp -r packages/bdd-e2e-test/output/* ${{ inputs.build_path }}/dist/odyssage-e2e-output/
            echo "E2Eテスト結果を ${{ inputs.build_path }}/dist/odyssage-e2e-output/ にコピーしました"
          else
            echo "E2Eテスト出力ディレクトリが見つかりません。ディレクトリを作成します。"
            mkdir -p ${{ inputs.build_path }}/dist/e2e-output
            echo "<html><head><title>E2E Test Results</title></head><body><h1>E2Eテスト結果</h1><p>テスト結果はありません</p></body></html>" > ${{ inputs.build_path }}/dist/e2e-output/index.html
          fi

      # astro ドキュメントアップロード
      - name: Upload artifact
        uses: actions/upload-pages-artifact@v3
        with:
          path: ${{ inputs.build_path }}/dist

.github/workflows/reusable-deploy-pages
name: Reusable Deploy to Pages Workflow

on:
  workflow_call:

jobs:
  deploy:
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    runs-on: ubuntu-latest
    name: Deploy
    steps:
      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v4

参考

AzureDevOpsのパイプライン上でFirebaseEmulatorをdocker-composeを使って起動したメモ
Azure DevOps の Pipeline で動かす cucumberからエラーログをとったメモ
Azure DevOps の Pipeline のDocker でPostgres+Neon Proxyのローカルサーバを動かしたメモ

GitHubPagesに開発ドキュメントをデプロイする総集編

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?