depからgo modulesへの移行と、移行時にTravis CI & GoReleaserでハマる(かもしれない)ポイント
Summary
- depで管理していた既存のGo製ツールをdepからgo moduleに移行してみたが、移行自体は特にハマりどころも無くスンナリいった
- go moduleへの移行後に依存パッケージのupgradeを実施、これもスンナリいった
- Travis CI + GoReleaser で、ビルド成果物をGithub Releasesに登録する作業 & GoアプリのHomeBrewパッケージ作成・公開作業 を自動化しようと試みたが、そのCIが
git is currently in a dirty state
というコケ方をしてちょっとハマった - GoReleaserは本当に便利
前提条件
|
|
切り替え手順
depを使っていたので、go mod init
して go build
の成功を確認できたらdep関連のファイルを削除する、という手順で完了します(対応例)
|
|
依存パッケージをupgradeしてみる
自作ツールで使用しているaws-sdk-goがv1.12.39だったのですが、最新がv1.16.36と乖離が発生していたのでupgradeしてみました。手順としては下記で問題ありません。
|
|
|
|
|
|
CIの設定変更(Travis CI)
test CI
Travis CIの場合は.travis.ymlを下記の通り修正すればOKです。
- envセクションで
GO111MODULE=on
を追加 - before_install か install かいずれかのセクションで
go mod download
を行うようにする
|
|
GoReleaserでGoアプリのdeploy CIを行う際の注意点
冒頭にTravis CI + GoReleaserによる成果物自動公開を試みてハマったと書きましたが、調査した結果こういう結論でした。
go mod
移行前に、「ライブラリ本体では使ってないがCIや開発補助目的でインストールしたパッケージ」が存在していた- 自分の場合は github.com/golang/lint。これをcode validation目的のCI jobで使用していた
- 該当パッケージは、自分の開発マシン(Mac)ではライブラリの開発とは無関係に
go get
で過去にインストールされていた、つまりgo.modには反映されていない状態だった。一方でTravis CIではbefore_install
セクションでCIの度にインストールを実行していた go mod
への移行によってgo get
の実行結果がgo.modとgo.sumに反映されるようになった為、Travis CIでbefore_install
セクションが実行されるとCI実行環境上でgo.modとgo.sumのgit diffが発生するようになった- GoReleaserはdeployの際に「git diffが発生していないかどうか」をチェックしていて、上記経緯でgo.modとgo.sumのdiffが発生した事によりチェックに引っかかり、deploy CIがエラーになっていた
回避策としては、
- GoReleaserのdeploy処理前に、go.modとgo.sumの差分を(強制的に)解消しておく
- Travis CIの
before_install
で実行しているgo get
をやめる(依存していたCI jobの設定も修正・削除が必要) - go.modに「CIや開発補助目的でインストールしたいパッケージ」も反映しておく
のいずれかの対応が必要そうです(とはいえ本来取るべき対応策はNo.3ではないかと)。
go modules対応版、Travis CI & GoReleaserの設定
go modulesを使用しているGoプロジェクトをgoreleaserでデプロイする場合、公式サイトで紹介されている ように .goreleaser.ymlのbefore hookの設定で go mod download
を実行するようにyamlを修正します。
|
|
そして.travis.ymlにあるdeployフェーズの設定を(無ければ追加して)、これも公式サイトで紹介されている通りGoReleaserを実行するように修正します。
|
|
こう設定しておけば、該当プロジェクトをmasterにmerge => tagを打ったタイミングで、Travis CIの deploy
フェーズで設定したGoReleaserによるデプロイも実行されるようになります。
補足: .goreleaser.ymlの動作確認について
GoReleaser公式のQuick Start にも書いてるのですが、goreleaserコマンドには --skip-publish
という公開(release)をskip出来るオプションと、--snapshot
というバージョンタグのチェックを行わず現状のコードベースの成果物を出力するオプションがあり、これらを組み合わせて.goreleaser.ymlの妥当性検証を行うことが可能です。
|
|
とはいえ実際にタグを打って成果物deploy用のCIを実行するとローカルで検証した際には見つからなかったエラーが発生する事もあり、そうなるとそのエラー解消の為にさらにreleaseを行って本チャンCIを走らせる、、、という「CIの為にrelease重ねる症候群」が起こりがちです(自分は今回ハマった件の調査の為に5つ6つはreleaseを重ねてrelease historyがだいぶ切ない事に orz…)。
公式提供のシェススクリプトをカスタマイズする
GoReleaserの場合、成果物公開用のジョブでは curl -sL http://git.io/goreleaser | bash
というスクリプトを実行するように設定しますが、http://git.io/goreleaser
の実体はタダのシェルスクリプトなので、これを丸っとコピーしてチェック処理やログ出力を追加したオリジナルのスクリプトに置き換えれば、いくらかは調査コストを下げる事が出来そうです。
|
|
|
|