最近こっちの更新が滞っておりますがsue445 Advent Calendarは絶賛更新中です。
当日記には下記アドベントカレンダーを投稿予定なのでよろしくお願いします。
Qiitaや会社ブログにはエントリ書いてたけどこっちのブログは1ヶ月間更新無しとかマジか。(挨拶)
先日自分がメンテしてるJenkinsプラグインにPRがきて「よっしゃ!マージしてリリースするぜ!」と思っていつものリリースコマンド *1 をたたいたらリリース時に謎のエラーがおきて途方に暮れていた時の出来事です。
日本語だと今回の事象が見つからなかったので日本語でメモ残しておきます
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
この修正でプラグインをリリースすることができました
Betamaxというのはhttp通信をモック化するGroovy製のライブラリです。自分のプラグインだとGitLabの通信部分をスタブにするために使っていました
上記PRでbetamaxを消した理由をメモ
keytool -importcert 〜
でbetamaxの鍵を追加すると動くようになるよ」って書いてあるってことでbetamaxを捨てて昔ながらにStubクラスからテスト対象のクラスを継承してテストするようにしました
*1:mvn release:prepare release:perform
RubyKaigi 2016 に参加してたのですが、最近までISUCON予選あったり自分がメインで関わってるアプリのリリースとかあったりで今更振り返りです
知り合い何人かとairbnbで宿をとってたんだけど(宿主の名前をとって通称モリタハウス)、ホストから当日朝にドタキャン喰らった。FBのモリタハウス連絡部屋が朝からハチャメチャ大混乱
詳細
聞いたセッション
最後のk0kubunさんのが一番気になってたんだけど、AWS完全依存なのでうちでは使えないかなーという印象。(アプリによってAWSやそれ以外使い分けたりするし、費用安くするために別クラウドに移行ってのもたまにあるので)
AWSしか使わない(他クラウドに絶対移行しない)のであればむっちゃよさそう
どっかでコミュニケーションロスがあって弊社の付箋が貼られた空っぽのブースがあるという事態に。。。
弊社ブースの様子です #rubykaigi pic.twitter.com/NBZJTYUMd6
— sue445 (@sue445) 2016年9月8日
当日行って初めて自社ブースがあるのを知るという超恥ずかしい状態だったので次回以降なんか協賛するのであればちゃんと準備したいというのを社内でしてました
聞いたセッション
個人的に気になったのは2番目の「How DSL works on Ruby」。自分が今作ってるやつのヒントがあってよかった(DSLじゃないけど)
rubykaigikaraoke.doorkeeper.jp
弊社がスポンサーだったのでいろいろ手伝ってました
初のカラオケスポンサーということで目立ってた*1んですが、会社的には何もアピールできてなかったのが残念
聞いたセッション
前日(翌日朝まで)のカラオケが祟って昼過ぎに起きました('A`)
そういえば会期中会った人から何回か先日のエントリについて聞かれることがありました
中には「日本語だけじゃもったいないから英語でも書いてほしい!」ってのを言われたのですが、なにぶん自分の英語が拙いのと自分が英語で書いてもそういう層にリーチしないという悩みが。(まあ英語でググってヒットするだけでも価値はありそうだけど)
英語で発信してくれる人、募集中です。
*1:ある意味ゴールドより目立ってたのでは?w
自戒です
先月くらいのFacebook内のちょっとした会話がきっかけでした *1
gem install
や bundle install
しようとすると5系をインストールしようとして、バージョンが古いって怒られる
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系がインストールされる、、、
Travis CIのビルドの各Rubyのバージョンのログを見ても意図したバージョンがインストールされていたし、間違いなんてあるわけないと思っていました。
https://rubygems.org/gems/rubicure/versions/0.4.7 の表示、てっきり表示だけこうなってて gem install
はいい感じに分岐してくれるのかと思ってた。。。
rubygems は jruby と cruby (platform) で別々の gem をリリースすることはできるんですが、残念なことに cruby のバージョンで別々の gem をリリースすることはできないのですよねぇ
リリースする gem 自体の依存は緩くして、アプリ側の Gemfile であなたの rubyバージョンに合わせてactivesupport 絞ってね、というしかないのかなぁと思ってました。rubygems に機能が足りてないと思うんですよねぇ。
travis を通す時も、gemspec は緩くしておいて、Gemfile 二つ用意して、build matrix を頑張る
ruby 2.1.9で上記gemspecの分岐が入ったrubicureのバージョンをインストールしようとすると、「activesupport requires Ruby version >= 2.2.2.」とエラーが出ているのが分かると思います
上記エラーは rubygems.orgからのインストールログですが、geminabox にホスティングされた社内gemでも検証をしましたが同様の結果でした。
add_dependency
( add_runtime_dependency
)で書くruntime dependency(アプリの実行時に必要なgem)に関しては上記の理由で意味が無い
add_development_dependency
で書くdevelopment dependency(gemの開発時に必要なgem)に関してはgem installでインストールされないため、if文を書いても意味なくはないadd_development_dependency
はOKで add_dependency
はNGというのは普通分からないし混在すると紛らわしいため、gemspecに RUBY_VERSION
のif文は一切書かずに 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 (0.3.0): Release MergeRequest generator for GitLab https://t.co/rRcImQNmkB
— RubyGems (@rubygems) 2016年8月17日
こちらをご覧ください
https://github.com/sue445/gitlab_mr_release/blob/master/CHANGELOG.md#v030
--labels
でMR作成時のラベルを指定できるようになりました
gitlab_mr_release create --labels=release
ラベルをつけておけばGitLab上で絞り込みができるので使いやすくなるかと思います
ちなみに複数のラベルを設定したい場合は --labels=label1,label2
のようにカンマ区切りで渡してください
--source
や --target
がない時に環境変数か .env.gitlab
に DEFAULT_SOURCE_BRANCH
, DEFAULT_TARGET_BRANCH
を設定してあればそれが使われるようになります。
ちなみに前述の --labels
も DEFAULT_LABELS
で代替可能です。
gitlab_mr_releaseを使えばMRを元にいい感じにリリースノートを作成できて便利なので是非ご利用ください。(僕も社内アプリのリリースにgitlab_mr_releaseを積極的に使っています)
以前構築していた Wercker のCI環境をClassic stack(古いCI環境)からworkflow(一番CI環境)に移行したのでメモ
Classic stackからDocker stackを経由してworkflowに移行します。一気にClassicからworkflowまでいけないこともないのですが、Classic stackとDocker stackの互換性がないのと、一度workflowにしたらClassicに戻せないので途中で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秒くらいだったのでまあ許容範囲かなと)
エラーの内容メモるの忘れたので詳しい状況は覚えてないですが、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
このissueと同じ現象でした
自分の場合 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
Settings -> Options -> Infrastructure stack よりプルダウンを切り替えてSwitch。
ボタン押すだけなら何か合ってもまだClassicに戻ってこれます
stackを切り替えた後に修正したやつをpushしないと正常にビルドされないので注意
メールフォームから随時申請します
UserIDとApplicationIDは入力済みの状態なのであとはメールアドレスを入れるだけ(任意)
メール送ってからWorkflowに移行されるまでに4〜5日くらいかかりました
メールフォームでメールアドレスを書いておけば移行後にメールが送られてくるのですが、メールの文面だけだとどのアプリに対して移行が完了したのか分かりません。
1つだけ申請してるのであればいいのですが、自分の場合5つくらい同時に移行依頼出したのでgmailのエイリアスで区別できるようにしました
が、エイリアスつけたメアドには移行完了メールが届かなかったのでダメかもしれない。*1
Settings -> Workflow
最初に下の方のPipelineを追加します
YML Pipeline nameがymlのkeyの名前でNameがWerckerで実際に表示される名前(werckerのビルドURLにも使われる)。特にこだわりがなければ両方同じでいいと思います
追加後に Report to SCM にチェックを入れないとPullRequestでビルドステータスが出ません
こういうの
[+] の部分をクリックしてポチポチ登録します
全てのブランチでビルド実行したければ *
でいいと思います。(デプロイだとmaster指定とかになりそう)
docker pull
してる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
ビルド結果が見やすいってのがあります
それぞれのpipelineのコンソールログが完全に分かれているのでビルドが失敗してもログから調査しやすいです
また、ビルドが失敗した時に任意のpipelineをリトライできるってのも地味に嬉しい
たまたま build-debian8 だけ調子悪くてビルドがこけたので再実行した図
上記デメリットを解消できるという点では個人的には GitLab CIが一番理想に近いと思ってます
Dockerfile用意すれば自分の好きな環境を使ってビルドできるし、Travis CIやCircle CIと違って複雑なビルドが書けるのでWercker割とおすすめです
移行対象のリポジトリが多すぎて Trello で進捗管理していました。便利
1つだけ移行不要にしているのは https://github.com/sue445/wercker-box-rvm-vagrant-digitalocean の動作確認用です
*1:単に一度に申請したのが多すぎただけ説ある
activerecord-compatible_legacy_migration (0.1.0): Compatible migration file between Rails 4.2 and 5+ https://t.co/k14u4ZXuHt
— RubyGems (@rubygems) August 4, 2016
同一のmigrationファイルでRails 4.2系とRails 5.0系の両方でいい感じに動くようにするためのgemです
これだけだと分かりづらいので具体例を出します
Rails 4.2系から5.0系に移行する時に、Rails 4.2で作られた既存のmigrationのスーパークラスを下記のように ActiveRecord::Migration
から ActiveRecord::Migration[4.2]
にします
class CreateUsers < ActiveRecord::Migration def change create_table :users do |t| t.timestamps null: false end end end
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だとそうはいきません。
ActiveRecord::Migration
の場合
ActiveRecord::Migration[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_class
はRails 5.0以降だと ActiveRecord::Migration[4.2]
を、Rails 5未満だと ActiveRecord::Migration
を返します
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:コンソールには出ないので注意