好きな言語でCI/CDを実装できる!DaggerのNode.js SDKを試してみた!

「CI/CDのサービスは素晴らしいけど、ローカルPCで動作を確認したい」「Daggerっていうサービスは可能性を感じるけどCUE言語の学習コストがなぁ・・・」。そんな悩みを解決できるかもしれないDaggerのNode.js SDKを試してみました!
2022.12.26

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは。AWS事業本部コンサルティング部に所属している今泉(@bun76235104)です。

みなさんはどのCI/CDツール・サービスがお好きでしょうか?

GitHub ActionsCircleCIGitLab CICDAWS CodePipeineなど、さまざまな便利なツールがありますよね。

どれも素晴らしいサービスだと思うのですが、「CI/CDをローカル環境でテストしたい」「どのサービスでも使えるラッパーツールが欲しい」と思ったことはありませんか?

私は以前、それらの悩みを解決できるかもしれないdagger.ioというサービスを紹介しました。

以下イメージのようにDaggerでコンテナ技術を利用しており、ローカルPCでも各種CI/CDサービス上でも同様に動作させることができます。

20221226_dagger_nodejs_image

以前の執筆時点では、Daggerを使用するためにCUE言語の学習コストも必要だったのですが、Node.js・Python・Goなどの各種言語向けのSDKが提供されるようになっていました!

これにより慣れ親しんだプログラミング言語でDaggerを動かすだけでなく、言語ごとのエディタの機能の恩恵を受けることができます!(型情報の参照など)

ということで、この記事ではDaggerのNode.js SDKを利用してTypeScriptで簡単なCI・CD処理をやってみました!

以下の公式Get Startedのコードを少し変更しただけですので、興味のある方はご参照ください!

先に結論(こんな感じでローカル・GitHub Actions双方で動作しました)

以下はReactアプリケーションをビルドしているサンプルですが、ローカルPCでもGitHubActionsでも同様に処理が成功しています!

# ローカルPCでの実行
node --loader ts-node/esm ./build.ts

特にエラーなく終了し、以下のようにbuild配下に出力されています。

# ローカルPCでの実行結果
asset-manifest.json
favicon.ico
index.html
logo192.png
logo512.png
manifest.json
robots.txt
static

また、GitHub Actionsでも同様に成功しました!

20221226_dagger_node_sdk_github_actions_result2

TypeScriptで実装しているのですが、エディタ上で型情報の参照や定義ジャンプが効いていて非常に開発体験もよかったです!

20221226_dagger_nodejs_teigi_jump

何よりもローカルPC上で実際の動作を確認できるのが、すばらしかったです。

まずはハローワールドしてみる

公式のGet Started with the Dagger Node.js SDK | Daggerの手順に従って、以下のようにReactのアプリケーションを準備していきます。

私はReactはあまり詳しくないですが、このサンプルでは特に問題ありません。

npx create-react-app my-app --template typescript
cd my-app
npm install ts-node
npm pkg set type=module

次に、daggerのNode.js SDKをインストールします。

npm install @dagger.io/dagger --save-dev

次にmy-appディレクトリ直下にbuild.ts ファイルを作成します。

build.ts

import Client, { connect } from "@dagger.io/dagger"

// initialize Dagger client
connect(async (client: Client) => {
  // get Node image
  // get Node version
  const node = client.container().from("node:16").withExec(["node", "-v"])

  // execute
  const version = await node.stdout()

  // print output
  console.log("Hello from Dagger and Node " + version)
})

ローカルのPCで以下コマンドを実行してみます。

node --loader ts-node/esm ./build.ts

以下のように出力されました。

> my-app@0.1.0 ci
> ./node_modules/.bin/ts-node-esm build.ts

Hello from Dagger and Node v16.19.0

GitHub Actionsでも同様に動作させてみます。

.github/workflows/main.yml

name: 'ci'

on:
  push:
    branches:
    - main

jobs:
  dagger:
    runs-on: ubuntu-latest
    steps:
      -
        name: Checkout
        uses: actions/checkout@v3
      -
        name: Setup node
        uses: actions/setup-node@v3
        with:
          node-version: 16.19.0
          cache: npm
      -
        name: Install
        run: npm install
      -
        name: Run Dagger Node.js SDK CI
        run: npm run ci

20221226_dagger_nodejs_hello_on_github

Reactアプリケーションをビルドしてみる

次にReactアプリケーションをビルドしてみます。

build.tsを以下のように変更してみます。

build.ts

import Client, { connect } from "@dagger.io/dagger";

// initialize Dagger client
connect(async (client: Client) => {
  // get reference to the local project
  const source = client.host().directory(".", { exclude: ["node_modules/"] });

  // get Node image
  const node = client.container().from("node:16");

  // mount cloned repository into Node image
  const runner = client
    .container({ id: node })
    .withMountedDirectory("/src", source)
    .withWorkdir("/src")
    .withExec(["npm", "install"]);

  // run tests
  await runner.withExec(["npm", "test", "--", "--watchAll=false"]).exitCode();

  // build application
  // write the build output to the host
  const build = await runner.withExec(["npm", "run", "build"]);
  // 先に出力結果の表示
  // 結果確認のためlsコマンドを追加
  const lsResult = await build.withExec(["ls", "./build"]).stdout();
  console.log(lsResult);
  // buildした結果をホストに出力
  await build.directory("build/").export("./build");
});

TypeScriptを利用しているので、エディタ上でも型情報の補完が効いていて非常に良い感じです!

20221226_dagger_nodejs_hover_action_on_editor

20221226_dagger_node_sdk_type_suggest2

定義ジャンプもできるので、便利ですね。

ちょっとメソッドや引数の情報を調べるにはこれでも十分かもしれません。

20221226_dagger_nodejs_teigi_jump

ローカルPCで再度以下コマンドを実行してみます。

node --loader ts-node/esm ./build.ts

特にエラーなく終了し、以下のようにbuild配下に出力されています。

asset-manifest.json
favicon.ico
index.html
logo192.png
logo512.png
manifest.json
robots.txt
static

GitHub Actionsでも動作を確認したいので、コミットしてプッシュしてみます。

git add .
git commit -m 'feat: build.ts'

同じようにビルドが成功しました!

20221226_dagger_node_sdk_github_actions_result2

まとめ

  • 好きな言語でDaggerを利用できるようになった!
    • CUE言語一択ではなく、利用までのハードルが下がった!
  • エディタの拡張機能などの恩恵が受けられるので、非常に利用しやすくなった!

ぜひみなさんも、一度好きな言語でDaggerを試してみてください!