rails assets:precompile 時に yarn install が実行されない

Rails5をHerokuにデプロイしようとした際、rails assets:precompile 時に yarn install が実行されず、node_module ディレクトリをassetsから読み込むことができずにビルドエラーになってしまった。

そもそも assets:precompile 時に yarn install が実行される条件ってなんだろうと思って探してみると、bin/yarn ファイルがあることが条件のようだった。

https://github.com/rails/rails/blob/f99b3c5f9759baffec5c1f7abf74e108e2fb1c77/railties/lib/rails/tasks/yarn.rake#L11

bin/yarn ファイルを作成すると無事に yarn install が実行されてデプロイできた。

Rubyの system メソッドは、デフォルトでは実行ファイルがない場合は何も出力せずに nil を返すだけのよう。

https://docs.ruby-lang.org/ja/latest/method/Kernel/m/system.html

irb(main):005:0> system("hogehoge")
=> nil

PHPでスクリプトが無言で死ぬ

状況

CakePHPのプロジェクト。
自分で作った機能ではないが、数年前に作ってほったらかしだったCI環境のアップデートの必要があり、他に手が空いてる人がいないとのことで私が担当していた。テストを実行すると、スクリプトのプロセスがエラーログも何も出さずに突然終了してしまう事象が発生した。

原因

PHPエクステンションにインストール漏れがあった。エクステンションでインストールされる関数を利用している箇所でエラー制御演算子(@)が使われていたため、プロセスが落ちた時にログが出なかった。
テストケースをコメントアウトしながら実行して落ちるテストケースを絞り込み、実行されているメソッドのコードリーディングで発見した。

エラー制御演算子のドキュメントには以下の記述がある。

警告現在、エラー制御演算子プレフィックス”@”は、スクリプトの実行を 終了するような致命的なエラーの出力さえ抑圧します。このため、ある関数の エラー出力を抑制するために “@” を使用した場合、その関数が 利用できなかったり、ミスタイプがあった場合でも、原因を示すことなく その場所でスクリプトは終了してしまいます。

エラー制御演算子を外してテストを実行すると以下のようなエラーが出た。

Fatal error: Call to undefined function exif_imagetype() 

ログを見た瞬間に原因が分かる。エラー制御演算子が使われていたために3秒で原因が分かるエラーの特定に3日かかってしまった。まじ💩

メモ

PHPのプロセスが無言で死ぬ時はまず最初にエラー制御演算子を疑う。

SimpleCovでHelperのカバレッジが測定されない

環境

  • Rails 5.2.3
  • Rspec 3.8.0
  • simplecov 0.16.1

事象

ApplicationHelperのspecを書いてrspecを実行したところ、Helperのカバレッジが0%になっていた。他のファイルのカバレッジは測定されていた。Rspecの実行ログから、ApplicationHelperのspecが実行されていることは確認できている。

原因

SimpleCov.start を rails_helper.rb の先頭に書いてなかったのが原因だった。
ドキュメントにも太文字でtopだと書いてあった。

Similarly to the usage with Test::Unit described above, the only thing you have to do is to add the SimpleCov config to the very top of your Cucumber/RSpec/whatever setup file.
Add the setup code to the top of features/support/env.rb (for Cucumber) or spec/spec_helper.rb (for RSpec).

https://github.com/colszowka/simplecov#use-it-with-any-framework

対処

SimpleCov関連の設定処理は spec/support/simplecov.rb にまとめていて、 Dir[Rails.root.join(‘spec/support/**/*.rb’)].each { |f| require f } で実行していたが、rails_helper.rb の先頭で require ‘./spec/support/simplecov’ を実行するようにしたらApplicationHelperのカバレッジが測定されるようになった。

メモ

SimpleCovはstartメソッドの中でRuby標準ライブラリのCoverage.startを実行している。Helper(module)がCoverage.startの実行前に読み込まれてしまってカバレッジの測定対象に入っていなかったのだろうか。(未確認)

RailsのSystem specで Net::ReadTimeout が発生する

症状

RailsのSystem specを実行すると、以下のエラーで spec が失敗する

     Net::ReadTimeout:
       Net::ReadTimeout with #<TCPSocket:(closed)>
  • ローカル環境では最初のテスト実行時だけ発生する。2回目から発生しなくなる。
  • CI環境でたまランダムで発生する。

原因

どうやらassetsのコンパイルに時間がかかっているためにSeleniumがタイムアウトしているようだった。(確かにこのサイトはassetsのscss, javascriptが巨大で、最初のアクセスにかなりの時間がかかっていた)

ローカル環境では一度assetsがコンパイルされていればキャッシュがあるため1度だけ発生していたようだ。

CI環境では以下の記事と同様に事前にassets:precompileすることで解決した。
https://jtway.co/4-lines-to-speed-up-your-rails-test-suite-on-ci-744e4326e8a3

# config/environments/test.rb
Rails.application.configure do
  :
  if ENV['CI']
    config.assets.digest = true
    config.assets.debug = false
    config.assets.compile = false
    config.assets.js_compressor = Uglifier.new(harmony: true)
  end
end
# .circleci/conf.yml
    :
    steps:
    :
    - restore_cache:
        keys:
          - asset-cache-{{ arch }}-{{ .Branch }}
          - asset-cache-
    - run: bundle exec rails assets:precompile
    - save_cache:
        key: asset-cache-{{ arch }}-{{ .Branch }}-{{ epoch }}
        paths:
          - public/assets
          - public/packs
          - tmp/cache/assets/sprockets

ThinkPad Carbon で仮想化を有効にできない

ThinkPad X1 Carbon 6th Gen (2018モデル) の Windows10 Pro。Dockerを入れようとしたところ、仮想化が無効になっているためインストールに失敗してしまった。

Windows10のヘルプの通りに「PowerShell を使用して Hyper-V を有効にする」を実行したところ、「Windowsの機能」のHyper-Vにチェックは入っているが、タスクマネージャーのパフォーマンスでは仮想化は「無効」のまま、という状況になってしまった。Dockerはインストールできないまま。

「Windowsの機能」で一度Hyper-Vのチェックを外してみると、Hyper-Vにチェックが入れられない状態になった。

原因はBIOSの設定で仮想化機能が無効化されていることのようだった。
BIOSのVirtualization設定でCPU Virtualization Technologyを有効化すると、「Windowsの機能」でHyper-Vにチェックを入れることができるようになり、タスクマネージャーで仮想化が「有効」になったのが確認できた。Dockerも無事インストールができた。

「Windowsの機能」のGUIでHyper-Vにチェックが入れられない状態でもPowerShellを使うと有効化できないにも関わらずチェックが入ってしまうようだった 😇

firebase init で認証エラーが出る

firebase init コマンドでプロジェクトを初期化しようとしたらエラーになり、ログを見ると認証エラーのようだった。(エラーログは勝手に消えてしまった)

認証トークンがおかしくなったのかなと思い、 firebase login –help を見てみると、–reauth といオプションがあるのに気がついた。

$ firebase login --help
Usage: login [options]

log the CLI into Firebase

Options:
  --no-localhost  copy and paste a code instead of starting a local server for authentication
  --reauth        force reauthentication even if already logged in
  -h, --help      output usage information

これで認証トークンのリフレッシュができるのかな、と思い、firebase login –reauth を実行してみたら無事に firebase init ができるようになった。