くりにっき

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

久しぶりにJenkinsプラグインをリリースしようとしたら謎のエラーで失敗した

Qiitaや会社ブログにはエントリ書いてたけどこっちのブログは1ヶ月間更新無しとかマジか。(挨拶)

前置き

先日自分がメンテしてるJenkinsプラグインにPRがきて「よっしゃ!マージしてリリースするぜ!」と思っていつものリリースコマンド *1 をたたいたらリリース時に謎のエラーがおきて途方に暮れていた時の出来事です。

日本語だと今回の事象が見つからなかったので日本語でメモ残しておきます

tl;dr

org.jenkins-ci.plugins.plugin(全てのJenkinsプラグインの親プラグイン)を2.5以降にしよう

エラー内容

[INFO] [INFO] --- maven-install-plugin:2.3.1:install (default-install) @ gitlab-logo ---
[INFO] [INFO] Installing /Users/sue445/dev/workspace/github.com/jenkinsci/gitlab-logo/target/checkout/target/gitlab-logo.hpi to /Users/sue445/.m2/repository/org/jenkins-ci/plugins/gitlab-logo/1.0.2/gitlab-logo-1.0.2.hpi
[INFO] [INFO] Installing /Users/sue445/dev/workspace/github.com/jenkinsci/gitlab-logo/target/checkout/pom.xml to /Users/sue445/.m2/repository/org/jenkins-ci/plugins/gitlab-logo/1.0.2/gitlab-logo-1.0.2.pom
[INFO] [INFO] Installing /Users/sue445/dev/workspace/github.com/jenkinsci/gitlab-logo/target/checkout/target/gitlab-logo.jar to /Users/sue445/.m2/repository/org/jenkins-ci/plugins/gitlab-logo/1.0.2/gitlab-logo-1.0.2.jar
[INFO] [INFO] Installing /Users/sue445/dev/workspace/github.com/jenkinsci/gitlab-logo/target/checkout/target/gitlab-logo-sources.jar to /Users/sue445/.m2/repository/org/jenkins-ci/plugins/gitlab-logo/1.0.2/gitlab-logo-1.0.2-sources.jar
[INFO] [INFO] Installing /Users/sue445/dev/workspace/github.com/jenkinsci/gitlab-logo/target/checkout/target/gitlab-logo-javadoc.jar to /Users/sue445/.m2/repository/org/jenkins-ci/plugins/gitlab-logo/1.0.2/gitlab-logo-1.0.2-javadoc.jar
[INFO] [INFO]
[INFO] [INFO] --- maven-deploy-plugin:2.6:deploy (default-deploy) @ gitlab-logo ---
[INFO] Uploading: http://maven.jenkins-ci.org:8081/content/repositories/releases/org/jenkins-ci/plugins/gitlab-logo/1.0.2/gitlab-logo-1.0.2.hpi
[INFO]
[INFO] Uploading: http://maven.jenkins-ci.org:8081/content/repositories/releases/org/jenkins-ci/plugins/gitlab-logo/1.0.2/gitlab-logo-1.0.2.pom
[INFO]
[INFO] [INFO] ------------------------------------------------------------------------
[INFO] [INFO] BUILD FAILURE
[INFO] [INFO] ------------------------------------------------------------------------
[INFO] [INFO] Total time: 3:57.988s
[INFO] [INFO] Finished at: Thu Oct 27 08:50:12 JST 2016
[INFO] [INFO] Final Memory: 71M/499M
[INFO] [INFO] ------------------------------------------------------------------------
[INFO] [ERROR] Failed to execute goal org.apache.maven.plugins:maven-deploy-plugin:2.6:deploy (default-deploy) on project gitlab-logo: Failed to deploy artifacts: Could not transfer artifact org.jenkins-ci.plugins:gitlab-logo:hpi:1.0.2 from/to maven.jenkins-ci.org (http://maven.jenkins-ci.org:8081/content/repositories/releases): Connection to http://maven.jenkins-ci.org:8081 refused: Operation timed out -> [Help 1]

うーん、http://maven.jenkins-ci.org:8081プラグインアップロードする時にタイムアウト????

エラー全文 https://gist.github.com/sue445/259d4c71d2e4d34b33948cb61c66a900

原因

プラグインのアップロード先が http://maven.jenkins-ci.org:8081 から https://repo.jenkins-ci.org に変わったため

ソース

原因が見つかったのは https://issues.jenkins-ci.org/browse/JENKINS-37423 の下記のコメントを見つけたのがきっかけでした。(このきっかけを見つけるまで約1週間かかった)

CrossBrowserTesting.com LLC added a comment - 2016/Aug/22 11:23 PM fixed it. had to update the parent to version of at least 2.5 in pom.xml https://wiki.jenkins-ci.org/display/JENKINS/Hosting+Plugins#HostingPlugins-Workingaroundcommonissues

で、リンク先には

Either overwrite the repository location in your POM to point to https://repo.jenkins-ci.org, or update to the parent plugins POM 2.5 or newer

って書いてた。親プラグインのバージョン上げずにPOMのアップロード先だけ変えるってのが分からなかったので正攻法に親プラグインのバージョンを上げることに。

実際に対応したのがこのPR

github.com

この修正でプラグインをリリースすることができました

org.jenkins-ci.plugins.pluginのバージョンを上げるとBetamaxがうまく動かない問題

Betamaxというのはhttp通信をモック化するGroovy製のライブラリです。自分のプラグインだとGitLabの通信部分をスタブにするために使っていました

betamax.software

上記PRでbetamaxを消した理由をメモ

  1. org.jenkins-ci.plugins.pluginのバージョンを上げるとつられてJettyのバージョンも上がって、betamaxの中で使ってるJettyのバージョンが古すぎてビルドでエラーになる
  2. betamaxのバージョンを1系から2系に上げると今度はSSLのモックがうまく効かない
  3. 公式のドキュメント 読むと「 keytool -importcert 〜 でbetamaxの鍵を追加すると動くようになるよ」って書いてある
  4. しかし自分で管理してるJenkinsならまだしもcloudbeesのJenkinsでそれは無理ぽ

ってことでbetamaxを捨てて昔ながらにStubクラスからテスト対象のクラスを継承してテストするようにしました

github.com

*1:mvn release:prepare release:perform

今更RubyKaigi2016振り返り

RubyKaigi 2016 に参加してたのですが、最近までISUCON予選あったり自分がメインで関わってるアプリのリリースとかあったりで今更振り返りです

rubykaigi.org

0日目(前日)

知り合い何人かとairbnbで宿をとってたんだけど(宿主の名前をとって通称モリタハウス)、ホストから当日朝にドタキャン喰らった。FBのモリタハウス連絡部屋が朝からハチャメチャ大混乱

詳細

chiastolite.hatenablog.com

1日目

聞いたセッション

最後のk0kubunさんのが一番気になってたんだけど、AWS完全依存なのでうちでは使えないかなーという印象。(アプリによってAWSやそれ以外使い分けたりするし、費用安くするために別クラウドに移行ってのもたまにあるので)

AWSしか使わない(他クラウドに絶対移行しない)のであればむっちゃよさそう

弊社ブースについて

どっかでコミュニケーションロスがあって弊社の付箋が貼られた空っぽのブースがあるという事態に。。。

当日行って初めて自社ブースがあるのを知るという超恥ずかしい状態だったので次回以降なんか協賛するのであればちゃんと準備したいというのを社内でしてました

2日目

聞いたセッション

個人的に気になったのは2番目の「How DSL works on Ruby」。自分が今作ってるやつのヒントがあってよかった(DSLじゃないけど)

RubyKaraoke 2016

rubykaigikaraoke.doorkeeper.jp

弊社がスポンサーだったのでいろいろ手伝ってました

初のカラオケスポンサーということで目立ってた*1んですが、会社的には何もアピールできてなかったのが残念

3日目

聞いたセッション

前日(翌日朝まで)のカラオケが祟って昼過ぎに起きました('A`)

その他

そういえば会期中会った人から何回か先日のエントリについて聞かれることがありました

sue445.hatenablog.com

中には「日本語だけじゃもったいないから英語でも書いてほしい!」ってのを言われたのですが、なにぶん自分の英語が拙いのと自分が英語で書いてもそういう層にリーチしないという悩みが。(まあ英語でググってヒットするだけでも価値はありそうだけど)

英語で発信してくれる人、募集中です。

*1:ある意味ゴールドより目立ってたのでは?w

gemspecにRUBY_VERSIONによるif文書くのは意味がないので今すぐやめるべき

自戒です

tl;dr

  • gemspecの中でRubyのバージョンによってインストールしたいgemのバージョンを変えたい時は、gemspecではなくGemfileでif文書くのがおそらく正解

発端

先月くらいのFacebook内のちょっとした会話がきっかけでした *1

f:id:sue445:20160901233138p:plain

間違った対処法

f:id:sue445:20160901233158p:plain

  if Gem::Version.create(RUBY_VERSION) >= Gem::Version.create("2.2.2")
    spec.add_dependency "activesupport", ">= 4.0.0"
  else
    # NOTE: activesupport 5.x supports only ruby 2.2.2+
    spec.add_dependency "activesupport", ">= 4.0.0", "< 5.0.0"
  end

https://github.com/sue445/rubicure/blob/v0.4.7/rubicure.gemspec#L23-L28

gemspecでこんなif文を書いておけば、ruby 2.2.2未満の時はactivesupport 4系がインストールされる、、、












そんなふうに考えていた時期が俺にもありました

f:id:sue445:20160901234657p:plain

Travis CIのビルドの各Rubyのバージョンのログを見ても意図したバージョンがインストールされていたし、間違いなんてあるわけないと思っていました。

だがしかし

f:id:sue445:20160901233532p:plain

https://rubygems.org/gems/rubicure/versions/0.4.7 の表示、てっきり表示だけこうなってて gem install はいい感じに分岐してくれるのかと思ってた。。。

sonots先生曰く

f:id:sue445:20160901233846p:plain

rubygemsjruby と cruby (platform) で別々の gem をリリースすることはできるんですが、残念なことに cruby のバージョンで別々の gem をリリースすることはできないのですよねぇ


リリースする gem 自体の依存は緩くして、アプリ側の Gemfile であなたの rubyバージョンに合わせてactivesupport 絞ってね、というしかないのかなぁと思ってました。rubygems に機能が足りてないと思うんですよねぇ。


travis を通す時も、gemspec は緩くしておいて、Gemfile 二つ用意して、build matrix を頑張る

検証結果

f:id:sue445:20160901234124p:plain

ruby 2.1.9で上記gemspecの分岐が入ったrubicureのバージョンをインストールしようとすると、「activesupport requires Ruby version >= 2.2.2.」とエラーが出ているのが分かると思います

gist.github.com

上記エラーは rubygems.orgからのインストールログですが、geminaboxホスティングされた社内gemでも検証をしましたが同様の結果でした。

所感

  • add_dependencyadd_runtime_dependency )で書くruntime dependency(アプリの実行時に必要なgem)に関しては上記の理由で意味が無い
    • もしバージョンを絞りたい場合はgemspecではゆるくしておいてGemfileでバージョンを絞る
    • 必要ならドキュメントにもそれを明記する。*2
  • add_development_dependency で書くdevelopment dependency(gemの開発時に必要なgem)に関してはgem installでインストールされないため、if文を書いても意味なくはない
  • とはいえ、add_development_dependency はOKで add_dependency はNGというのは普通分からないし混在すると紛らわしいため、gemspecに RUBY_VERSION のif文は一切書かずに Gemfileに書くよう統一するのが今の自分の中では正解だと思ってます。(異論は認める)

Rubyのバージョンによる分岐を全部Gemfileに寄せた結果

こんな風になりました

source "https://rubygems.org"

# Specify your gem's dependencies in rubicure.gemspec
gemspec

if Gem::Version.create(RUBY_VERSION) < Gem::Version.create("2.1.0")
  # NOTE: build is failed when use ruby 2.0 and rspec-parameterized 0.3.0+
  #   https://travis-ci.org/sue445/rubicure/jobs/114266855
  gem "rspec-parameterized", "< 0.3.0"
end

if Gem::Version.create(RUBY_VERSION) < Gem::Version.create("2.1.0")
  # NOTE: unparser v0.2.5 drop support ruby < 2.1
  gem "unparser", "< 0.2.5"
end

if Gem::Version.create(RUBY_VERSION) < Gem::Version.create("2.2.2")
  # NOTE: activesupport 5.x supports only ruby 2.2.2+
  gem "activesupport", ">= 4.0.0", "< 5.0.0"
end

if Gem::Version.create(RUBY_VERSION) < Gem::Version.create("2.3.0")
  gem "backport_dig"
end

https://github.com/sue445/rubicure/blob/v0.4.9/Gemfile

rubicureもそろそろRuby 2.0系サポートきってもいいかなぁ。。。

謝辞

上記Facebookの会話の転載を快諾してくださった id:koic さんと id:sonots さん、ありがとうございます m(_ _)m

*1:FBキャプチャ転載に関しては事前にお二人の許可はとっています

*2: rubicureだとこんな感じ https://github.com/sue445/rubicure/blob/v0.4.9/README.md#installation

gitlab_mr_release v0.3.0をリリースした

gitlab_mr_releaseについて

こちらをご覧ください

github.com

sue445.hatenablog.com

v0.3.0の新機能

https://github.com/sue445/gitlab_mr_release/blob/master/CHANGELOG.md#v030

MR作成時にラベルを設定できるようになった

--labels でMR作成時のラベルを指定できるようになりました

gitlab_mr_release create --labels=release

ラベルをつけておけばGitLab上で絞り込みができるので使いやすくなるかと思います

f:id:sue445:20160818020754p:plain

ちなみに複数のラベルを設定したい場合は --labels=label1,label2 のようにカンマ区切りで渡してください

--source(MR作成元ブランチ)と --target(MR作成先ブランチ)を省略できるようになった

--source--target がない時に環境変数.env.gitlabDEFAULT_SOURCE_BRANCH, DEFAULT_TARGET_BRANCH を設定してあればそれが使われるようになります。

ちなみに前述の --labelsDEFAULT_LABELS で代替可能です。

最後に

gitlab_mr_releaseを使えばMRを元にいい感じにリリースノートを作成できて便利なので是非ご利用ください。(僕も社内アプリのリリースにgitlab_mr_releaseを積極的に使っています)

Wercker使っててClassic stackからWorkflowに移行した

以前構築していた Wercker のCI環境をClassic stack(古いCI環境)からworkflow(一番CI環境)に移行したのでメモ

前提

sue445.hatenablog.com

手順

Classic stackからDocker stackを経由してworkflowに移行します。一気にClassicからworkflowまでいけないこともないのですが、Classic stackとDocker stackの互換性がないのと、一度workflowにしたらClassicに戻せないので途中でDocker stackに移行するのがいいと思います

Classic stackからDocker stackに移行

Classic stack だとCI環境に Wercker Registry のboxを使いますが、Docker stackだとDockerのイメージを使うのでそのための移行です

wercker.ymlの差分はこんな感じ

-box: sue445/rvm-vagrant-digitalocean@1.1.1
 +box: drecom/centos-ruby:2.3.1

あとはbox内で行ってたVagrant周りのセットアップをスクリプトに移動してました。

Vagrant込のDockerfile作ってもよかったのですが、あまりオレオレイメージを作りたくなかったので既存のイメージを使う形にしました。(Vagrant本体とVagrantプラグインのインストールで20秒くらいだったのでまあ許容範囲かなと)

ハマったこと1. Vagrant の synced folderでエラーになるようになった

エラーの内容メモるの忘れたので詳しい状況は覚えてないですが、rsyncでエラーになるようになりました(使ってたイメージとの相性?)

調べても長引きそうだったし今回のケースだとローカルからsshごしにitamaeとserverspecを実行する関係でsynced folderは不要だったので無効化して逃げました。。。

     if ENV["WERCKER"] == "true"
+      override.vm.synced_folder ".", "/vagrant", disabled: true
       provider.ssh_key_name = "wercker-#{ENV['WERCKER_GIT_REPOSITORY']}"
       override.ssh.private_key_path = "~/.ssh/id_rsa.vagrant"
     else

ハマったこと2. Dockerの中でネストして bundle exec するとエラーになる

このissueと同じ現象でした

github.com

自分の場合 bundle exec rake itamae:$HOST の中で

sh "bundle exec itamae ssh --host=#{host} --vagrant --node-yaml=recipes/node.yml recipes/install.rb"

のようなrake taskを実行するとvagrantが見つからないみたいなエラーになったので、bundle exec の中で bundle exec を呼ばないようにしました

-      sh "bundle exec itamae ssh --host=#{host} --vagrant --node-yaml=recipes/node.yml recipes/install.rb"
 +      sh "itamae ssh --host=#{host} --vagrant --node-yaml=recipes/node.yml recipes/install.rb"

この時点の差分

https://github.com/sue445/itamae-plugin-resource-encrypted_remote_file/pull/7/files

stackを切り替える

Settings -> Options -> Infrastructure stack よりプルダウンを切り替えてSwitch。

f:id:sue445:20160802015207p:plain

ボタン押すだけなら何か合ってもまだClassicに戻ってこれます

修正をpushする

stackを切り替えた後に修正したやつをpushしないと正常にビルドされないので注意

Docker stackからworkflowに移行

メールフォームから随時申請します

Docker stackを有効にすると上の方にWorkflowsって出てるのでそれをクリック

f:id:sue445:20160802020307p:plain

Request this app to be migrated to workflows のボタンをクリック

f:id:sue445:20160802020405p:plain

メールフォームから申請

UserIDとApplicationIDは入力済みの状態なのであとはメールアドレスを入れるだけ(任意)

f:id:sue445:20160802020613p:plain

メール送ってからWorkflowに移行されるまでに4〜5日くらいかかりました

メールフォームでメールアドレスを書いておけば移行後にメールが送られてくるのですが、メールの文面だけだとどのアプリに対して移行が完了したのか分かりません。

f:id:sue445:20160802020903p:plain

1つだけ申請してるのであればいいのですが、自分の場合5つくらい同時に移行依頼出したのでgmailエイリアスで区別できるようにしました

www.ajaxtower.jp

が、エイリアスつけたメアドには移行完了メールが届かなかったのでダメかもしれない。*1

Workflowの設定

Settings -> Workflow

Pipeline

最初に下の方のPipelineを追加します

f:id:sue445:20160811002149p:plain

YML Pipeline nameがymlのkeyの名前でNameがWerckerで実際に表示される名前(werckerのビルドURLにも使われる)。特にこだわりがなければ両方同じでいいと思います

f:id:sue445:20160811002324p:plain

追加後に Report to SCM にチェックを入れないとPullRequestでビルドステータスが出ません

f:id:sue445:20160811002452p:plain

こういうの

f:id:sue445:20160811002614p:plain

Workflow

[+] の部分をクリックしてポチポチ登録します f:id:sue445:20160811002700p:plain

全てのブランチでビルド実行したければ * でいいと思います。(デプロイだとmaster指定とかになりそう)

f:id:sue445:20160811002819p:plain

Workflowの特徴

  • Workflow内のPipelineがそれぞれ完全に1つのDockerコンテナとして独立している
    • 各Pipelineの冒頭で docker pull してる
    • 1つ目のPipelineでbundle installしてキャッシュを作り、2つ目のPipelineでそのgemを使ってテストを実行というのはできない
    • Pipeline間でステータスを引き継がせる方法はなさそう
  • ymlのマージ機能*2 が使えるので、stepの共通化ができます
default: &default
    after-steps:
        - script:
            name: set variables
            code: |
                # NOTE: override .ruby-version in pretty-slack-notify
                export RBENV_VERSION=2.3.1
        - script:
            name: remove all vms
            code: vagrant destroy -f

        - wantedly/pretty-slack-notify:
            webhook_url: $SLACK_WEBHOOK_URL
            username: wercker_build

build-centos70:
    <<: *default  # 上で定義したafter-stepsが使えるようになる
    steps:
        - script:
            name: setup
            code: ./ci/setup.sh

        - bundle-install:
            jobs: 4

        - script:
            name: build CentOS 7.0
            code: ./ci/build.sh centos70

build-debian8:
    <<: *default  # 上で定義したafter-stepsが使えるようになる
    steps:
        - script:
            name: setup
            code: ./ci/setup.sh

        - bundle-install:
            jobs: 4

        - script:
            name: build Debian 8
            code: ./ci/build.sh debian8

Workflowのメリット

ビルド結果が見やすいってのがあります

それぞれのpipelineのコンソールログが完全に分かれているのでビルドが失敗してもログから調査しやすいです

また、ビルドが失敗した時に任意のpipelineをリトライできるってのも地味に嬉しい

たまたま build-debian8 だけ調子悪くてビルドがこけたので再実行した図

f:id:sue445:20160811003409p:plain

Workflowのデメリット

  • Pipelineの依存関係をウェブでポチる必要があるのが難点
    • GUIで操作できるのは見やすいんですが、個人的にはwercker.ymlで完結してほしかった感はある
  • Pipelineの枝分かれができるのは便利だが、合流することができない
    • 例:枝分かれしたPIpelineが全部終わった時に通知用のPipelineを1つだけ実行

上記デメリットを解消できるという点では個人的には GitLab CIが一番理想に近いと思ってます

tech.drecom.co.jp

まとめ

Dockerfile用意すれば自分の好きな環境を使ってビルドできるし、Travis CIやCircle CIと違って複雑なビルドが書けるのでWercker割とおすすめです

おまけ

移行対象のリポジトリが多すぎて Trello進捗管理していました。便利

f:id:sue445:20160810084301p:plain

1つだけ移行不要にしているのは https://github.com/sue445/wercker-box-rvm-vagrant-digitalocean の動作確認用です

*1:単に一度に申請したのが多すぎただけ説ある

*2: http://magazine.rubyist.net/?0012-YAML#l17

【今月のgem】activerecord-compatible_legacy_migration というgemを作った

github.com

どんなgemか

同一のmigrationファイルでRails 4.2系とRails 5.0系の両方でいい感じに動くようにするためのgemです

これだけだと分かりづらいので具体例を出します

Rails 4.2系から5.0系へのmigrationファイルの移行について

Rails 4.2系から5.0系に移行する時に、Rails 4.2で作られた既存のmigrationのスーパークラスを下記のように ActiveRecord::Migration から ActiveRecord::Migration[4.2] にします

Rails 4時代のmigration

class CreateUsers < ActiveRecord::Migration
  def change
    create_table :users do |t|
      t.timestamps null: false
    end
  end
end

Rails 5移行後のmigration

class CreateUsers < ActiveRecord::Migration[4.2]
  def change
    create_table :users do |t|
      t.timestamps null: false
    end
  end
end

ActiveRecord::Migration のままでもエラーにはなりませんがログファイルに下記のようなDEPRECATION WARNINGが出ます *1

DEPRECATION WARNING: Directly inheriting from ActiveRecord::Migration is deprecated. Please specify the Rails release the migration was written for:

class CreateUsers < ActiveRecord::Migration[4.2]

ユースケース

アプリであればmigrationファイルを上記のように修正すればいいのですが、moutable engineのようにgemの中に内包されてるmigrationファイルをアプリの db/migrate/ にコピーするgemだとそうはいきません。

  • gem内のmigrationファイルが ActiveRecord::Migration の場合
    • アプリでRails 4.2系を使ってる時は問題なし
    • アプリでRails 5.0系を使ってる時にDEPRECATION WARNINGが出る
      • 動きはするけど、5.1辺りで使えなくなる可能性もあるのでできれば放置はしたくない
      • とはいえgem開発者的にはなるべく多くのバージョンに対応しておきたい
      • アプリでmigrationファイルを修正後にgemのmigration installコマンドをたたいた時にgem側のmigratonファイルとアプリ側のmigratonファイルで差分があると「変更されてるけど上書きしますか?」的な確認が大量にでそう(自信ない)
  • gem内のmigrationファイルが ActiveRecord::Migration[4.2] の場合
    • アプリでRails 5.0系を使ってる時は問題なし
    • アプリでRails 4.2系を使ってる時にはエラーになる

migrationファイルを内包したgemをいくつかメンテしているのですが、Rails 5対応をするために既存のRails 4系のアプリともmigrationファイルの互換性を保つのが割とつらかったのでそれを解決するために作りました

使い方

migrationクラスのスーパークラスActiveRecord::CompatibleLegacyMigration.migration_class にするだけです

class CreateUsers < ActiveRecord::CompatibleLegacyMigration.migration_class
  def change
    create_table :users do |t|
      t.timestamps null: false
    end
  end
end

ActiveRecord::CompatibleLegacyMigration.migration_classRails 5.0以降だと ActiveRecord::Migration[4.2] を、Rails 5未満だと ActiveRecord::Migration を返します

https://github.com/sue445/activerecord-compatible_legacy_migration/blob/v0.1.0/lib/active_record/compatible_legacy_migration.rb

Rails 5.0以降でしか使えないmigrationファイルはgemとして配布する時に ActiveRecord::Migration[5.0] つければいいと思います

おまけ

他のgemはどうやってRails 5対応やってるんだろうなぁと思って試しに devise を見たら [5.0] の部分をerbで埋め込んでた

gemごとに個別対応するの、つらみある。。。

最後に

gemでmigrationファイルを配布していてRails 4.2系とRails 5.0系を両方メンテする必要が出てきたら是非ご利用ください

*1:コンソールには出ないので注意