GitHub ActionsでMySQLのコンテナを起動し、テスト実行でDB接続も確認する

2023年6月2日

以下を参考にさせていただきました。

https://zenn.dev/snowcait/articles/0cc4a464610e61

経緯

今回はAzure Functions用のスターターテンプレートの作成過程について説明します。
このテンプレート作成においては、Azure Functionsに関連する内容が主に含まれています。

テストの実行にはjestを使用しており、今回はdockerでホストされているmysqlを使用して、DBへの問合せを含むテストを行います。

以前はmockデータを使用してテストを行っていました。しかし、DBの定義変更が生じた際にテストで検知できない問題に直面しました。そのため、簡易的なテストでもバグを防ぐことができるかもと感じたことから、一部のDBテストを導入することに決めました。

元々のプロジェクトでは、同じプロジェクトディレクトリにDB用のdocker設定ファイルを置いていました。これは日常的に使用しており、テストでも同じ設定ファイルを使用する予定です。

プロジェクトの構成

以下のような構成となっています。

.
├── README.md
├── SampleTableAccess
├── SampleTrigger
├── coverage
├── db-service
├── docker
├── docs
├── entity
├── host.json
├── jest.config.ts
├── node_modules
├── package-lock.json
├── package.json
├── tests
└── tsconfig.json

今回は、dockerディレクトリ以下にあるdocker-compose.ymlをGithub Actionsで動かしたいという内容になります。

.
├── README.md
├── docker-compose.yml
├── init
│   ├── init.sh
│   ├── init.sql
│   └── sql
│       └── sample.sql
└── my.cnf

Github Actionsのworkflowsを設定する

publish-profile: ${{ secrets.xxx }}
ここはAzureのデプロイセンターからGithub Actionsの設定をした時に自動的に払い出されるシークレットを使用します。

シークレットはGithubの設定画面から確認できます。

そもそもAzureのデプロイセンターの設定をどうするかについてはこちらを参考にしてください。

自動的に作成されたworkflowsを修正して以下のようにしました。

# Docs for the Azure Web Apps Deploy action: https://github.com/azure/functions-action
# More GitHub Actions for Azure: https://github.com/Azure/actions

name: Build and deploy Node.js project to Azure Function App - func-starter-sample

on:
  push:
    branches:
      - "*"
  workflow_dispatch:

env:
  AZURE_FUNCTIONAPP_PACKAGE_PATH: '.' # set this to the path to your web app project, defaults to the repository root
  NODE_VERSION: '18.x' # set this to the node version to use (supports 8.x, 10.x, 12.x)

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - name: 'Checkout GitHub Action'
        uses: actions/checkout@v2

      - name: Setup Node ${{ env.NODE_VERSION }} Environment
        uses: actions/setup-node@v1
        with:
          node-version: ${{ env.NODE_VERSION }}

      - name: 'Resolve Project Dependencies Using Npm'
        shell: bash
        run: |
            pushd './${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}'
            npm install
            npm run build --if-present
            popd
  
      - name: 'Run Docker Compose'
        run: |
            docker compose -f ./docker/docker-compose.yml up -d --wait

      - name: 'Show Docker Compose log'
        run: |
            pushd './${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}'
            cd ./docker
            docker compose logs
            popd

      - name: 'Wait for DB to be ready'
        run: |
            host="localhost"
            dbUser="root"
            dbPass="root"
            until mysql --host=$host --user=$dbUser --password=$dbPass --protocol=TCP -e "SELECT 1"; do
              echo "Waiting for DB to start..."
              sleep 5
            done

      - name: 'Run tests'
        run: |
            pushd './${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}'
            npm run test --if-present
            popd

      # これは、Azure Functionsのリソースが作成されていることが前提
      # - name: 'Run Azure Functions Action'
      #   uses: Azure/functions-action@v1
      #   id: fa
      #   with:
      #     app-name: 'func-starter-sample'
      #     slot-name: 'Production'
      #     package: ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}
      #     # set the secret key to your Azure function.
      #     # you can get the secret key after setting cicd in your Azure function.
      #     # once you set the cicd, you can get the secret key in Github Setting pages.
      #     publish-profile: ${{ secrets.xxx }}

47行目からMySQLがちゃんと接続できるか確認しています。
一時的なテスト用DBなので、idとpassは直書きしています。
このステップがないとDB起動前にテストが実行されてしまい失敗します。

pushdとpopdについて

少し脱線しますが、pushdとpopdについて説明します。(メモしてます。)

pushdpopdは、ディレクトリのスタックを管理するためのコマンドです。以下にそれぞれのコマンドの説明を示します。

  • pushd: 現在のディレクトリをスタックに保存し、指定されたディレクトリに移動します。スタックに保存されたディレクトリは、後でpopdコマンドを使用して元の位置に戻ることができます。pushdは、ディレクトリの移動と同時に移動前のディレクトリをスタックにプッシュします。
  • popd: スタックに保存されたディレクトリをポップ(取り出し)して、そのディレクトリに移動します。スタックはLIFO(Last In, First Out)の動作をしますので、最後にプッシュされたディレクトリが最初にポップされます。popdは、スタックからディレクトリをポップして元の位置に戻します。

これらのコマンドは、一時的にディレクトリを移動して、後で元の位置に戻る必要がある場合に便利です。上記の例のコードでは、pushdpopdを使用して、npm installnpm run build、およびnpm run testコマンドを実行する前にディレクトリを変更しています。pushdを使用してディレクトリに移動し、必要なコマンドを実行した後にpopdを使用して元のディレクトリに戻ることで、作業ディレクトリを綺麗に管理しています。