GitHub Actionsで#<Errno::ENOTTY
発生した経緯
自作のRubyGemのテストとCIを整えていた時に遭遇。 パスワード入力の所でIO#noechoを使うように修正した所、GitHub Actions内で以下のようなエラーが起きた。
1) GreenDay::Cli login valid name and password create cookie-store Failure/Error: password = STDIN.noecho { |stdin| stdin.gets(chomp: true) }.tap { puts } Errno::ENOTTY: Inappropriate ioctl for device # ./lib/green_day/cli.rb:19:in `noecho' # ./lib/green_day/cli.rb:19:in `login' # ./spec/cli_spec.rb:83:in `block (3 levels) in <top (required)>' # ./spec/cli_spec.rb:101:in `block (4 levels) in <top (required)>'
ローカルでは通ったのでCI環境での問題っぽい。
解決まで
"GitHub Actions Inappropriate ioctl for device"でググった所以下のissueを発見。
どうやらTTYなるもので無いのが駄目らしい。
ワークアラウンドらしいけどこのコメントで解決した
https://github.com/actions/runner/issues/241#issuecomment-577360161
script
はデフォルトでtypescript
ってファイルにターミナルのsessionをまるごと記録してくれるもの。
仕組みはよくわかってないけど実際にローカルでscriptを叩くとセッションが新しく始まって後述のtty
コマンドの結果も変化したのでなにかしらttyに当たるものを作るとうまく行く原理なのだろうか。
travis ciでは問題が再現しなかったのでGitHub Actions特有の問題っぽい。Dockerコンテナの出力をキャプチャしているのが関係しているのかもしれない。
最終的にscript -e -c
をつけてテストを実行するとエラーは起きなくなった。
https://github.com/QWYNG/green_day/blob/1e174b17201743723a98e7ae245de4fe27e4bbc6/.github/workflows/ruby.yml#L28
tty is 何
最後にttyというワードも初めて知ったのでメモ。 tty自体はUNIXコマンド
man tty TTY(1) User Commands TTY(1) NAME tty - print the file name of the terminal connected to standard input
ターミナルに入力していると思っていた標準入力は実際はこのファイルへ送っているらしい。
~ ps 2020年07月16日 23時00分57秒 PID TTY TIME CMD 83617 pts/2 00:00:00 fish 83739 pts/2 00:00:00 ps ~ ll /proc/83617/fd 2020年07月16日 23時01分00秒 合計 0 lrwx------ 1 qwyng qwyng 64 7月 16 23:00 0 -> /dev/pts/2 lrwx------ 1 qwyng qwyng 64 7月 16 23:00 1 -> /dev/pts/2 lrwx------ 1 qwyng qwyng 64 7月 16 23:00 2 -> /dev/pts/2 lr-x------ 1 qwyng qwyng 64 7月 16 23:00 3 -> /home/qwyng/ lr-x------ 1 qwyng qwyng 64 7月 16 23:00 4 -> 'pipe:[727942]' l-wx------ 1 qwyng qwyng 64 7月 16 23:00 5 -> 'pipe:[727942]' lr-x------ 1 qwyng qwyng 64 7月 16 23:00 6 -> 'pipe:[728533]' l-wx------ 1 qwyng qwyng 64 7月 16 23:00 7 -> 'pipe:[728533]' lrwx------ 1 qwyng qwyng 64 7月 16 23:00 8 -> /run/user/1000/fish_universal_variables.notifier| ~ tty 2020年07月16日 23時01分19秒 /dev/pts/2 ~ 2020年07月16日 23時01分35秒
RubyにもIOがttyか調べるメソッドが合った。 docs.ruby-lang.org
IO#nochoのソースコードもttyが前提のようなコードだった。