【Go】Daggerを使ってCI/CD書いてみた

本投稿は TECOTEC Advent Calendar 2022 の16日目の記事です。
こんにちは、次世代デジタル基盤開発事業部の椎葉です。
今回はCI/CDをコードで書けるツールを見つけたので、軽く触ってみようと思います。

Daggerとは

CI/CDのパイプラインをポータブルに構築できるツールです。
ポータブルとはGitHub ActionsやCircleCI等の特定の環境に依存せずに構築できるということです。
ローカル環境でも確認ができるので、設定の確認のためにプッシュ→失敗→修正→コミットしてプッシュ→失敗→また修正して・・・といった時間のかかる作業をスキップできます。
最初の設定時は何かと失敗することも多いので、手元で確認できるのは便利ですね。

また、CI/CDパイプラインをコードとして、アプリケーションと同じプログラミング言語で開発できるのも特徴の一つです。
今回は業務でも使っているGoを使って実装してみたいと思います。

Dagger ハンズオン

公式サイトにハンズオンがあったので、これに沿って動かしてみます。 docs.dagger.io

まずはGoのプロジェクトを作成します。

mkdir multibuild
cd multibuild
go mod init multibuild

途中まで進めていくと以下のようなビルドを実行するコードが出来上がります。

package main

import (
    "context"
    "fmt"
    "os"

    "dagger.io/dagger"
)

func main() {
    if err := build(context.Background()); err != nil {
        fmt.Println(err)
    }
}

func build(ctx context.Context) error {
    fmt.Println("Building with Dagger")

    // Daggerクライアントの作成
    client, err := dagger.Connect(ctx, dagger.WithLogOutput(os.Stdout))
    if err != nil {
        return err
    }
    defer client.Close()

    // ホストのカレントディレクトリへの参照を取得
    src := client.Host().Directory(".")

    // Goの最新Verのコンテナイメージを取得
    golang := client.Container().From("golang:latest")

    // コンテナ内のsrcディレクトリへマウント
    // srcディレクトリをワークディレクトリに設定
    golang = golang.WithMountedDirectory("/src", src).WithWorkdir("/src")

    // ビルドコマンドを実行
    path := "build/"
    golang = golang.WithExec([]string{"go", "build", "-o", path})

    // コンテナ内のbuildディレクトリへの参照を取得
    output := golang.Directory(path)

    // コンテナからホストへbuildディレクトリの内容を書き込む
    _, err = output.Export(ctx, path)
    if err != nil {
        return err
    }

    return nil
}

そして、daggerをインストールして実行すると、ビルドファイルが出来上がります。

go get dagger.io/dagger@latest
go mod tidy
go run main.go

これでビルドを行うパイプラインが完成しました!

最後までハンズオンを行うと、複数OS、複数アーキテクチャの組み合わせでマルチビルドを行うコードが完成します。
興味のある方はぜひ試してみてください。

GitHub Actions でdaggerを実行してみる

次はハンズオンで作成したコードをGitHub Actions で実行してみたいと思います。

GitHub Actions の設定を追加します。

name: build

on:
  push:
    branches:
      - master

jobs:
  build:
    # 実行環境の構築
    runs-on: ubuntu-latest

    name: build
    steps:
      # レポジトリからソースコードを取得する
      - name: Checkout
        uses: actions/checkout@v3

      # Goの実行環境を準備する
      - name: Set up Go
        uses: actions/setup-go@v3
        with:
          go-version: 1.19

      # 実行
      - run: go run ./main.go

ソースコードを読み込んで、Goの実行環境準備して、実行するだけ。
簡単ですね。
実行部分はGitHub Actionsの書き方に依存しないので記述がスッキリします。

まとめ

DaggerのGo SDKを使ってCI/CDの処理を書いてみました。 今回はビルドを実行するだけでしたが、もっといろいろできるようにカスタマイズできると便利そうだなと感じました。

最後まで読んでいただき、ありがとうございました。

www.tecotec.co.jp