Travis では複数のジョブを並列で実行できる。複数の処理系のバージョンでテストを回したりするのはよく行われている。
また、Travis は後処理でデプロイも行える。専用の設定をする項目があり、一部の有名所のデプロイ先については雛形が用意されていてオプションの項目を埋めるだけだ。
私は今まで Travis から https://www.npmjs.com/ へ npm パッケージをデプロイする設定をしていたのだけど、普通に設定しているだけだと並列で実行されている全てのジョブがデプロイを実行するので、多重デプロイが発生していることに気付いた。
幸い www.npmjs.com は同じバージョンのデプロイをエラーとして弾いてくれていたのでデプロイ自体は問題なく行われていたが、いかんせん無駄だし、気持ち悪い。また、この設定だと一部のジョブでテストが失敗しても、どれか1つが成功してしまえばデプロイされてしまう。これは問題がある。
そこでなんとかする方法を調べた。
Build Stages
Travis には Build Stages というまさに今回の問題のための機能があり、これを使えば問題が解決することがわかった。
全てのジョブはいずれかのステージに紐付けられており、各ステージではステージ内の全てのジョブを並列に実行し、かつそれぞれステージはステージ内のジョブが全て成功してから次のステージに進む。
実は何もしなくても、通常の設定のジョブは全てデフォルトである test
ステージに属していることになっている。
今まで行っていた設定は以下のような感じ(一部改変)。
language: node_js node_js: - "node" - "6.0" - "6" - "7.0" - "7" sudo: false cache: directories: - node_modules before_install: - npm install -g codecov script: - npm run lint - npm run coverage # テストしつつカバレッジを取る after_success: - codecov deploy: provider: npm skip_cleanup: true email: thinca+npm@gmail.com api_key: secure: {travis encrypt コマンドで設定した値} on: tags: true
これを以下のようにした。前半は全く同じで、最後だけ違う。
language: node_js node_js: - "node" - "6.0" - "6" - "7.0" - "7" sudo: false cache: directories: - node_modules before_install: - npm install -g codecov script: - npm run lint - npm run coverage # テストしつつカバレッジを取る after_success: - codecov jobs: include: - stage: npm release if: tag IS present node_js: "node" cache: {} before_install: skip install: skip script: skip after_success: true # Don't skip: To trigger the deploy deploy: provider: npm email: thinca+npm@gmail.com api_key: secure: {travis encrypt コマンドで設定した値} on: tags: true
まず前提として、これは Git のタグを push した時にだけデプロイをする設定だ。if: tag IS present
で、タグが存在する場合にのみこのジョブを実行する。このジョブは stage: npm release
によって npm release
ステージに属しており、これはデフォルトの test
ステージの次に実行される。
jobs.include
以下の各ジョブは、トップレベルの設定を引き継ぐ。しかし、デプロイ時に再度テストを実行する意味はない。そこで各ステップを skip
として飛ばすようにしている。この辺りは、テストの設定も jobs.include
に書いてしまえば解決するのかもしれないけど、試していない。
そして次がハマったところで、どうも after_success
を skip
してしまうと、デプロイ処理自体行われなくなってしまう模様。ドキュメントにも特に記載が見つけられず、かなり試行錯誤した。なのでここは skip
せず、適当に何もせず成功するコマンド、今回の場合は true
コマンドでトップレベルの設定を上書きした。
という感じで、無事Travis から npm パッケージのリリースに成功した。
これで今後は npm version patch
等でバージョンコミット&タグを作成したあと git push origin master --tags
でタグを push するだけで npm パッケージがリリースできる。ラクチン。