ravelll の日記

よしなに

yarn upgrade したプルリクを出す Jenkins ジョブを作る

さくらの専用サーバチームでフロントエンドエンジニアをやっている @ravelll です。このエントリはさくらインターネット Advent Calendar 2018の7日目のエントリです。

今日は https://speakerdeck.com/ravelll/vue-dot-js-in-sakura の中で触れている yarn upgrade のプルリクを自動で出す Jenkins ジョブについて、実際に使っているジョブの作り方を書いていきます。

前提

  • Jenkins を動かしている環境の OS: Ubuntu 14.04.5 LTS
  • 動かしている Jenkins のバージョン: 2.107.2
  • Jenkins には SSH Agent プラグインがインストールされていること
  • Pull Request を出す GitHub ユーザーの Personal access token を取得していること
  • Pull Request を出す GitHub ユーザーに公開鍵が登録されていること
  • jenkins ユーザーが yarn を実行できること
    • 筆者の環境では jenkins ユーザーのホームディレクトリに ndenv を設置し、事前に必要なバージョンの Node.js と yarn をインストールしたものを使っています。PATH は他のビルドに影響が出ないよう実行するスクリプト内で export しています

作ってみる

ジョブを作りましょう。適当な名前を付けて "フリースタイル・プロジェクトのビルド" を選択して作成します。

f:id:ravelll:20181207143321p:plain

作成後、まず "ビルド環境" の "ビルド開始前にワークスペースを削除する" にチェックを入れます。

次に yarn upgrade するスクリプトの中から GitHub のアクセストークンを環境変数から参照できるようにします。"ビルド環境" にある "秘密テキストや秘密ファイルを使用する" にチェックを入れ、秘密テキストを追加します。変数に入れるトークンの値は認証情報欄の "追加" から Secret text を追加することで登録できます。

f:id:ravelll:20181207143349p:plain

f:id:ravelll:20181207143404p:plain

次に git clone/push する際に使う SSH秘密鍵を登録します。SSH Agent がインストールされていれば "ビルド環境" に "SSH Agent" の項目があるはずです。そこにチェックを入れ、"追加" から秘密鍵を登録します。

f:id:ravelll:20181207143444p:plain

f:id:ravelll:20181207143500p:plain

秘密鍵を直接入力したくない場合は Jenkins を動かしている環境に秘密鍵ファイルを設置して ssh-add する、秘密鍵を使わず git コマンド実行時にユーザー名と GITHUB_ACCESS_TOKEN を指定するなどして回避することができるでしょう。

次に実際に yarn upgrade をする処理を書きます。"ビルド" の "ビルド手順の追加" から "シェルの実行" を選択し、以下のようにスクリプトを書きます。

today=`date +%Y%m%d`
branch="yarn-upgrade-$today"

# jenkins 上に設置した秘密鍵を使う場合の例
#
# eval $(ssh-agent)
# ssh-add /var/lib/jenkins/.ssh/users_key

export PATH="$HOME/.ndenv/bin:$PATH"
eval "$(ndenv init -)"

git clone git@github.com:your/awesome-repo.git
cd awesome-repo
git checkout -b $branch
yarn upgrade
git add -A
git commit -m 'yarn upgrade'
git push origin $branch

# GITHUB_ACCESS_TOKEN を使って push する場合の例
#   * git clone は https プロトコルで行う
#   * expect コマンドが無かったら apt-get install expect-lite する
#
# expect -c "
#   set timeout 60
#   spawn git push origin $branch
#   expect \"Username\"
#   send \"pull-request-user\n\"
#   expect \"Password\"
#   send \"$GITHUB_ACCESS_TOKEN\n\"
#   wait
# "

curl -X POST \
  -H "Authorization: token $GITHUB_ACCESS_TOKEN" \
  -d"{\"base\":\"master\",\"head\":\"$branch\",\"title\":\"yarn upgrade: $today\",\"body\":\"Upgraded!\"}" \
  https://api.github.com/repos/your/awesome-repo/pulls

ここまでできたらジョブの設定を保存し、ビルドしてみましょう。想定通りにプルリクエストが来ていれば成功です🎉

正常に動くことが確認できたら定期実行の設定をしましょう。定期実行はジョブの設定にある "ビルド・トリガ" の中の "定期的に実行" から crontab のシンタックス*1設定することができます。
例えば毎週月曜日の朝9時頃に実行したい場合は H 9 * * 1 のように設定すれば良いでしょう。

*1:help に "with minor differences" とあるように完全に同じ仕様ではない