☠️
Problem Matcherの登録とGithub Annotationへの反映
loglint というエラーログから正規表現で該当部分を検出する仕組みを以前に作ったのだけど、Github Actionsで同様の仕組みがあることを知ったので調べたメモ。
概要
Problem Matcher
- GitHub Actionsで実行したログからエラー部分を正規表現で抽出する仕組み
- 下記JSONをプロジェクト内に配置して、Github Actionのログに
::add-matcher::hoge.json
をprintしておけばいい.
具体例
NextJSのビルドログのmatcherを試してみた。
検出したいサンプルログ。
./src/lib/sample.ts
Error:
x Expression expected
,-[/home/runner/work/sample-problem-matcher/sample-problem-matcher/src/lib/sample.ts:1:1]
1 | export function calc(a: number, b: number): number {
2 | return a ^^ b;
: ^
3 | }
`----
Caused by:
Error: Syntax Error
実際のログにはterminalのcolorエスケープシーケンスが挿入されているので、下記の感じ。
./src/lib/sample.ts
Error:
ESC[31mxESC[0m Expression expected
,-[ESC[36;1;4m/Users/mattak/github/mattak/sample-problem-matcher/src/lib/sample.tsESC[0m:1:1]
ESC[2m1ESC[0m | export function calc(a: number, b: number): number {
ESC[2m2ESC[0m | return a *** b;
: ESC[31;1m ^ESC[0m
ESC[2m3ESC[0m | }
`----
Caused by:
Syntax Error
.github/sample-matcher.json
{
"problemMatcher": [
{
"owner": "next-build",
"severity": "error",
"pattern": [
{
"regexp": "^(\\./.+)$",
"file": 1
},
{
"regexp": "^\\s*Error:\\s*$"
},
{
"regexp": "^\\s+\\S*x\\S* (.+)$",
"message": 1
},
{
"regexp": "\\[(.+):(\\d+):(\\d+)\\]$",
"line": 2,
"column": 3
},
{
"regexp": "^\\s*Caused by:\\s*$"
},
{
"regexp": "^\\s+(.+)$",
"code": 1
}
]
}
]
}
定義ファイルの仕組み
- pattern内に検出したいログ1行に相当する部分を記述する
- 複数行に渡る場合はjson array内に複数記述する
- regexpにログ検出する正規表現を記述する
- 正規表現のgroup matchした各indexと対応付ける感じで、message,file,line,column,code等を記述する
あとは、actionsのworkflow定義に ::add-matcher::sample-matcher.json
を追記する.
.github/workflows/deploy.yml
name: Deploy Next.js Static Site to GitHub Pages
on:
push:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
steps:
# リポジトリをチェックアウト
- name: Checkout repository
uses: actions/checkout@v4
# Node.js をセットアップ
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
# パッケージをインストール
- name: Install dependencies
run: npm install
# problem-matcher
- name: Add NextJS problem matcher
run: echo "::add-matcher::.github/sample-matcher.json"
# ビルド
- name: Build the project
run: npm run build
# デプロイ
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./out
結果
ActionsのAnnotation に対象部分が検出されている
リンク先に飛ぶと対象コードをハイライトできている
その他
手元で実験する方法がわからなかったので、rubyで標準入力から正規表現の
マッチ部分を検証するコードを書いた。
#!/usr/bin/env ruby
regexes =
[
Regexp.new("^(\\./.+)$"),
Regexp.new("^\\s*Error:\\s*$"),
Regexp.new("^\\s+\\S*x\\S* (.+)$"),
Regexp.new("\\[(.+):(\\d+):(\\d+)\\]$"),
Regexp.new("^\\s*Caused by:\\s*$"),
Regexp.new("^\\s+(.+)$"),
]
lines = STDIN.map {|x| x}
i = 0
lines.each_with_index do |line, n|
break if i >= regexes.size
if m = regexes[i].match(line)
puts "** MATCH\t#{n}\t#{m.captures}"
i+=1
end
end
あと、Custom Action作るならr7kamuraさんのコードがシンプルで参考になった.
::add-matcher
::をconsole.logするだけでシンプル..!
Discussion