golangのコードにCircleCIを適用してみた話
去年の秋から、ずっとお前を使ってみたかったんだよ。
めっちゃ今更CircleCIをいじってみたので備忘録的なものを書くぞ。
最初に、CircleCIのドキュメントは以下。
CircleCIとは
まずCIってなんだよ、ということにならないために勉強。。。
CIとは、継続的インテグレーション(Continuous Integration)の略。 ソフトウェアを健全な状態に保つことを目的とし、ビルド/テストを常に行うことで問題の発見を迅速に行う開発手法です。
メリットは、というと
チーム開発の生産性、効率、満足度が向上します。 コードにおける問題の迅速な発見と解決につながります。 不具合の少ない高品質なプロダクトの提供を実現します。
コードの品質保証に一役買ってくれる開発手法って感じですね。
メリットに、チーム開発の生産性や満足度の向上も挙げられているところを見るとモチベが上がる!
CircleCIとは、CIを行うためのツールの一つです。他にもGithub ActionsとかJenkinsとかあります。
CircleCIは他のツールと比べ、ビルド/テストの処理速度が早い、らしい。
やりたいこと
ローカルリポジトリからコードをpushしたらテストを実行するって感じにしたい。
継続的デリバリーの方はとりあえず保留。。。デプロイ周りの自動化もやりたいよね。
やったこと
JWTをつかった認証をgoで実装した時のコードを再利用します。
その時の記事が以下。宣伝ですね
本流がmasterブランチなので、ブランチ切っときます。developってお名前。無難。
めっちゃちょっとだけテストを書いて、ローカルでテストを通します。よしよし。
とりあえず通るテストを用意したので、CircleCIをいじっていきます。
githubアカウントでログインします。
ログインするとこんな感じの画面に。適用したいリポジトリの横のSetUpProject
からセットアップします。
セットアップの段階で、configの取得ができます。テンプレがあるのでサクサク。
StartBuilding
からビルドかけてみます。
configファイルがないので、モーダルにて、どうする?って聞かれます。add config
しました...。
けど結局ローカルに手動で設定ファイル作ったので、add manually
で良かった気がしています。
ビルドはconfigファイル作って、リモートにpushしてからでも良いのではって思います。
次にdevelopブランチにCIのconfigファイルを作成します。
configファイルは、プロジェクトのルートディレクトリに、.circleci/config.yml
となるように作る必要があります。
config.yaml
って名前にするとつらい思いをします。
$ mkdir .circleci $ touch config.yml
ちなみにconfigの中身はこんな感じ。めっちゃシンプル
# version circleCIのバーション version: 2 # jobs CIのフローの実行単位を定義 jobs: # build workflowsを使わない場合に用意するジョブ # プッシュをトリガーとしてCIを実行する時のデフォルトエントリーポイント build: docker: - image: circleci/golang:1.12 working_directory: /go/src/github.com/yawn-yawn-yawn/authJWT-go # steps 実行内容のリスト steps: - checkout - run: go get -v -t -d ./... - run: go test -v ./...
configファイルを書いたらリモートリポジトリにpushします。
するとCIが実行されますー!連携自体はこれで完了!!簡単!
masterにプルリク出して、そこでCIが通るとこんな感じになります。気分が良い。
テストなどにエラーがあったりするとこんな感じ。
ぐぬぬってなるのでCircleCIの方を確認しにいきます。 テストの結果が吐かれてるのでチェックしたり。
導入自体は以上な感じで、サクサクできます!導入コストが低いのめっちゃ助かる。
吐かれたエラーたち
configファイルがない
config.yaml
にした場合。こんなエラーを吐かれました。
#!/bin/sh -eo pipefail # No configuration was found in your project. Please refer to https://circleci.com/docs/2.0/ to get started with your configuration. # # ------- # Warning: This configuration was auto-generated to show you the message above. # Don't rerun this job. Rerunning will have no effect. false Exited with code exit status 1
いやconfigあるが???って気持ちになります。
go get
がうまく通ってくれない。
#!/bin/bash -eo pipefail go get -v -t -d ./... package auth-jwt/handler: unrecognized import path "auth-jwt/handler" (import path does not begin with hostname)
この開発で最初、go mod init auth-jwt
って感じで初期化していたのだけど、どうやらimportのpathはhostnameから書かねばならんらしい。
ということで、module名をgithub.com/yawn-yawn-yawn/authJWT-go
に直したところちゃんと通りました。
circleCIのconfigで指定したり、gomodなしで通ったりするんだろうかと思ってみたりした。検証せねば...
go test
がつまった
ローカルで通ってたやん!ってなったけどそこじゃなかった。
#!/bin/bash -eo pipefail go test -v ./... # github.com/go-sql-driver/mysql ../../go-sql-driver/mysql/driver.go:88:33: undefined: driver.Connector ../../go-sql-driver/mysql/driver.go:99:49: undefined: driver.Connector
このissueみたところ、mysqlのドライバが、go1.9だとサポートできてないっぽい。。。
最初、configをそのままコピーしてたので、1.9だったんですよね...初めから開発環境と揃えろという話。
追加で少しだけ
configファイルにworkflows
を導入
workflows
はジョブを自動化するのに用います。
configファイルはこんな感じになる。
version: 2 jobs: test: docker: - image: circleci/golang:1.12 working_directory: /go/src/github.com/yawn-yawn-yawn/authJWT-go steps: - checkout - run: go get -v -t -d ./... - run: go test -v ./... workflows: version: 2 testflow: jobs: - test
先ほどbuild
で定義していたジョブを、test
って名前に変更して定義します。
test
ジョブをworkflows
に組み込みます。めっちゃ簡単!
実行するジョブが一個だけだと恩恵がない気がする...複数になった時に管理しやすそうですね。
終わりに
導入手こずったーと思ったけど、思い返すとそこまでじゃないな。。。
CIやるからにはテスト書かなきゃーって気持ちになりますし、品質保証もできるならちゃんと導入しよって思います。
他CIツールとかも使って比べてみたいところです。