すっかり忘れてしまったHKT48のメンバーを思い出すために個人開発で簡単なクイズアプリを作成したとき golang-migate と GitHub Actionsを使うことがあったのでメモに残す。
以下が対象のリポジトリ github.com
golang-migrateについて
とりあえずローカルでgolang-migrate CLIを使用してmigrationを実行してみる。
基本的な使い方はいかに書かれているが念の為にメモに残しておく。
MySQLコンテナを立ち上げる。
docker run --rm --name gin-service-db -e MYSQL_USER=ginuser \ -e MYSQL_PASSWORD=password -e MYSQL_ROOT_PASSWORD=password \ -e MYSQL_DATABASE=gin-service \ -p 3307:3306 \ --network gin-service-network\ --hostname gin_service_db\ -d mysql:8.0
migrateを実行する
-database
で先ほど立ち上げたMySQLコンテナを指定して -path
で作成したマイグレーションファイルが入ったディレクトリを指定している。
migrate -database="mysql://ginuser:password@tcp(localhost:3307)/gin-service"\ -path "./db/migrations"\ --verbose up 2022/04/07 23:49:39 Start buffering 1/u init_db 2022/04/07 23:49:39 Start buffering 2/u init_data_form_csv 2022/04/07 23:49:39 Start buffering 3/u add_member_info_from_csv 2022/04/07 23:49:39 Read and execute 1/u init_db 2022/04/07 23:49:39 Finished 1/u init_db (read 129.465776ms, ran 254.94272ms) 2022/04/07 23:49:39 Read and execute 2/u init_data_form_csv 2022/04/07 23:49:39 Finished 2/u init_data_form_csv (read 487.425323ms, ran 171.378875ms) 2022/04/07 23:49:39 Read and execute 3/u add_member_info_from_csv 2022/04/07 23:49:40 Finished 3/u add_member_info_from_csv (read 771.780878ms, ran 198.832452ms) 2022/04/07 23:49:40 Finished after 999.447239ms 2022/04/07 23:49:40 Closing source and database
TablePlusで確認してみるときちんとテーブルが作成されているのが確認できる。
migrateを元に戻してみてみるときちんとテーブルが削除されていることが確認できる。
migrate -database="mysql://ginuser:password@tcp(localhost:3307)/gin-service"\ -path "./db/migrations"\ --verbose down 2022/04/07 23:48:40 Are you sure you want to apply all down migrations? [y/N] y 2022/04/07 23:48:44 Applying all down migrations 2022/04/07 23:48:44 Start buffering 3/d add_member_info_from_csv 2022/04/07 23:48:44 Start buffering 2/d init_data_form_csv 2022/04/07 23:48:44 Start buffering 1/d init_db 2022/04/07 23:48:45 Read and execute 3/d add_member_info_from_csv 2022/04/07 23:48:45 Finished 3/d add_member_info_from_csv (read 346.478997ms, ran 242.207909ms) 2022/04/07 23:48:45 Read and execute 2/d init_data_form_csv 2022/04/07 23:48:45 Finished 2/d init_data_form_csv (read 690.487922ms, ran 132.063138ms) 2022/04/07 23:48:45 Read and execute 1/d init_db 2022/04/07 23:48:45 Finished 1/d init_db (read 976.37633ms, ran 190.032461ms) 2022/04/07 23:48:45 Finished after 5.236469304s 2022/04/07 23:48:45 Closing source and database
GitHub Actionsについて
GitHub Actionsで実行してみる。
定義ファイルは以下のようになっている。
name: Gin API on: push: branches: - main jobs: build: name: test runs-on: ubuntu-latest services: gin_service_db: image: mysql:8.0 ports: - 3306:3306 env: MYSQL_USER: ginuser MYSQL_PASSWORD: password MYSQL_DATABASE: gin-service MYSQL_ROOT_PASSWORD: password MYSQL_HOST: gin_service_db steps: - uses: actions/checkout@v2 - name: Set up Go uses: actions/setup-go@v2 with: go-version: 1.17.7 - name: Install golang-migrate CLI run: | curl -L https://packagecloud.io/golang-migrate/migrate/gpgkey | sudo apt-key add - echo "deb https://packagecloud.io/golang-migrate/migrate/ubuntu/ $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/migrate.list sudo apt-get update sudo apt-get install -y migrate - name: Run Migration run: migrate -database="mysql://ginuser:password@tcp(localhost:3306)/gin-service" -path "./db/migrations" --verbose up - name: Build run: go build -v ./... - name: Test run: TEST_CLIENT=CI bash -c 'go test ./... -v'
以下のstepでgolang-migrate CLIをインストールしている。 インストール方法をこちらを参照した。
- name: Install golang-migrate CLI run: | curl -L https://packagecloud.io/golang-migrate/migrate/gpgkey | sudo apt-key add - echo "deb https://packagecloud.io/golang-migrate/migrate/ubuntu/ $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/migrate.list sudo apt-get update sudo apt-get install -y migrate
以下のstepでmigrateを実行している。
- name: Run Migration run: migrate -database="mysql://ginuser:password@tcp(localhost:3306)/gin-service" -path "./db/migrations" --verbose up
Actionタブからmigrateされていることを確認できた。
以下のstepでテストを実行している。
- name: Test run: TEST_CLIENT=CI bash -c 'go test ./... -v'
GitHub Actionsでハマったこと
MySQLサービスコンテナのホスト名の指定の方法が分からない
開発環境で使用しているMySQLコンテナのホスト名を gin_service_db
と命名してDSNを ginuser:password@tcp(gin_service_db:3306)/gin-service?parseTime=true
として使用しているのでGitHub Actions上でもMySQLサービスコンテナに gin_service_db
というホスト名を付けたかったが分からなかったので、以下のように TEST_CLIENT
という環境変数があるかどうかとその値が CI
となった時にCI用のDSN (ginuser:password@tcp(127.0.0.1:3306)/gin-service?parseTime=true
) を返す関数を作成した。
func configTestCliant() string { if value, ok := os.LookupEnv("TEST_CLIENT"); ok && value == "CI" { return "ginuser:password@tcp(127.0.0.1:3306)/gin-service?parseTime=true" } return "ginuser:password@tcp(gin_service_db:3306)/gin-service?parseTime=true" } func ConnectDB() *sql.DB { var dnsNmae string = configTestCliant() db, err := sql.Open("mysql", dnsNmae) if err != nil { panic(err.Error()) } return db }