VB.NETでもナウいCIサーバでテストをギュイーンしたい
はじめに
この記事はVisual Basic Advent Calendar 2018の15日目の記事です。
どうも、闇落ちJenkinsおじさんです。
オンプレのCIサーバといえばJenkinsが筆頭に上がりますが、Jenkinsのビルド環境が秘伝のタレ化してスレーブを追加する際に死ぬほどコンパイラやらSDKやらをぶち込まないとならず、自動化の裏側でソウルジェムをマッハで濁らせながらメンテナンスしている管理者も多いのではないでしょうか。
こんな時、コンテナでテスト環境は生成・破棄出来たらどんなに幸せでしょうか。オンプレで
コンテナは投げ捨てるもの
JenkinsでもPipelineを使えばDockerコンテナ上でビルド・テストを実行出来ますが、いかんせんGroovyで記述しなくてはならないというところが個人的にはつらみポイントでした。*1
という感じで色々迷っていたところ、drone.ioというオンプレにも展開できるDockerコンテナを使用したCIサーバを見つけたので試してみました。*2
Dockerパーリナイ
というわけで以下の図のようにLinuxインスタンスを生やしまくります。
今回の検証に使用したソフトウェアは以下な感じです。
- dnsmasq
- 弊社は3桁以上の数字は覚えられないのでDNSサーバを立てます。
- Gitea
- Giteaを使うと割と簡単に構築できるそうなので今回はGiteaを使用しました。
- drone
- 今回の主役です。今回はサーバとエージェントを分ける構成で構築してみました。
今回はdnsmasq以外はすべてDocker上で構築します。これは別にコンテナ至上主義とかそういうのではなく、単純にそうしたほうが楽だから程度の理由です。
Gitea
まずはソースコードをホストするためにGiteaを立てます。
Giteaはデータ格納用にPostgres・MySQL・SQL Server(とSQLite)が選べますが、マイクロソフト信者の私たちはもちろん最強のデータベースであるSQL Serverを選びますよね?
version: '3' services: mssql: image: 'microsoft/mssql-server-linux:2017-CU12' volumes: - ./data:/var/opt/mssql/data ports: - '1433:1433' environment: - ACCEPT_EULA=Y - SA_PASSWORD=mssqllinux@1 - MSSQL_LCID=1041 - MSSQL_COLLATION=Japanese_CI_AS
version: "2" networks: gitea: external: false services: server: image: gitea/gitea:1.6 environment: - USER_UID=1000 - USER_GID=1000 restart: always networks: - gitea volumes: - ./gitea:/data ports: - "80:3000" - "222:22"
drone
droneもDockerで立てていきます。というよりはDockerでしか立てられません。
version: "2" services: server: image: drone/drone:1.0.0-rc.1 environment: - DRONE_GIT_ALWAYS_AUTH=false - DRONE_GITEA_SERVER=http://gitea.opabinia.co.jp/ - DRONE_RPC_SECRET=2039906835c92213b78cce47d38be1e9 - DRONE_SERVER_HOST=drone.opabinia.co.jp - DRONE_SERVER_PROTO=http - DRONE_TLS_AUTOCERT=false restart: always volumes: - ./drone:/data ports: - "80:80" - "443:443"
drone agent
こちらに至ってはOSインストールしてDockerインストールして以下のコマンドをコピペでぶち込めばそれで終わりです。
docker run \ --volume=/var/run/docker.sock:/var/run/docker.sock \ --env=DRONE_RPC_SERVER=http://drone.opabinia.co.jp \ --env=DRONE_RPC_SECRET=2039906835c92213b78cce47d38be1e9 \ --env=DRONE_RUNNER_CAPACITY=4 \ --env=DRONE_RUNNER_NAME=dad96u1 \ --restart=always \ --detach=true \ --name=agent \ drone/agent:1.0.0-rc.1
プロジェクトの作成
まぁ、Linuxとかが出てきてお察しの通り、今回は.NET Coreで検証しています。droneのエージェントにはWindowsも使えるのでもしかしたら.NET Frameworkの方も行けるかもしれませんが今回は検証していないです。
Public Class Class1 Public Function Add(x As Integer, y As Integer) As Integer Return x - y End Function End Class
みたいなクラスがあって
Imports System Imports Xunit Imports ClassLibrary1 Public Class Class1Test <Fact> Sub Add_return_valid_value() Dim x = 10 : Dim y = 20 Dim expected = x + y Dim c = New Class1() Assert.Equal(expected, c.Add(x, y)) End Sub End Class
みたいなテストを用意します。そして、手元でテストを回してばっちり失敗することを確認してから以下の.drone.yml
を追加してからプッシュします。
kind: pipeline name: default steps: - name: classlibrary1 image: microsoft/dotnet:2.1-sdk commands: - dotnet test
ちゃんと失敗しています。
なおすと
成功します。
おわりに
多分ドキュメントの整備が追い付いていないのか、ちょっとドキュメント類が不足しているなというところが率直な感想です。 また、開発途中だから無いのかそれともエンタープライズ版との差別化なのかは分かりませんが、ブラウザから操作できることが非常に限られている感じです。ブラウザからは現在いくつのエージェントがぶら下がっているのかも分かりません。*3
今回はクッソ簡単な例しか試していませんが、これが大規模になった場合、ビルド実行用のDockerイメージを用意したり、用意したDockerコンテナをローカルでホストするためリポジトリ(Sonatype Nexus OSSとか)を用意したり、独自ライブラリをNuGet経由で配布するためにパッケージを作ったり、それをホストするためのNuGetリポジトリを立てたりと想像するだけで大変そうです。
逆にその辺を解決できれば自動化インフラ管理者にとっての救済となるかもしれません。
おわり