🚀
docker-compose + GithubActionsでCI・CD環境を構築する
概要
こちらで作成したE2Eテストをdocker-compose up
で実行する仕組みを作りました
やり方
e2eテストを実行するDockerfileを作成します
Dockerfile.test
# FROM ベースイメージを指定する
# as build-stage ビルド用のイメージと実行用のイメージを分ける
# -alpine 軽量イメージ
FROM node:14.16.1-alpine as build-stage
# 作業ディレクトリを作成
WORKDIR /work
COPY . /work/
RUN npm install
# コマンドを実行する
CMD ["npm","run","test:e2e"]
開発環境を構築するDockerfileを作成します
Dockerfile.migrate
FROM node:14.16.1-alpine
WORKDIR /work
COPY ./src/databases /work/src/databases
COPY ./package.json ./package-lock.json ./ormconfig.ts ./tsconfig.json /work/
RUN npm install
CMD ["npm", "run", "typeorm", "migration:run"]
E2Eテスト用のymlファイルを作成する
unit-test.yml
# docker-composeで使用するバージョン
version: '3'
# アプリケーションを動かすための各要素
services:
# コンテナ名
app:
# ComposeFileを実行し、ビルドされるときのpath
build:
# docker buildコマンドを実行した場所
context: "."
# Dockerfileのある場所
dockerfile: "Dockerfile.test"
# image ID
image: hoge-test
# コンテナ名
container_name: hoge-test
# ポート番号
ports:
- '3000:3000'
# 環境変数
environment:
PORT: xxx
TZ: 'Asia/Tokyo'
DB_HOST: 'xx'
DB_PORT: 'xxxx'
DB_USERNAME: 'xxxx'
DB_PASSWORD: 'xxxx'
DB_NAME: 'hoge'
REDIS_HOST: 'xx'
REDIS_PORT: 'xx'
# サービス間の依存関係
depends_on:
- db
- redis
redis:
image: redis:5.0
container_name: redis_container-test
ports:
- "xxxx:xxxx"
db:
image: mysql:8.0
command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
container_name: db_container_test
ports:
- xxxx:xxxx
environment:
TZ: 'Asia/Tokyo'
MYSQL_ROOT_PASSWORD: xxxx
MYSQL_DATABASE: xxxx
MYSQL_USER: xxxx
MYSQL_PASSWORD: xxxx
TypeOrm用の設定ファイルを作成
typeormが持つsynchronizeの機能を使えば、ヒトがテーブルを作成せずともスキーマさえあればテーブル定義を自動生成してくれる。
同期-アプリケーションの起動ごとにデータベーススキーマを自動作成する必要があるかどうかを示します。このオプションには注意してください。本番環境では使用しないでください。本番環境のデータが失われる可能性があります。このオプションは、デバッグおよび開発中に役立ちます。その代わりに、CLIを使用してschema:syncコマンドを実行できます。
ormconfig.test.ts
module.exports = {
type: 'mysql',
host: process.env.DB_HOST || 'localhost',
port: process.env.DB_PORT || 'xxxx',
username: process.env.DB_USERNAME || 'xxxx',
password: process.env.DB_PASSWORD || 'xxxx',
database: process.env.DB_NAME || 'xxxx',
// アプリケーション実行時にEntityをデータベースに同期する
synchronize: true,
// 実行されるSQLをログとして吐く
logging: true,
entities: ['src/domain/entities/*.ts'],
migrations: ['src/databases/migrations/*.ts'],
seeds: ['src/test/databases/seeders/*.seed.{js,ts}'],
subscribers: ['src/subscribers/**/*.ts'],
cli: {
migrationsDir: 'src/databases/migrations',
entitiesDir: 'src/domain/entities',
seedersDir: 'src/databases/seeders',
subscribersDir: 'src/subscribers',
},
}
テストを実行する
bash
# E2Eテストコンテナ立ち上げ
docker-compose -f unit-test.yml build
# E2Eテストコンテナ起動 テスト終わったらコンテナ落とす
docker-compose -f unit-test.yml up --abort-on-container-exit
Recreating redis_container ... done
Recreating db_container ... done
Recreating xxx-api-test ... done
Attaching to redis_container-test, db_container_test, xxx-api-test
xxx-api-test |
xxx-api-test | > sample@0.0.1 test:e2e /work
xxx-api-test | > jest --config ./src/test/e2e/jest-e2e.json
xxx-api-test |
xxx-api-test | PASS src/test/e2e/contractor-reps.e2e-spec.ts (92.288 s)
xxx-api-test 契約担当者(E2E)
xxx-api-test ログインしていない場合は401が返ります
xxx-api-test ✓ OK /contractor-reps (GET) (1471 ms)
xxx-api-test 契約担当者一覧テスト_サービス・システム管理
xxx-api-test ✓ OK /contractor-reps (GET) (1195 ms)
// 省略
xxx-api-test Test Suites: 1 passed, 1 total
xxx-api-test Tests: 38 passed, 38 total
xxx-api-test Snapshots: 0 total
xxx-api-test Time: 92.428 s
xxx-api-test Ran all test suites.
xxxx-api-test exited with code 0
GitHubActionsを設定する
# ワークフローをトリガーするGitHubイベントの名前
on:
# PR作成をトリガーする
pull_request:
# PR作成・プッシュ時に実行
types: [opened, synchronize]
# ジョブ定義
jobs:
run-test:
name: Run Test
# ubuntu環境で動作
runs-on: ubuntu-latest
# アクションを定義
steps:
- name: checkout pushed commit
# ソースコードのチェックアウト
uses: actions/checkout@v2
with:
# PRのHEADブランチを使う
ref: ${{ github.event.pull_request.head.sha }}
# E2E テストを Docker Compose で実行する
- name: run test on docker-compose
run: |
docker-compose -f ./unit-test.yml build
docker-compose -f ./unit-test.yml up --abort-on-container-exit
working-directory: ./
最後に
読んでいただきありがとうございます。
今回の記事はいかがでしたか?
・こういう記事が読みたい
・こういうところが良かった
・こうした方が良いのではないか
などなど、率直なご意見を募集しております。
Discussion