💡

CI/CDのDaggerで、GithubActionsとCircleCIにシュッと連携してみた

2022/08/24に公開

前々から気になっていた、CI/CD の非ベンダーロックインな Dagger というツールを試してみました。本記事では、試した内容について共有しようと思います。

CI/CD のパイプラインを書く

Dagger では、CUE という言語を使って CI/CD のパイプラインを書きます。
公式サイトのチュートリアルから、そのまま使ってみます。
コードは、次のようなものになります。

package todoapp

import (
	"dagger.io/dagger"

	"dagger.io/dagger/core"
	"universe.dagger.io/netlify"
	"universe.dagger.io/yarn"
)

dagger.#Plan & {
	actions: {
		source: core.#Source & {
			path: "."
			exclude: [
				"node_modules",
				"build",
				"*.cue",
				"*.md",
				".git",
			]
		}

		build: yarn.#Script & {
			name:   "build"
			source: actions.source.output
		}

		test: yarn.#Script & {
			name:   "test"
			source: actions.source.output
			container: env: CI: "true"
		}

		deploy: netlify.#Deploy & {
			contents: actions.build.output
			site:     string | *"dagger-todoapp"
		}
	}
}

見慣れない構文かもしれませんが、何をやっているかはなんとなく分かるんじゃないかなと思います。
actions は、実行するものを定義していて、dagger do <action名> のようにして使います。
上の定義にあるsource: core.#Source は、 source がアクション名で、core が実行するパッケージになります。
パッケージは、次の 2 つに分類されます。

ローカル環境で Dagger を動かす

実際にローカルで動かしてみます。

$ dagger do test
[] actions.test.container                                                                                                                11.6s
[] actions.test.install.container.script                                                                                                  0.1s
[] actions.source                                                                                                                         0.5s
[] actions.test.install.container                                                                                                         2.3s
[] actions.test.container.script                                                                                                          0.1s
[] actions.test.install.container.export                                                                                                  0.0s
[] actions.test.container.export                                                                                                          0.2s
Field  Value
logs   """\n  yarn run v1.22.17\n  $ react-scripts test\n  Done in 6.78s.\n\n  """

特に問題なく、PASS しています。--log-format plain をつけると、実行の詳細な情報が出力されます。

$ dagger do test --log-format plain
8:06PM INFO  actions.test.install.container.script._write | computing
8:06PM INFO  actions.test.container._image._dag."0"._pull | computing
8:06PM INFO  actions.test.install.container._image._dag."0"._pull | computing
8:06PM INFO  actions.test.container.script._write | computing
8:06PM INFO  actions.source | computing
...

ちなみに、actions.source が実行されているのは、actions.testactions.sourceに依存しているためと思います。

$ NETLIFY_TOKEN=**** USER=**** dagger do deploy
[] actions.deploy.container.script                                                                                                        0.2s
[] actions.build.install.container                                                                                                        3.8s
[] client.env                                                                                                                             0.0s
[] actions.source                                                                                                                         0.4s
[] actions.build.install.container.script                                                                                                 0.2s
[] actions.build.container                                                                                                               21.0s
[] actions.build.container.script                                                                                                         0.2s
[] actions.deploy                                                                                                                         4.8s
[] actions.build.install.container.export                                                                                                 0.1s
[] actions.build.container.export                                                                                                         0.1s
[] actions.deploy.container                                                                                                              91.0s
[] client.filesystem."./build".write                                                                                                      0.3s
[] actions.deploy.container.export                                                                                                        0.0s
Field      Value
site       "****-dagger-todoapp"
url        "https://******-dagger-todoapp.netlify.app"
deployUrl  "https://xxxx--******-dagger-todoapp.netlify.app"
logsUrl    "https://app.netlify.com/sites/******-dagger-todoapp/deploys/xxxx"

ローカル環境で、CI/CD のパイプラインコードを動かくことができました。
次は、CI と連携したいと思います。

CircleCI で Dagger を動かす

まずは、CircleCI で Dagger を動かしてみます。
CircleCI の yml ファイルは、次の定義になります。

# .circleci/config.yml
version: 2.1

jobs:
  install-and-run-dagger:
    docker:
      - image: cimg/base:stable
    steps:
      - checkout
      - setup_remote_docker:
          version: "20.10.14"
      - run:
          name: "Install Dagger"
          command: |
            cd /usr/local
            wget -O - https://dl.dagger.io/dagger/install.sh | sudo sh
            cd -
      - run:
          name: "Update project"
          command: |
            dagger project init
            dagger project update
      - run:
          name: "Testing"
          command: |
            dagger do test --log-format plain
      - run:
          name: "Deploy to Netlify"
          command: |
            dagger do deploy --log-format plain

workflows:
  dagger-workflow:
    jobs:
      - install-and-run-dagger

CircleCI の環境変数に、NETLIFY_TOKENUSERを設定しておきます。
この定義ファイルは、Dagger をインストールして、先程ローカル環境で動かしていた dagger do testdagger do deploy を実行しているだけです。

この定義は、CircleCI 上で PASS します。めちゃくちゃ簡単ですね。

GithubActions で Dagger を動かす

次は、GithubActions で Dagger を動かしてみます。
GithubActions の yml ファイルは、次の定義になります。

# .github/workflows/todoapp.yml
name: todoapp

on:
  push:
    branches:
      - main

jobs:
  dagger:
    runs-on: ubuntu-latest
    steps:
      - name: Clone repository
        uses: actions/checkout@v2
      - name: Update project
        uses: dagger/dagger-for-github@v3
        with:
          version: 0.2
          cmds: |
            project init
            project update
      - name: Testing
        uses: dagger/dagger-for-github@v3
        with:
          version: 0.2
          cmds: |
            do test
      - name: Deploy to Netlify
        uses: dagger/dagger-for-github@v3
        with:
          version: 0.2
          cmds: |
            do deploy
        env:
          USER: ${{ secrets.USER }}
          NETLIFY_TOKEN: ${{ secrets.NETLIFY_TOKEN }}

ここの定義も、CircleCI の定義とほとんど一緒だと思います。
ただ、少し違うのは、GithubActions では、uses: dagger/dagger-for-github@v3 が使えるため、
cmdsが、do testdo deploy のように、daggerを書かなくて済むようになります。

GithubActions の環境変数に、NETLIFY_TOKENUSERを設定しておきます。
そうすれば、このパイプラインも成功します。

終わりに

ローカル環境で、CI/CD のパイプラインをテストできて、それをシュッと CI サービスに連携できました。
今回は、チュートリアルのものをそのまま使っているので、テストやデプロイがシンプルな構成になっていましたが、
実務になると、より複雑な構成になると思うので、手元で確認できるのは良いものと思いました。
ただし、CUEへの学習コストがかかるため、導入する際は、そのあたりも含めて検討しましょう。

Discussion