くりにっき

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

「GitHubのPull Requestを簡単にチェックアウトするたった1つの方法」のaliasを作った

元ネタ

sinsoku.hatenablog.com

便利なんですがコマンド長すぎて覚えられないのでaliasにしました

.gitconfig

[alias]
  fpr = "!f() { git fetch origin pull/$1/head:pr/$1; }; f"

コマンド名が気になる人は適宜変えてください

使い方

git fpr <PullRequest ID>

pr/<PullRequest ID> にbranchが作られます

使った図

[sueyoshi_go@YG41-08546.local] ✓ ~/workspace/github.com/sue445/chrome-gitlab-notifier (master)
[sueyoshi_go@YG41-08546.local] [03-31 16:01:18] $ g fpr 83
remote: Counting objects: 14, done.
remote: Compressing objects: 100% (14/14), done.
remote: Total 14 (delta 4), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (14/14), done.
From github.com:sue445/chrome-gitlab-notifier
 * [new ref]         refs/pull/83/head -> pr/83

[sueyoshi_go@YG41-08546.local] ✓ ~/workspace/github.com/sue445/chrome-gitlab-notifier (master)
[sueyoshi_go@YG41-08546.local] [03-31 16:02:18] $ g co pr/83
Switched to branch 'pr/83'

[sueyoshi_go@YG41-08546.local] ✓ ~/workspace/github.com/sue445/chrome-gitlab-notifier (pr/83)
[sueyoshi_go@YG41-08546.local] [03-31 16:02:46] $

【おまけ】.gitconfig の aliasで登録したコマンドから引数を取得する方法

直接 $1 って書くとうまく動かなかったので調べたら関数の中に入れる必要があるっぽい

stackoverflow.com

プリキュアオールスターズを見たのでrubicureでキュアエコー対応した

こんにちは、映画プリキュアオールスターズ みんなで歌う♪奇跡の魔法! の映画公開2日目ですが既に2回見てきました。

www.precure-allstars.com

いろいろ思うところがあってキュアエコー対応を行いました

github.com

きっかけ

prehyou2015.hatenablog.com

プリキュアの数字ブログさんの

2016年3月現在では

「44人のプリキュアがいる」

というのが教科書的な答えです。

を読んでrubicureも対応しないといけないような使命感に駆られて対応しました

使い方

Cure.echo

いつものように Cure.echo でキュアエコーのインスタンスを取得できます

echo = Cure.echo

echo.name
# => "坂上あゆみ"

echo.transform!
みんなの思いを守るために
心をひとつに!
思いよ届け!キュアエコー!

# 変身後なので名前が変わる
echo.name
# => "キュアエコー"

echo.attack!
世界に響け、みんなの思い!
プリキュア・ハートフルエコー!

Precure.all_stars

通常はプリキュアオールスターズは43人です

Precure.all_stars.count
# => 43

キュアエコーは特定の映画 *1の中だけに登場するので、Precure.all_stars の引数にその映画の名前を渡せばカウントすることができます

Precure.all_stars(:sing_together_miracle_magic).count
# => 44
Precure.all_stars(:sing_together_miracle_magic).include?(Cure.echo)
# => true

ちなみに :sing_together_miracle_magic は、公式略称のSTMMから推測したものなので間違ってたら直します。。。

他に :new_stage:new_stage3でもキュアエコーは取得できます

Precure.all_stars(:new_stage).count
# => 29
Precure.all_stars(:new_stage).include?(Cure.echo)
# => true

Precure.all_stars(:new_stage3).count
# => 37
Precure.all_stars(:new_stage3).include?(Cure.echo)
# => true

Precure.all_stars の引数に渡せる映画の名称はいろいろエイリアスがあるので詳細はソースを読んでください

https://github.com/sue445/rubicure/blob/v0.4.3/config/movies.yml

映画感想

ネタバレにならない程度に

*1:オールスターズNewStage みらいのともだち、オールスターズNewStage3 永遠のともだち、オールスターズみんなで歌う♪奇跡の魔法!

rubicure v0.4.0をリリースしました

魔法つかいプリキュア! 対応です

github.com

まほプリの仕様上今までとちょっと使い方が変わってるので注意してください

今までのプリキュア

yayoi = Cure.peace

yayoi.name
#=> "黄瀬やよい"

yayoi.cast_name
#=> "金元寿子"

yayoi.attack!
#=> RuntimeError: require transform


yayoi.transform!

(レディ?)
プリキュア・スマイルチャージ!
(ゴー!ゴー!レッツ・ゴー!ピース!!)
ピカピカピカリンジャンケンポン! キュアピース!
5つの光が導く未来!
輝け!スマイルプリキュア!

# 1st transform
yayoi.name
#=> "キュアピース"

yayoi.attack!

プリキュア!ピースサンダー!!

魔法つかいプリキュア

各種スタイルに対応すべく、Rubicure::Girl#transform! に引数を渡せるようになっています

ダイヤスタイルに変身する時

mirai = Cure.miracle

mirai.name
# => "朝日奈みらい"

mirai.cure_up_rapapa! :diamond
# or
mirai.transform! :diamond

キュアップ・ラパパ! ダイヤ!
ミラクル・マジカル・ジュエリーレ!
ふたりの奇跡!キュアミラクル!
魔法つかいプリキュア!!

mirai.name
# => "キュアミラクル(ダイヤスタイル)"

mirai.attack!
リンクルステッキ!
ダイヤ!永遠の輝きを私達の手に!
フルフルリンクル!
プリキュア!ダイヤモンドエターナル!

Ruby ルビースタイルに変身する時

mirai = Cure.miracle

mirai.name
# => "朝日奈みらい"

mirai.cure_up_rapapa! :ruby
# or
mirai.transform! :ruby

キュアップ・ラパパ! ルビー!
ミラクル・マジカル・ジュエリーレ!
ふたりの奇跡!キュアミラクル!
魔法つかいプリキュア!!

mirai.name
# => "キュアミラクル(ルビースタイル)"

mirai.attack!
リンクルステッキ!
ルビー!紅の情熱よ私達の手に!
フルフルリンクル!
プリキュア!ルビーパッショナーレ!

Splash☆Star の Cure.bloomCure.bright みたいにそれぞれのスタイルを別名で定義というのは今までもありましたが、同名で複数のスタイルを対応というのが今回の一番の目玉です!

それではよいキュアエンジニアライフを

追伸

yamlのデータ構造がつらくなってきた・・・

https://github.com/sue445/rubicure/blob/v0.4.0/config/girls/013_maho_girls.yml

heroku-buildpack-rroonga で突然エラーが出た時の対処法

忙しい人のためのまとめ

heroku-buildpack-rroongaの設定が変わってた

経緯

Tachikoma.io を使って Sebastian-badge.info を毎週 bundle update しているのですが、2/21のビルドは問題なかったのに2/28のビルド以降Circle CIの自動デプロイに失敗するという事象がありました。

remote: -----> Fetching set buildpack https://github.com/groonga/heroku-buildpack-rroonga... done
remote: -----> Rroonga app detected
remote: -----> Initializing database
remote: bundle exec ruby groonga/init.rb
remote: /app/vendor/bundle/ruby/2.3.0/gems/bundler-1.9.7/lib/bundler/spec_set.rb:92:in `block in materialize': Could not find rake-10.5.0 in any of the sources (Bundler::GemNotFound)
remote:     from /app/vendor/bundle/ruby/2.3.0/gems/bundler-1.9.7/lib/bundler/spec_set.rb:85:in `map!'
remote:     from /app/vendor/bundle/ruby/2.3.0/gems/bundler-1.9.7/lib/bundler/spec_set.rb:85:in `materialize'
remote:     from /app/vendor/bundle/ruby/2.3.0/gems/bundler-1.9.7/lib/bundler/definition.rb:132:in `specs'
remote:     from /app/vendor/bundle/ruby/2.3.0/gems/bundler-1.9.7/lib/bundler/definition.rb:177:in `specs_for'
remote:     from /app/vendor/bundle/ruby/2.3.0/gems/bundler-1.9.7/lib/bundler/definition.rb:166:in `requested_specs'
remote:     from /app/vendor/bundle/ruby/2.3.0/gems/bundler-1.9.7/lib/bundler/environment.rb:18:in `requested_specs'
remote:     from /app/vendor/bundle/ruby/2.3.0/gems/bundler-1.9.7/lib/bundler/runtime.rb:13:in `setup'
remote:     from /app/vendor/bundle/ruby/2.3.0/gems/bundler-1.9.7/lib/bundler.rb:122:in `setup'
remote:     from /app/vendor/bundle/ruby/2.3.0/gems/bundler-1.9.7/lib/bundler/setup.rb:18:in `<top (required)>'
remote:     from /app/vendor/ruby-2.3.0/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
remote:     from /app/vendor/ruby-2.3.0/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
remote: 
remote:  !     Push rejected, failed to compile Rroonga app

https://circleci.com/gh/sue445/sebastian-badge/269

bundle install されてないだと・・・!?

いろいろ調べてたら2/23に入ってた heroku-buildpack-rroonga の変更が原因でした

https://github.com/groonga/heroku-buildpack-rroonga/commit/11af6d1bb0bf83210b7ca9129e171fd04c5b5158

対処法

Circle CIを使ってるので circle.ymlの修正を載せますが他のCIでもやることはだいたい同じだと思います

修正前

deployment:
  production:
    commands:
      - heroku config:add BUILDPACK_URL="https://github.com/groonga/heroku-buildpack-rroonga" --app $HEROKU_APP_NAME

https://github.com/sue445/sebastian-badge/blob/aaf35ea8c02a99d57fbc18fe7ef49097258084d5/circle.yml#L37

修正後

READMEの通りにbuildpackを設定しなおしてやるだけ

deployment:
  production:
    commands:
      - heroku buildpacks:add https://codon-buildpacks.s3.amazonaws.com/buildpacks/groonga/groonga.tgz --app $HEROKU_APP_NAME || true
      - heroku buildpacks:add heroku/ruby --app $HEROKU_APP_NAME || true
      - heroku buildpacks:add https://codon-buildpacks.s3.amazonaws.com/buildpacks/groonga/rroonga.tgz --app $HEROKU_APP_NAME || true

https://github.com/sue445/sebastian-badge/blob/040eb9a298ce06cf2648ccd1d8f2bdeea1ed6ccf/circle.yml#L37-L39

heroku buildpack:add 〜" の後に || trueをつけているのは、既にbuildpack追加済みの状態でbuildpacks:add` するとステータスコード1になりデプロイが途中で止まるのを回避するため。

heroku buildpacks:add https://codon-buildpacks.s3.amazonaws.com/buildpacks/groonga/groonga.tgz --app $HEROKU_APP_NAME
 ▸    The buildpack
 ▸    https://codon-buildpacks.s3.amazonaws.com/buildpacks/groonga/groonga.tgz

heroku buildpacks:add https://codon-buildpacks.s3.amazonaws.com/buildpacks/groonga/groonga.tgz --app $HEROKU_APP_NAME returned exit code 1

▸ is already set on your app. Action failed: heroku buildpacks:add https://codon-buildpacks.s3.amazonaws.com/buildpacks/groonga/groonga.tgz --app $HEROKU_APP_NAME

https://circleci.com/gh/sue445/sebastian-badge/271

【今月のgem】itamae-plugin-recipe-tmux を作った

俺得itamaeプラグイン第n弾です

tmuxをpackageを使わずにソースからビルドするプラグインを作りました *1

github.com

作った経緯とか

tmuxなんて普通にパッケージからインストールすればいいのでは思いますが

  • 本番環境などでシステムに余計なミドルをインストールしたくないこともある
    • homeにtmuxをインストールしていればautohomeが効いていれば複数のサーバで使える
  • tmuxのビルドの前にlibeventやncursesもビルドして、tmux のビルド時にincludeやlibも指定する必要があって地味にビルドが面倒

というわけでレシピにしました

ビルド方法はこちらを参考にしています

minomawari.jp

使い方

レシピの中でこういう風に書くだけです

# recipe.rb
include_recipe "tmux"

設定はこんな感じ

# node.yml
tmux:
  # tmux prefix (default: /home/<username>/local)
  prefix: /usr/local

  # install version (default: 2.1)
  version: 2.1

libevent:
  # install version (default: 2.0.22)
  version: 2.0.22

ncurses:
  # install version (default: 6.0)
  version: 6.0

homeにtmuxをインストールした場合は .bash_profile 辺りに

export $PATH=$PATH:$HOME/local/bin

を書けばPATHが通ります

*1:「今月のgem」とかいいつつ先月は作ってなかったな。。。

Gitlab Merge Request Builder Plugin で Could not merge が出た時の対処法

tl;dr

Jenkins上でマージするのを諦めよう

github.com

使ってるバージョン

  • Jenkins v1.643
  • Gitlab Merge Request Builder Plugin v2.0.0
  • Git client plugin v1.19.1
  • Git plugin v2.4.1

エラー詳細

こんな感じのエラーです

19:58:57  > git rev-parse origin/develop^{commit} # timeout=10
19:58:57  > git config core.sparsecheckout # timeout=10
19:58:57  > git checkout -f origin/develop
19:58:57  > git merge -s recursive --no-ff 70659b22c6503833c8d3f71b7754dd3e16e2d71e # timeout=10
19:58:57  > git config core.sparsecheckout # timeout=10
19:58:57  > git checkout -f 70659b22c6503833c8d3f71b7754dd3e16e2d71e
19:58:57 ERROR: Branch not suitable for integration as it does not merge cleanly: Could not merge AnyObjectId[70659b22c6503833c8d3f71b7754dd3e16e2d71e]
19:58:57 Finished: FAILURE

大した差分でもないしGitLab上でもコンフリクト起こしていないしアクセプトボタンも押せる状態なのに、なぜかJenkins上でマージできずにエラーになるということがたまにありました

2年くらい使ってる自分の経験則では

  • fast forwardでマージできる場合にはエラーは起きないが、fast forwardでマージできない場合にエラーになる
  • MergeRequestのsource branch(送り元のトピックブランチ)とtarget branch(送り先のブランチ)の差分が大きいとエラーになりやすい

という感じでした。

Git flowを使っている場合に、リリースブランチからdevelopブランチへのマージ*1は問題ないのに、masterブランチへのマージ*2でエラーになるのでなかなか厳しいものがありました。(つらい)

f:id:sue445:20160202234130p:plain

エラーが発生してる場所

Jenkinsのコンソールログだけだと特定しづらかったですが、JGitでのマージに失敗してるようでした。 https://github.com/jenkinsci/git-plugin/blob/git-2.4.2/src/main/java/hudson/plugins/git/extensions/impl/PreBuildMerge.java#L76

そりゃJenkinsサーバのgitのバージョンを上げても直らないわけだ。。。

設定をいろいろいじった

f:id:sue445:20160202232135p:plain

思いっきし「This feature is not fully implemented in JGIT.(この機能はJGITでは完全にサポートされていない)」って書いてるなw

f:id:sue445:20160202232138p:plain

Fast-forward modeを --no-ff にした状態でMerge strategyは全種類試しましたが解決しませんでした。。。

対処法

Additional Behavioursを消した

Before

Gitlab Merge Request Builder Pluginのドキュメントに書いてる設定 f:id:sue445:20160202232925p:plain

After

修正後

f:id:sue445:20160202232953p:plain

Merge before buildを削除。要はsource branchをtarget branchにマージした状態でテストするのではなく、source branch自体をテストするというわけです

「マージした状態でビルドしなくて大丈夫か?」とも思うかもしれませんが、

  • 差分がでかい時にマージエラーが起きるくらいならマージしないでビルドしたい
  • ビルドに時間がかかるとrebaseしてビルドし直すコストが高い *3
  • マージした先のdevelopブランチやmasterブランチもJenkinsでビルドをしている *4

と判断で外しました。

ちなみに同プラグインGitHub版の GitHub pull request builder plugin だと ${sha1} (マージしない状態のPullRequestのコミットID)でテストをしていました

しばらく運用してみた

上記設定で1週間くらい運用してみました

ビルドスクリプトを修正してmasterにコミットした時にトピックブランチ側が古い状態でビルドしてエラーになることがありましたが、それ以外はそれなりに快適にやってます。まぁその辺はトレードオフなんじゃないかと。

*1:差分はCHANGELOGくらい

*2:developに比べたら差分はたくさんある

*3:今メインで開発してるアプリだと1ビルド10分前後

*4:MergeRequestをビルドしているような人がmasterブランチをビルドしないわけないw