くりにっき

フルスタックキュアエンジニアです

Travis CIで定期的にビルドを実行する

tl;dr;

Travis CIを使っているのならCron Jobsを使うのが便利

前置き

Meguro.rb#2OSSパッチ会 で発表した資料で「1年以上ビルドしてないリポジトリだと久しぶりにPRが飛んできたらactivesupport系でだいたいテストが落ちる」といったことをしゃべったのですが、それに対してリポジトリ管理者はどうすべきかというアンサーソングです

解決方法

リポジトリを定期的にビルドをすることで解決することができます。

大半のOSSだとTravis CIを使ってることが多いと思いますが、Travis CIだと「Cron Jobs」でブランチの定期ビルドができます

Cron Jobs - Travis CI

設定方法

Travis CIの Settings -> Cron Jobsで設定するだけです。(詳しくは 公式ドキュメント 参照)

f:id:sue445:20170528151200p:plain

monthly(1ヶ月に1回ビルド)、weekly(1週間に1回ビルド)、daily(1日1回ビルド)のいずれかのタイミングで定期ビルドが実行できます。

f:id:sue445:20170528151441p:plain

活用例

自分はweeklyを使って週1の定期ビルドしています。

登録した日時を起点にして定期ビルドが実行されるのですが、金曜日の18:30過ぎ(だいたい定時)に設定したので、20個くらいのリポジトリで一斉にビルドが実行されてSlackに通知が流れると非常に花金感があります。

f:id:sue445:20170528151524p:plain

プリキュアが始まる前にトゥートするmastodonボットなどを作った

前置き

最近 Mastodon が流行っていますが、僕はプリキュア好きなのでプリキュアインスタンスきゅあったー に参加しています。

precure.ml

中の人曰く

f:id:sue445:20170507212951p:plain

とのことだったので*1、サーバの負荷にならないレベルで雑にボットを作ってみました

プリキュアこのあとすぐボット

プリキュアは日曜朝(通称ニチアサ)の本放送以外にも、過去作品がほぼ毎日どこかの放送局で再放送されています。それが始まる前にトゥートするボットが「プリキュアこのあとすぐボット」です

https://precure.ml/@precure_onair_bot

f:id:sue445:20170507213554p:plain

実際にトゥートした結果

こんな感じ。

f:id:sue445:20170507212206p:plain

https://precure.ml/@precure_onair_bot/20677

f:id:sue445:20170508174846p:plain

https://precure.ml/@precure_onair_bot/23663

技術的なこと

番組情報を しょぼいカレンダーAPI から取得して、プリキュア開始10分前くらいになったらトゥートするようにしてます。*2

気持ち的には開始5分前くらいにしたかったんだけど、Heroku Schedulerで指定できる時間が10分刻みなため10分前にしています。

f:id:sue445:20170507214528p:plain

これくらいのボットなら個人サーバに置いてcrontabで動かすというのもあったけど、git pushで (楽に|雑に) デプロイできるのが魅力だったのでHerokuを採用。

プリキュア誕生日ボット

プリキュアの誕生日にトゥートするだけのボットです

https://precure.ml/@precure_birthday_bot

f:id:sue445:20170507215038p:plain

開発時期の関係でまだ1トゥートもしてないですが、バグってなければ5/28のキュアロゼッタの誕生日にトゥートされるはず

【2017/5/28追記】 ちゃんと投稿されたのでスクショ追加

f:id:sue445:20170528145844p:plain

https://precure.ml/@precure_birthday_bot/79359

技術的なこと

プリキュアの誕生日情報は rubicure で管理されているので、今日が誕生日のプリキュアを取得したい場合はこういう風にワンライナーでシュッと書けます。rubicure便利(熱い自画自賛

birthday_girls = Precure.all.select { |girl| girl.birthday?(today) }

https://github.com/sue445/cure-mastodon-bots/blob/2f8beb07fcd5e980cf8dd926329804a44d665e40/lib/birthday_bot.rb

ソースコード

いずれもこちらになります

github.com

参考リンク

*1: https://precure.ml/@precure/20379

*2:厳密には毎時50分(20分)になったら10〜39分後(つまり毎時0〜29分 or 毎時30〜59分)に開始する番組の中にプリキュアが含まれてる場合にトゥート

chrome-gitlab-notifier v2.0.0をリリースした

今年初のビッグバンリリースです

chrome.google.com

tl;dr

既存のコードを全て捨てて全部書き直しました

書き直した経緯

  • GitLab API v4に対応するにあたって、既存のコードベースでv3とv4両方対応するのはいろいろつらそうだったため
    • 特にjQueryでDOMをゴリゴリ操作してるところとか
  • テストを書いてないことはなかったけど、jQueryでDOM操作してるviewや定期的にGitLab APIをたたいてポーリングしてるバッググラウンド処理のテストが全然なくて、かつ今までの経験上一番不具合起こってた場所だったので手厚くテストを書きたかった

主な変更点

https://github.com/sue445/chrome-gitlab-notifier/blob/master/CHANGELOG.md#200-20170504 からの抜粋です

  • 全てのjsをES6で書き直した
    • Chromeはトランスパイル不要でES6がそのまま動かせるので、あえてBabel系のツールは使っていません
    • Chrome拡張はChrome以外のブラウザを考慮不要なのが非常によい
    • classとアロー演算子便利
  • jQueryに依存してた処理を mithril.js に移植
    • Twitter BootstrapがjQueryに依存してるためjQuery自体は捨てていませんが、プロダクトコードでのjQuery依存は全部なくしました
    • mithril v1を使ってたのですが、日本語サイト がv0系のままで苦労した記憶(mithril移植終わったくらいで日本語サイトもv1対応してた)
  • Jasmineでやってたユニットテストmocha に変更
    • 最初 ospec っていうmithril付属のテスティングフレームワーク使ってたのですが、あまりにも機能が少なすぎたので断念
    • 一番最初にテスト書いてた当時(4年前くらい)はJasmineとmochaほぼ同じくらいのシェア(主観)だったのですが、今はmochaが優勢な気がした(主観)のでmochaを採用
  • ESLint 導入
    • 仕事でrubocopをよく使ってるのでjsでも使いたいと思って探していたらESLintに行き着いた
  • yarn 導入
    • Travis CIでnpm installしたパッケージのキャッシュを効かせるにはyarnが必要っぽかったので導入
  • せっかくなので使ってるライブラリも諸々アップデート
  • その他細かいバグ修正など

差分

プルリクエストだと差分しかなくてワケワカメなので細かいdiff読むならマイルストーンがおすすめ

f:id:sue445:20170504024921p:plain

プルリクエスト上だとライブラリのアップデート内容も含まれてるので無駄に差分が大きいですが、書き直したソースの差分だけならこんな感じ

$ git diff --stat 1.4.3...2.0.0 -- src/
 src/avatar_cache.js       |  69 +++++++--------
 src/background.js         | 356 +++++++++++++++++++++++++++++++++++------------------------------------------
 src/background_init.js    |  42 ++++++++++
 src/base_cache.js         |  19 +++++
 src/config.js             | 348 ++++++++++++++++++++++++++++++++++-----------------------------------------
 src/gitlab.js             | 313 ++++++++++++++++++++++++++++++++++++++------------------------------
 src/notification.js       | 130 +++++++++++++++-------------
 src/notification_cache.js |  71 ++++++++--------
 src/options.js            | 489 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------------
 src/options_init.js       |  42 ++++++++++
 src/popup.js              | 235 +++++++++++++++++++++++++++------------------------
 src/popup_init.js         |  36 ++++++++
 src/util.js               |  61 --------------
 13 files changed, 1237 insertions(+), 974 deletions(-)

$ git diff --stat 1.4.3...2.0.0 -- test/
 test/avatar_cache_test.js       |  56 +++++++++++++++++++++
 test/background_test.js         | 273 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 test/base_cache_test.js         |  38 ++++++++++++++
 test/notification_cache_test.js |  65 ++++++++++++++++++++++++
 test/notification_test.js       | 148 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 test/options_test.js            |  31 ++++++++++++
 test/popup_test.js              |  63 +++++++++++++++++++++++
 test/stub/projects.json         | 112 +++++++++++++++++++++++++++++++++++++++++
 8 files changed, 786 insertions(+)

$ git diff --stat 1.4.3...2.0.0 -- spec/
 spec/SpecRunner.html                   |   63 ---
 spec/gitlab_spec.js                    |   98 ----
 spec/lib/jasmine-1.3.1/MIT.LICENSE     |   20 -
 spec/lib/jasmine-1.3.1/jasmine-html.js |  681 ------------------------
 spec/lib/jasmine-1.3.1/jasmine.css     |   82 ---
 spec/lib/jasmine-1.3.1/jasmine.js      | 2600 --------------------------------------------------------------------------------------------
 spec/lib/jquery.mockjax.js             |  587 ---------------------
 spec/lib/run-jasmine.js                |   86 ----
 spec/notification_spec.js              |   94 ----
 spec/spec_helper.js                    |    4 -
 spec/stub.js                           |   89 ----
 11 files changed, 4404 deletions(-)

spec/ 全消しなのはJasmineを捨ててmochaに乗り換えたためです

mithril.jsを採用した経緯

実は最初Vue.jsを使って書き直してたのですが、Vue.jsの中で使ってるevalがChrome拡張だとサンドボックスモードを有効にしないと使えなくて、サンドボックスを有効にすると今度はChromeのlocalStorageにアクセスできなくてVue.jsは断念しました。

が、後日Twitterでのやりとりで事前に全部コンパイルしているとChrome拡張でもVue.jsが使えるということが判明。

jp.vuejs.org

次にChrome拡張作る時はVue.jsワンチャンありそう

開発期間とか

前述のVue.js時代から含めるとかれこれ2ヶ月くらいかかって全部のコードを書き直しています

あとビッグバンリリースと銘打ってますが、TDDのこころ に従って1ファイルずつ地道にES6化&テスト追加しています

1ヶ月くらい自分のローカルで動かしてたので致命的なバグはないはずです。

今日から使える!OSSプルリク集 #megurorb

昨日 Meguro.rb#2 2017/04/20(Thu) でLTをしたのでその時の資料を公開したいと想います

megurorb.connpass.com

スライド版

sue445.github.io

リポジトリhttps://github.com/sue445/megurorb-02

ブログ版(内容はスライドとほぼ同じです)

OSSにプルリク出す時のあるあるネタを実用例を交えて紹介


1. ドキュメントのtypoなどを修正

  • これが一番プルリクの難易度は低い

https://github.com/gitlabhq/gitlabhq/pull/7534

  • GitLabのwebhookで実装はされているが、リファレンスから漏れているパラメータがいくつかあったので追加
  • 「◯◯(プルリク番号)で追加されているけどその時にリファレンスに更新されていないよ!」って言えればベスト
  • GitLabはAPIの実装とリファレンスの差異が結構多いので狙い目

2. .travis.yml に新しいRubyのバージョンを追加

rvm:
  - 2.1
  - 2.2.2
  - 2.3.1
  # ここに2.4を追加したい

CI against ruby 2.4

https://github.com/sue445/index_shotgun/pull/28/files

f:id:sue445:20170420010405p:plain


英文の元ネタ

https://github.com/amatsuda/database_rewinder/commit/6a1f87c3a0729391bd24c68f38d28622d385479b

f:id:sue445:20170420010438p:plain

「CI against 〜」は使いやすいので定型句として覚えていていい


3. gemの新しいバージョンが出たので依存を緩めたい

f:id:sue445:20170420010449p:plain


https://github.com/activeadmin/activeadmin/pull/4722

  • kaminari v1系が出た直後に、activeadminでkaminari 1系使うために依存を緩めたかった

f:id:sue445:20170420010458p:plain


英文の元ネタ

https://github.com/activeadmin/activeadmin/commit/7a861b723bd65ea174541cf2f23048143575cba8

f:id:sue445:20170420010506p:plain

「Relax ◯◯ dependency for △△△」も使いやすいので定型句として覚えていていい


4. activesupportactiverecordに依存してるgemでRuby 2.2未満系でコケるので5系未満使うようにする

  • 1年以上ビルドしてないようなリポジトリだと久しぶりのPRでビルドがコケる原因第1位

f:id:sue445:20170420010518p:plain

https://travis-ci.org/railsware/global/jobs/198722120


Gemfileにとりあえずこれ書いとけば bundle install できるのでPR送る

if Gem::Version.create(RUBY_VERSION) < Gem::Version.create("2.2.2")
  # activesupport 5+ requires MRI 2.2.2+
  gem "activesupport", "< 5.0.0"
end
  • Ruby 2.2.2未満で動かんからとりあえずサポート切ったわ!」っていきなりPR送るのは穏やかじゃないので、Ruby 2.2.2未満だったらCIでactivesupport 5系使わないようにしてCIを正常な状態に戻すのが平和
  • 実際にRuby 2.2.2未満のサポート切るかどうかはリポジトリオーナーの判断に委ねる

Tips:バージョンは文字列比較ではなく Gem::Version で比較した方がいい

"2.1.10" > "2.1.2"
#=> false

Gem::Version.create("2.1.10") > Gem::Version.create("2.1.2")
#=> true

"5.1.0" > "5.1.0.rc1"
#=> false

Gem::Version.create("5.1.0") > Gem::Version.create("5.1.0.rc1")
#=> true

5. Railsのrc出たからとりあえずビルドしようぜー!

https://github.com/mitaku/komachi_heartbeat/pull/22

f:id:sue445:20170420010531p:plain


.travis.ymlで複数gemfile対応してるのであればgemfile作って1行追加するだけ

gemfiles/rails5_1.gemfile

source "https://rubygems.org"

gem 'rails', "~> 5.1.0.rc1"

gemspec path: '../'

.travis.yml

gemfile:
  - gemfiles/rails4_1.gemfile
  - gemfiles/rails4_2.gemfile
  - gemfiles/rails5_0.gemfile
  - gemfiles/rails5_1.gemfile # <- 1行追加

正式版じゃないのでallow_failuresにしておいて、ビルドコケるのは許容する

matrix:
  allow_failures:
    # NOTE: There are unstable versions
    - rvm: ruby-head
    - gemfile: gemfiles/rails5_1.gemfile # TODO: Remove this after rails5.1 is released!

6. Travis CI対応してないリポジトリに .travis.yml 投げつける

f:id:sue445:20170420010539p:plain


Let’s contribute! :innocent:

備考

今回スライド作成に reveak-ck を使っていますが、reveal-ckはOGP対応していなかったのでOGP対応してプルリク投げています

github.com

発表に使ったスライドもプルリク投げたブランチでビルドしています

# frozen_string_literal: true
source "https://rubygems.org"

gem "rake"
# gem "reveal-ck"
gem "reveal-ck", github: "sue445/reveal-ck", branch: "meta_contents"

https://github.com/sue445/megurorb-02/blob/68f69bcd4de980969e9b0fa42fed9e6c262b8b69/Gemfile

OGP対応の結果はこちらになります sue445.github.io

2017/4/24追記

reveal-ckに僕のプルリクが取り込まれたやつが v3.6.0 としてリリースされています! https://github.com/jedcn/reveal-ck/blob/master/CHANGELOG.md#360–2017-04-23

誕生日に有給でプリ充してきた

プリ充 = リア充プリキュア版みたいなの

Togetterでもよかったんだけどはてなブログの方がはてブ通知受け取れて便利なのでこっちで。

プリキュアドリームスターズ@TジョイSEIBU大泉

キラキラ☆プリキュアアラモード

誕生日なので有給とってプリキュア映画見にきた

なんだかんだで5回目でした。1つの映画でこれだけ見るのはおそらく最多

とはいえ、5回目でもいろいろ新しい発見があってよかった

展示

Go!プリンセスプリキュア

魔法つかいプリキュア

キラキラ☆プリキュアアラモード(3人)

カスタードかわいい

Instagram

スイパラプリキュアコラボ@池袋スイパラ

www.sweets-paradise.jp

去年か一昨年も誕生日に有給とってスイパラ行きましたが、平日昼間だと予約なしで並ばずに入れてよいですね

キラパティ感ある

ペコリン

以降飯テロ注意

りすプリン!ハッピーバースデー俺!

キュアカスタードのオレンジフロート

ごちそうサマンサタバサ

こちらからは以上です

35歳になった

とうとう定年の歳です *1

例年のごとくこの日は有給とってプリキュアの映画を見に行く予定です。

例のリスト

http://www.amazon.co.jp/registry/wishlist/3HH1FL88AQAG8/

ご査収ください

*1:「エンジニア35歳 定年」でググってください