GitLab のコンテナネイティブなパイプライン機能を使ってみる

オンプレミスで自前のサーバーを建て GitLab をセルフホストしている現場をよく見るようになってきました。GitLab 曰く、セルフホスト市場で 2/3 のシェアを獲っているそうです。

今や GitLab はソースコード管理に留まらず DevOps 含めたワンストップのサービスになろうとしているようです。

docs.gitlab.com

CI/CD が標準装備で、月2000分まで無償枠です。GitLab にアカウントを作成して、CI を試してみました。

1つのリポジトリに対して1つの CI/CD パイプラインを定義できます。パイプラインは .gitlab-ci.yml という名前の YAML ファイルで記述します。

build1:
  stage: build
  script:
    - echo build

test1:
  stage: test
  script:
    - echo "run a test suite"

test2:
  stage: test
  script:
    - echo "run a lint test"

deploy1:
  stage: deploy
  script:
    - echo "Do your deploy here"

git clone がないのは対象リポジトリが固定だからです。デフォルトの stage 名と実行順は buildtestdeploy で、ステージ名が同じ場合は並行実行になります*1。上記のパイプラインは以下のように、test1test2 がパラレルに実行されます。

f:id:kondoumh:20190414060306p:plain

前回の Jenkins Build Pipeline と同様に Spring Boot アプリのサンプルを使います。

github.com

リポジトリは GitHub から簡単にインポートできます。プロジェクトのルートに .gitlab-ci.yml を配置すれば CI Runner がコミットの度にパイプラインを実行してくれます。

f:id:kondoumh:20190414013930p:plain

Runner は GitLab で稼働していますが、Jenkins の JNLP エージェントのようにローカル環境にインストールして実行することも可能です。

docs.gitlab.com

今回作ったパイプライン定義です。BuildTest の2ステージ構成で、それぞれ Java 8 と Docker in Docker のコンテナイメージを使います。Build ステージで Spring Boot アプリの JAR を作成 (ビルドと単体テスト実行、アーカイブが流れます)。artifacts で生成した JAR のパスを書いて、Test ステージの docker-compose から呼ばれる Dockerfile でコンテナに JAR を COPY しています。

Build:
  image: java:8
  stage: build
  script: ./mvnw package
  artifacts:
    paths:
      - target/sb-sample-service.jar

Test:
  image: docker:latest
  services:
    - docker:dind
  stage: test
  script:
    - apk add --no-cache py-pip python-dev libffi-dev openssl-dev gcc libc-dev make curl
    - pip install docker-compose
    - docker-compose up -d
    - sleep 30
    - 'curl -X POST "http://docker:8080/api/user/" -H "accept: */*" -H "Content-Type: application/json" -d "{ \"id\": 1, \"name\": \"Mike\"}"'
    - 'curl -X GET "http://docker:8080/api/usr/1" -H "accept: */*"'
    - docker-compose down

Test ステージではコンテナ内でアプリのコンテナを起動して curl で REST API を叩きます。docker-compose をインストールするために Python をインストールして pip install でインストールしています。curl もインストール。

docker-compose up -d でアプリと Mongo DB のコンテナを起動、curl で REST API を叩きます。この時アプリのホスト名は docker を使います*2

パイプライン実行結果グラフのノードをクリックすると実行ログを確認できます。

f:id:kondoumh:20190414071031p:plain

f:id:kondoumh:20190414011906p:plain

今回は使っていませんが、ステージ毎に only セクションでビルドの種類を指定でき、MR (Merge Request) 単位のビルドや Master ビルドを定義して GitLab フローを回すのに最適です。

build:
  stage: build
  script: ./build
  only:
  - master

test:
  stage: test
  script: ./test
  only:
  - merge_requests

deploy:
  stage: deploy
  script: ./deploy
  only:
  - master

docs.gitlab.com

Jenkins のように複数のリポジトリを取得して複合的なパイプラインを作るということはできません*3が、今回見たようにコンテナがネイティブにサポートされているので、クリーン環境でテストできますし、慣れれば環境構築も楽ですね。

Microsoft にも Azure DevOps があるので GitHub とインテグレートしたりするのかな?

azure.microsoft.com

*1:stages セクションを定義してカスタマイズ可能です。

*2:これが分からずちょっとハマりました。

*3:将来的に計画はされてるようです。

Jenkins でコンテナアプリの CI

プロジェクトでは Jenkins でビルド職人をやることが結構あります。Jenkins のジョブは Web UI でポチポチ設定するのが伝統でしたが、最近はビルドパイプラインを DSL で書けるようになって Infrastructure as Code 化が進んでいます*1

wiki.jenkins.io

ここ数年は Docker コンテナでアプリをリリースすることが増えており、コンテナイメージのビルド・破棄というステップがパイプラインに入ってきます。

以前作った Spring Boot の REST API のコンテナ化アプリを題材にパイプラインを構築してみました。

blog.kondoumh.com

github.com

このサンプルでは、docker-compose で Spring Boot の jar ファイルをコンテナに COPY して起動し Mongo DB のコンテナと連携させています。

パイプラインは以下のようなステップで流します。

  • ソースコードのチェックアウト (git clone)
  • パッケージング (maven package)
    • ビルド
    • 単体テスト
    • jar ファイル生成
  • コンテナビルドと起動 (docker-compose up)
  • 結合テストの実行
  • コンテナの停止と破棄 (docker-compose down)

アプリの単体テストはコンテナビルド前に実行し、結合テストはコンテナを起動してエンドポイントに対して E2E のテストを実行します。

pipeline {
    agent { node {label 'jnlp_agent'} }
    stages {
        stage('checkout') {
            // git clone
            steps {
                checkout([$class: 'GitSCM', branches: [[name: '*/master']],
     userRemoteConfigs: [[url: 'https://github.com/kondoumh/sb-sample-service.git']]])
            }
        }
        stage('package') {
            steps {
                // build, unit test, package
                sh './mvnw package'
            }
        }
        stage('build and run container') {
            steps {
                // build and run container
                sh 'docker-compose up -d'
                sleep 60
            }
        }
        stage('container integration test') {
            steps {
                // e2e test with curl
                echo 'conteiner integration test'
                sh 'curl -X POST "http://localhost:18888/api/user/" -H "accept: */*" -H "Content-Type: application/json" -d "{ \"id\": 1, \"name\": \"Mike\"}"'
                sh 'curl -X GET "http://localhost:18888/api/usr/1" -H "accept: */*"'
            }
        }
    }
    post {
        always {
            // shutdown container
            sh 'docker-compose down'
        }
    }
}

DSL なので Groovy 知らなくても大体読めると思います。agent {} 宣言で実行する Jenkins agent を指定します*2stages 内の stage が順次実行されます。post { always{} } に書かれた処理は stages の途中でエラーが発生しても必ず実行されます。stage は並列実行などもできます。

docker-compose でコンテナをビルド実行すると Spring アプリケーションの起動に時間がかかるため、sleep を入れてます。

結合テストは Java で書いてちゃんと assert すべきですが、簡単な動作確認を curl で書いて済ませました。

実行は Blue Ocean のモダンな画面でモニタリングできます*3

f:id:kondoumh:20190401211954p:plain

jenkins.io

Blue Ocean の画面でパイプラインを編集可能なプラグインもあるようです。

今回のように Docker コマンドを shell で叩いてもいいのですが Pipeline Plugin の DSL で書けるようにしてくれるプラグインもあります。

wiki.jenkins.io

イメージの取得ビルド、コンテナ内のプログラム実行、ジョブ終了後のコンテナ破棄をやってくれます。ただし、docker-compose には対応していないようです。残念。

Jenkins のエージェント自体もコンテナで動かすことができて、公式のイメージを利用できます。

https://hub.docker.com/r/jenkinsci/slave

Jenkins ではプラグインを使う必要がありますが、最近の CI ツールはネイティブにコンテナイメージを扱えるものが主流になっています。 Jenkins も Jenkins X というプロジェクトで、クラウドネイティブ化を目指しています。

jenkins-x.io

*1:Jenkinsfile という Groovy の DSL でコードとして管理できます。

*2:以前は slave と呼ばれてましたがポリコレ的に改名されました。

*3:Blue Ocean は必須ではありません。

Visual Studio 2019 for Windows / Mac ダブルリリース

Visual Studio 2019 は Windows 版と macOS 版が同時リリースされました。

visualstudio.microsoft.com

f:id:kondoumh:20190406145225p:plain

for Mac

macOS 版からインストールしてみます。以前入れた 2017 Community 版はなぜか起動できなくなってそのまま放置してました。

blog.kondoumh.com

f:id:kondoumh:20190406145822p:plain

とりあえず全部入りで

f:id:kondoumh:20190406145845p:plain

f:id:kondoumh:20190406145906p:plain

わりとあっさり終わりました。2017 をインストールしていたのでその残骸のモジュールアップデートだけで済んだのもありました。

f:id:kondoumh:20190406145932p:plain

Xamarin の master - detail フォームのアプリを生成してみます。

f:id:kondoumh:20190406150005p:plain

ASP.NET Core Web API プロジェクトを追加する にチェックを入れました。

f:id:kondoumh:20190406150024p:plain

f:id:kondoumh:20190406150050p:plain

2017 版と同様なプロジェクト構成です。

f:id:kondoumh:20190406150921p:plain

アプリをビルド・デバッグしてみました。いい感じです。エミュレータは Xcode や Android SDK のものが使われます。Swagger UI も起動して API の確認ができます。

f:id:kondoumh:20190406152509p:plain

ダークテーマにも対応してました。

f:id:kondoumh:20190406154420p:plain

for Windows

次に Windows 版。事前に 2017 は全部アンインストールしてます。

f:id:kondoumh:20190406154701p:plain

f:id:kondoumh:20190406154718p:plain

UWP の開発予定はないし、モバイル開発や Node.js、Python の開発も Visual Studio ではやらないので、ワークロードの画面では [ASP.NET と Web 開発]、[.NET デスクトップ開発]、[C++ によるデスクトップ開発]、[.NET Core クロスプラットフォーム開発] にチェックを入れました。

f:id:kondoumh:20190406154733p:plain

C++ は MFC アプリ開発にはデフォルトのオプションでは足りないのが 2017 のインストール時にわかっているので個別オプションをチェック

f:id:kondoumh:20190406155428p:plain

f:id:kondoumh:20190406160041p:plain

Windows 版のインストールは全部入りじゃなくてもけっこうかかりました。

f:id:kondoumh:20190406164455p:plain

以前作った WPF のプロジェクトを開いてみました。

blog.kondoumh.com

ターゲットフレームワークが入ってないと言われたので別途インストール。

f:id:kondoumh:20190406164851p:plain

マイグレーションできました。コードエディタ上にプロパティの参照情報がオーバーレイされるようになってますね。設定は 2017 のが引き継がれています。

f:id:kondoumh:20190406171233p:plain

MFC アプリのプロジェクトも上記の C++ 追加設定で無事マイグレーションできました。

印象

Mac 版は 2017 をほとんど触ってない僕が言うのもなんですが、2017 の Xamarin Studio をリネームしましたというリリースに比べると、各ツールのインテグレートが進んで Visual Studio 感が出てきている印象です。.NET Core も一緒にインストールされるようになりました。

コードエディタは .NET Core と ネイティブ macOS UI で完全に書き換えたみたいです。

blogs.technet.microsoft.com

Visual Studio for Mac のコード エディターは、Visual Studio on Windows と共有されるコア上に構築された新しいエディターと、ネイティブの macOS UI で、完全に置き換えられました。スムーズな編集およびナビゲーションによりエクスペリエンスが向上しているだけでなく、新しいエディターには、Visual Studio エディターに期待される強力な IntelliSense コード補完およびクイック修正提案もすべて含まれます。

やはり Xamarin でクロスプラットフォームなモバイルアプリ作りたい時は Xcode が利用できる macOS 版を使うのがよさそうです。

Windows 版もインストールが一層改善されています。リリースノートによるとパフォーマンスも大きく改善されている模様です。

.NET Core や Language Service Protcol そして .NET Core CLI が普及すれば Visual Studio なしで、テキストエディタだけで .NET の開発できる世界がもうそこまで来ている気はします。

docs.microsoft.com

しかしながら、ベースラインは 2年に1度の Visual Studio のリリースという時代が当面続くのかなあと。

野良 Scrapbox アプリ - プロジェクトアクティビティ表示ダイアログ

またまた Scrapbox アプリの話。

社内で導入されている Scrapbox。隙間時間に閲覧・更新できて社内の活動も透明化されるということで、我々のように客先常駐が多い環境では導入効果高いです。

導入した管理者の人から、利用状況を把握するためページビュー(集計値) の推移を記録したいという要望がありました。

ページ一覧を取得する API で全ページのリストを取れば可能です。1回のリクエストで取得できる一覧には限りがあるので、繰り返し取得して最後に集計値をダイアログ表示するようにしています。Copy ボタンを押すとクリップボードに内容がコピーされます。

f:id:kondoumh:20190328212609p:plain

これは、僕の個人ページの情報ですが、会社のはすでに2,000ページ、80,000ビューを超えています。

Release v0.6.3 · kondoumh/sbe · GitHub

野良 Scrapbox アプリ - 見出し指定っぽいコンテキストメニュー

Scrapbox には見出し記法はなく、文字の大きさを [** text] というフォーマットで修飾する(* が多いとサイズが大きい) という仕様です。標準のメニューでは * 1個のパターンのみ Strong 記法として指定可能です。

長めの文章を書いていると、文字の大きさを見出し風に指定したい場合があるので、独自コンテキストメニューで4段階で指定できるようにしました。Scrapbox の場合タイトルの文字がだいたいレベル4ぐらいのようなので 1-4 で指定できれば OK ということで。

f:id:kondoumh:20190326004310g:plain

関連する機能として、見出しサイズを指定してプレースホルダーとして挿入するキーボードショートカット (⌘ + 1 など) も以前のバージョンで追加してました。

f:id:kondoumh:20190326005730g:plain

Release v0.6.2 · kondoumh/sbe · GitHub

野良 Scrapbox アプリ - ページ情報ダイアログを出せるようにしました

コンテキストメニュー Info からページ情報を表示するダイアログを出すようにしました。

f:id:kondoumh:20190309105249p:plain

ページを開く前に概要を把握できたらと思い、ページへのリンクに対してコンテキストメニューを表示しています。

タイトル、ページを作成したユーザ、共同編集ユーザ、ページ概要を表示します。

ページ概要は、本文の先頭5行ぐらいが入っている模様です。

ダイアログから直接ページを開くことも可能です。

f:id:kondoumh:20190309014844p:plain

Release v0.6.1 · kondoumh/sbe · GitHub

社内勉強会で Electron の話をしました

そもそも社内勉強会で喋るというのが初だったかも。

www.slideshare.net

趣旨としては、

  • Electron 熟成してきてるよ
  • クロスプラットフォーム開発大変だけど Electron はけっこう手軽
  • PWA の方が流行るかもしれないけどねー

という感じです

簡単なハンズオンもやりました。

  • WebView を使うサンプルを作ってみる
  • 独自の Menu を追加してみる
  • WebAPI からデータを取得してレンダリングしてみる

先日の Vue アプリの Electron 化もデモしました。

blog.kondoumh.com

Main process 経由で OS ネイティブのプログラムと Web 画面の相互運用ができることに興味を示した人がいました。