概要
Azureのパイプラインで同様のことができたので、VSCode Copilot Agent(Claude 3.7 Sonet
)を使ってGithub Action用に書き直してもらった。 ほとんど手直しせずに使えるものができた。
ソースコード
.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のローカルサーバを動かしたメモ