🚀

docker-compose + GithubActionsでCI・CD環境を構築する

2021/11/28に公開約4,700字

概要

こちらで作成したE2Eテストをdocker-compose upで実行する仕組みを作りました

https://zenn.dev/naonao70/articles/5167d8c18c81e2

やり方

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

ログインするとコメントできます