ksaitoの日記

日々試したことの覚え書き

concourseを使ったビルド

concourse.ioは、日本語情報とても少ないです。 とてもクールなCIツールです。

パイプライン、ジョブ、リソース、タスクといった考え方があり、CI/CDのパイプラインを構築できますが、実装しようと思うと意外と手が止まります。 パイプラインの起点は、S3やgitなどで、Jenkinsのようにとりあえず実行といったことができないからです。

とりあえず実行をするには、タスクを作るのがお勧めです。文書だけでは、うまく伝わらないと思いますが、日常の開発でも地味に便利です。

ユースケース

Javaの開発をしていたとします。対応する必要のあるJDKのバージョンはたくさんあるとします。

従来のビルド環境であれば、複数のバージョンをインストールして環境変数で切り替えるといったことが考えられますが、以外と面倒なことになります。

タスクの作成

concourseは、タスクはdockerコンテナで実行されます。 下記のようなタスクを準備してJDK1.6の環境を準備できます。

DockerHubのjavaオフシャルコンテナを使っています。tagの指定を変えれば、好みのバージョンを使うことができます。

$ cat sample.yml
---
platform: linux

image_resource:
  type: docker-image
  source: {repository: java, tag: 6}

run:
  path: sh
  args:
  - -exc
  - |
    java -version
$ fly -t test execute -c sample.yml
executing build 41 at http://172.17.0.1:8080/builds/41 
initializing
running sh -exc java -version

+ java -version
openjdk version "1.8.0_111"
OpenJDK Runtime Environment (build 1.8.0_111-8u111-b14-2~bpo8+1-b14)
OpenJDK 64-Bit Server VM (build 25.111-b14, mixed mode)
succeeded
$

パラメータを指定する

任意のパラメータを環境変数で渡すことができます。コンパイルオプションの指定に便利です。

$ cat sample.yml
---
platform: linux

image_resource:
  type: docker-image
  source: {repository: java, tag: 6}

params:
  JAVA_OPTS: -version

run:
  path: sh
  args:
  - -exc
  - |
    java $JAVA_OPTS
$ JAVA_OPTS=-fullversion fly -t test execute -c sample.yml
executing build 43 at http://172.17.0.1:8080/builds/43 
initializing
running sh -exc java $JAVA_OPTS

+ java -fullversion
java full version "1.6.0_38-b38"
succeeded
$

ファイルの受け渡し

下記のようなプログラムをコンパイルする場合、ソースコードを渡して、コンパイル結果を受け取る必要があります。

$ cat Hello.java 
public class Hello {
    public static void main(String[] args)
    {
        System.out.println("Hello, world.");
    }
}
$ 

タスクにファイルを渡すためのinputsとファイルを受け取るためのoutputsを定義します。

$ cat sample.yml
---
platform: linux

image_resource:
  type: docker-image
  source: {repository: java, tag: 6}

params:
  JAVA_OPTS: -version
inputs:
  - name: src
outputs:
  - name: obj

run:
  path: sh
  args:
  - -exc
  - |
    java $JAVA_OPTS
    javac src/Hello.java
    java -cp src Hello
    cp -p src/Hello.class obj

下記のように実行するとカレントディレクトリのファイルがsrcディレクトリにコピーされてタスク内で使用できるようになります。また、タスク内でobjディレクトリにコピーしたファイルは、/tmp/objで受け取ることができます。

$ fly -t test execute -c sample.yml -i src=. -o obj=/tmp/obj
executing build 44 at http://172.17.0.1:8080/builds/44 
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  1337    0  1337    0     0   1337      0 --:--:-- --:--:-- --:--:--  435k
initializing
running sh -exc java $JAVA_OPTS
javac src/Hello.java
java -cp src Hello
cp -p src/Hello.class obj

+ java -version
java version "1.6.0_38"
OpenJDK Runtime Environment (IcedTea6 1.13.10) (6b38-1.13.10-1~deb7u1)
OpenJDK 64-Bit Server VM (build 23.25-b01, mixed mode)
+ javac src/Hello.java
+ java -cp src Hello
Hello, world.
+ cp -p src/Hello.class obj
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   455    0     0    0   455      0    455 --:--:-- --:--:-- --:--:-- 45500
succeeded
$ ls /tmp/obj
Hello.class
$ 

パイプラインは、タスクに定義されたinputsとoutputsをつなぎ合わせることで成果物の受け渡しを行います。非常によく考えられていて便利です。