https://github.com/srz-zumix/jenkinsfile-shellcheck
actionlint が run の内容に対して shellcheck してくれるのをみて、Jenkinsfile の sh にもしてほしいなと思って作ってみました。
一応それっぽくできたのですが、何点か既知の問題があります。
sh ブロックの検出は AstBuilder 使ってるので問題ないのですが、行継続のエスケープが展開されて一行になるので、行番号がズレてしまうのが問題です。
ちなみに上は Groovy の文字列の記述がどう展開されるかテストしたものです。
Groovy の文字列記述には複数種類があります。ダブルクオーテーション・シングルクォーテーション、それを3つつなげて複数行記述。「$/」と「/$」で囲うことでも複数行記述できます。このうちシングルクォーテーション以外は GString にあたります。($/~/$はエスケープがそのまんま展開されるのがダブルクオーテーションと異なります)
GString は「${HOGE}」のような変数を展開します。
Jenkinsfile で GString の場合に環境変数を参照する場合に ${env.HOGE} のように書くこともあるのではないでしょうか。
(GString は知らないと結構ハマりやすいところだと思います)
AstNode から getText すると GString は展開されて取得できるのですが、そのとき「${env.HOGE}」は「env.HOGE」として展開されます。
この挙動はそんなには問題ないですが、Jenkinsfile が実行されるときのそれとは異なるので注意。
実行時と異なるという点での問題はまだあります。
sh の引数には単一の文字列ではなく、文字列連結して渡すことも当然できるため以下のようなケースで正しく解析できません。
頑張ればできないことはないかもしれませんが、今は非対応です。
ちなみに GString でシークレット環境変数を使うと展開されてから評価されるので shell 実行時に環境変数展開されるようにすべきなのですが、その警告は Jenkins がしてくれるので jenkinsfile-shellcheck ではノータッチです。
(ジョブ実行時もしくは validate で検出可能)
issue や pull request お気軽にどうぞ。
では、今回は以上です。