おもしろwebサービス開発日記

Ruby や Rails を中心に、web技術について書いています

Rails Developers Meetup 2018でモデレーターをした

Rails Developers Meetup 2018の最後のセッション「基調Q&A」でモデレーターをしてきました。

事前に皆さんから集めたお便りとビールを元に、日本が誇るRailsコミッターたちにいろいろ話してもらいました。40分があっという間に過ぎた感じでしたね。前回のぎんざRuby会議の基調Q&A同様、楽しい時間になりました。

他の発表も面白いものがたくさんで充実した二日間でした。Railsを使っている人や企業が実際にどう開発を進めているのか、何に苦労しているか、何を頑張っているのかの実例をたくさん聞いてモチベーションが高まると同時に、自分の向いている方向は間違ってないのだな、と勇気づけられました。

最近時間がなかったので登壇や勉強会の参加などを控えてたのですが、なんだかんだあり結局フルで参加><。でも参加した以上の価値があったなと思います。

次は時間を作ってなにか喋ろうと思うのでよろしくお願いします (\( ⁰⊖⁰)/)

定期的にyarn updateするには

ライブラリは定期的かつこまめにアップデートすることで辛さを減らしていく、というのは最近の開発現場では定説ではないかと思います。Railsプロジェクトの場合、Gemfileの定期更新を実施している現場も多いのではないでしょうか*1

最近のRailsアプリケーションはjsライブラリの管理にyarnを使っているところが多いかと思いますが、これもGemfileと同じように定期的にアップデートしたいところです。

商用のものもいくつかありますが、僕は普段使っているCiecleCIを活用して定期的にyarn updateしています。

使っているツールはこちら。CiecleCIに限定されているわけではないので、定期実行できる環境さえあればどこでも活用できると思います。

taichi/ci-yarn-upgrade: Keep NPM dependencies up-to-date with CI, providing version-to-version diff for each library

設定の仕方

CiecleCIの設定は次のような感じでやっておきます*2

version: 2
jobs:
  yarn-update:
    docker:
      - image: circleci/ruby:2.5.0-node-browsers
    steps:
      - checkout
      - run: sudo sh -c 'echo "deb http://ftp.us.debian.org/debian testing main contrib non-free" >> /etc/apt/sources.list'
      - run: sudo apt-get update
      - run: sudo apt-get install -y git
      - run: yarn global add ci-yarn-upgrade
      - run: GIT_USER_NAME=your_github_user_name GIT_USER_EMAIL=your_email@example.com `yarn global bin`/ci-yarn-upgrade --execute

これとは別に、GitHubのpersonal tokenを取得して、GITHUB_ACCESS_TOKENをCircleCIの設定画面で設定する必要があります。

設定のあと、yarn-updateジョブを実行するとこんな感じのPRができます。

image.png (258.0 kB)

定期実行のやり方

定期実行のやり方はいろいろありますね。常時使える、かつcronが使えるマシンがあればそこからCircleCIのAPIをたたいてもよいです。

Running Jobs With the API - CircleCI

herokuを使って定期実行する

僕はつい最近までherokuのschedulerを使っていました。

herobu という、拙作のシェルスクリプトをherokuにデプロイしておくと、heroku schedulerでCircleCIのAPIを定期実行できます。

毎日PRがくるとちょっと頻度が高すぎるので、週に一回だけPRを作るようにしたいのですが、heroku schedulerは週一回の実行をサポートしていません。

そこでシェルスクリプト側で工夫しています。次のように登録しておいて、土曜日に実行されたときだけAPIを叩くようにしていました。

DAY=6 JOB=yarn-update PROJECT=willnet/savanna ./fire2.sh

詳細はソースを見てください(大したことはしてません)。

circle ciで定期実行する

CircleCIのv2からはWorkflowという仕組みができたので、サーバレスでジョブを定期実行できるようになりました。workflowの仕組自体はジョブを組み合わせて一つのワークフローを定義できるというものですが、一緒に定期実行の機能も追加されています。先程のyarn-updateというジョブを定期実行するworkflowは次のようにして定義できます。

workflows:
  version: 2
  yarn-update-scheculed:
    triggers:
      - schedule:
          cron: "5 0 * * 0"
          filters:
            branches:
              only:
                - master
    jobs:
      - yarn-update

これで毎週日曜日の9時5分にジョブが実行され、定期的にyarn updateできるようになりました。やりましたね。

まとめ

CircleCIを利用してyarnを定期的にアップデートするやり方を紹介しました。CircleCI以外でもいろいろやり方はあると思うので、自分なりのやり方でライブラリを最新に保っていくと良いのではないでしょうか。

*1:Gemfile更新用のツールは商用、OSSでそれなりの数あり、情報も多いので適当にググってください

*2:jobの中でgitをインストールしているのは、たしかCircleCIのイメージ内にあるgitのバージョンが古くてうまく動かなかったからのはず

RailsガイドでOSS貢献するのはどうだろうか

日本語版のRuby on Rails ガイド、日本人Railsエンジニアなら一度はお世話になったことがあると思うのだけど。読んでいるとtypoだったり、てにをはがちょっとおかしいところだったり、古いバージョンの記述のままだったりするところがあります。

ぼくは技術顧問業の一環でよくRailsガイドを読む機会があるので、そういうのを見つけたらなるべくPull Requestを送るようにしていたらコミット権をいただきました。

yasslab/railsguides.jp: Ruby on Rails Guides in Japanese (Railsガイド)

↑に普通に日本語でPull Requestを出せば大抵すぐにマージされるので、読んでいてここちょっとおかしいのでは?と思ったら気軽にPull Requestを投げるようにするとみんな幸せになるはず。日本語でPull Requet投げられるので、OSSに貢献というのをやってみたいけどどうしたらいいのかよくわからないみたいな人にオススメ。

例: Fix typo by willnet · Pull Request #491 · yasslab/railsguides.jp

あとは日本語版の間違いかな?と思ったら、原著が間違えていたという例もあります。その場合は、rails/railsにPRを投げることになります。Railsガイドの原著は本体のソースコードと一緒に管理されているのでした。

例: [ci skip] Add a missing space before closing curly braces by willnet · Pull Request #31312 · rails/rails

こういうしょぼいコミットでもRails Contributorsに反映されるので、積極的に見つけてコントリビューターの順位を上げていくと楽しいと思います。

もうちょっとちゃんと貢献したい人は、新規の章や節を探して追加してみるのが良いかと。例えば最近原著でActive Strorageの章ができたので、こういうの訳してPRくれたりするとみんなとても嬉しいはず。

というわけで、みなさんからのPull Requestお待ちしています。

Rails Developers Meetup 2017でレールの伸ばし方について話した

Rails Developers Meetup の年末拡大版である、Rails Developers Meetup 2017で発表させていただきました。

Railsアプリケーションの可読性を保ちつつ開発をすすめるにはどうしたらよいか、みたいな話です。資料はこちら

所感

この辺の情報は、英語圏だとちらほら情報あるのですが、まだまだまとまった統一見解みたいなものはなくそれぞれ思い思いのやり方でやっているような状況です。日本の現場だと、可読性を保つための方法はほとんど共有されておらず、共有されているとしてもチーム内で口伝に近いやり方*1で行われており、みんなの形式知になっているとは言い難いです。

楽に可読性の高いコードを書くための形式知(もしくはツール)があるとみんな幸せになれると思うので、ブログ書きやYubaの開発の進捗を頑張りたいと思います><。

*1:コードレビューのときなどで指摘する

RejectKaigi2017でファイルアップロードについて発表した

先日行われたRejectKaigi 2017でファイルアップロードについて発表しました。資料はこちら。

内容的には、WEB+DB PRESS Vol.95で書いたファイルアップロード話を最新にしたものになります。Rails5.2で新しく追加されるActive Storageというファイルアップロード機能を紹介しつつ、ファイルアップロード全般の話題について触れています。

ファイルアップロードをただしく実装するにはそれにまつわる様々な要素についての知見が必要で、webエンジニア的には腕の見せ所ではないかと思います。Active Storageの登場でファイルアップロードについての知見が広まって、ただしく実装できる人が増えるといいなと思います(( ⁰⊖⁰)/)

あわせて読みたい

WEB+DB PRESS Vol.95
WEB+DB PRESS Vol.95
posted with amazlet at 17.08.20
小出 淳子 黒澤 剛志 牧 大輔 横江 亮佑 山口 貴也 尾藤 正人 佐藤 琢哉 中橋 研太郎 田中 慎司 小西 裕介 伊藤 直也 稲富 駿 前島 真一 長野 雅広 山際 康貴 のざき ひろふみ うらがみ 岡林 大 遠藤 雅伸 ひげぽん 海野 弘成 はまちや2 竹原 大場 寧子 大場 光一郎 野々下 裕子
技術評論社
売り上げランキング: 281,045

「Rails5.1時代のアプリケーション開発」というテーマで発表した

昨日「Rails5.1時代のアプリケーション開発」というテーマで発表しました。

MedBeer -Rails 5.1での開発について- - connpass

スライドはこちら。内容的には、web開発難しいので頑張って勉強していきましょうというメッセージになっています。若干エモ寄り。

web開発における知の高速道路みたいなものがあるとよいのですが、学ばなければいけない要素技術は日に日に増えていくので頑張って道路を作ってもすぐ陳腐化していきます。なのでレベルを上げて物理で殴るのが現状の最適解かなと。みんなでレベル上げ頑張っていきましょう💪

ActionCableでフィーチャスペックを書く

最近自分の作っているサービスにActionCableを導入しました。そこでフィーチャスペックを書いていくつかハマったので内容を共有します。

使っているのはcapybara & poltergeistです。

Capybara.serverをpumaにする

Capybaraのデフォルトのサーバは、ざっと見た感じRailsアプリを別スレッドで動かしているだけのようです。これではActionCableを動かすことはできません。ActionCableを利用するにはpumaを使う必要があります。

次のようにすれば Capybara はpumaをサーバとして使ってくれます。

Capybara.server = :puma

これでオーケー…と言いたいところですが、まだ落とし穴が2つほどあります*1

puma のデフォルトワーカ数(プロセス数)を1にする

(追記)最近のcapybara(2.15.1以上?)を使っている場合、config/puma.rbの設定に関わらずワーカ数は1に設定されるようになったみたいです。

pumaはconfig/puma.rb があると、テスト時でもそれを設定に利用します。developmentやtestの環境ではActionCableのアダプタはasyncが設定されているため、pumaのプロセス数が2以上だとうまく動かないケースがあります。

次のように環境変数が設定されていない場合は1になるようにしておきましょう。

workers ENV.fetch("WEB_CONCURRENCY") { 1 }

ActiveJobのテストと環境を分ける

(追記)コード見た感じ、同一プロセス内の別スレッドでサーバ起動しているように見える&&実際にpumaで問題なく動くようだったのでこの節は読み飛ばしてください><

capybara/server.rb at master · teamcapybara/capybara · GitHub

前提として、ActiveJobのテスト用のアダプタはデフォルトの:testです。

Capybaraデフォルトのサーバを利用する場合は同一プロセス内でサーバが動くので、サーバ内でキューにジョブを詰めたとき、テストコード内でassert_enqueued_jobsなどのメソッドで実際にキューにジョブが入ったかを確認することができます。しかし、サーバをpumaにした場合は別プロセスになり、サーバ内でキューにジョブを詰めても、テストコード内では確認することができません。

ではActionCableを利用した場合だけサーバをpumaに変えればいいのでは?と思い次のようにしたのですが、フィーチャスペックが不安定になったのでやめました。どうやらserverはdriverのように頻繁に変更するようにはできていないようです(深掘りはしていません)。

config.around(:example, websocket: true) do |example|
  default_server = Capybara.server
  Capybara.server = :puma
  example.run
  Capybara.server = default_server
end

とりあえず次のように、通常のテストはActionCable以外をテストし、ActionCableを使ったテストだけを実行したい場合は環境変数をつけるようにしました。

if ENV['WEBSOCKET'].present?
  config.filter_run_including :websocket
else
  config.filter_run_excluding :websocket
end

これでテストが通るようになりました🍏

*1:僕はきっちりハマりました><