[Go] Dagger でテストを呼び出す

2025-07-05
Dagger は CI/CD をポータブルにするツール。
スクリプトを Docker コンテナに閉じ込めることで、どこでも実行できるようになります。

気になったのでサンプルアプリを作ってみました。
flow.png
公式サイト
インストール
Mac では Homebrew でインストールできます。
</>
$ brew install dagger/tap/dagger

$ dagger version
dagger v0.18.12 (docker-image://registry.dagger.io/engine:v0.18.12) darwin/arm64
サンプルアプリ
Go でサンプルアプリを作りました。

ディレクトリ構造は次の通りです。
</>
$ tree -a -L 2
.
├── .dagger
│   ├── dagger.gen.go
│   ├── go.mod
│   ├── internal
│   └── main.go          // Dagger のスクリプト
├── .gitignore
├── dagger.json          // Dagger の設定ファイル
├── db
├── docker-compose.yml
├── Dockerfile           // Dockerfile
├── go.mod
└── main.go
.dagger/main.go に Dagger のスクリプトを書きます。
コード
</>
1
メモ
アプリのコンテナです

Dagger ではベースイメージを指定してゼロから組み立てるケースが多いですが、私は Dockerfile ベースにしました
MySQL のコンテナです。テストで使います
リント
`dagger call lint` で呼び出せます
テスト
`dagger call test` で呼び出せます
テストする前に、マグレーションをします
アプリケーションを立ち上げます
</>
docker compose up
マイグレーションします
</>
docker compose exec app go tool goose mysql 'root:pass@tcp(mysql:3306)/app' -dir migrations up
テストする
`dagger call test` を実行します
</>
$ dagger call test

✔ connect 36.8s
✔ load module: . 6.7s
✔ parsing command line arguments 0.0s

✔ app: App! 0.0s
✔ .test: String! 1m35s

=== RUN   TestGetTasksHandler
--- PASS: TestGetTasksHandler (0.00s)
PASS
ok  	github.com/enuesaa/lab/data/dagger-go-echo	0.004s
?   	github.com/enuesaa/lab/data/dagger-go-echo/db	[no test files]
test.gif
リントする
`dagger call lint` を実行します
</>
$ dagger call lint

✔ connect 0.6s
✔ load module: . 1.3s
✔ parsing command line arguments 0.0s

✔ app: App! 0.0s
✔ .lint: String! 22.7s
GitHub Actions
Actions で dagger call するには `dagger/dagger-for-github` を使います。
</>
name: ci

on:
  push:
    branches:
      - '**'
  workflow_dispatch:

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: dagger/dagger-for-github@8.0.0
        with:
          call: lint

      - uses: dagger/dagger-for-github@8.0.0
        with:
          call: test
感想
往々にして、テスト環境を構築するためのコマンドは長くなりがちであり、それらが CI に散らばることを課題に感じてました。
その意味で、Dagger を使えば DRY にできます。

一方で、何をどこまで Dagger に寄せるか考える必要がありそうです。
例えば `go fmt ./...` は、ふつうに直接呼び出したほうが楽でした。