1
0
Fork 0
toolkit/docs/problem-matchers.md

162 lines
5.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# Problem Matchers
Problem matchers are a way to scan the output of actions for a specific regular expression (regex) pattern and surface that information prominently in the UI. Both [check run annotations](https://docs.github.com/en/rest/checks/runs) and log file decorations are created when a match is detected.
## Limitations
Currently, GitHub Actions limits the annotation count in a workflow run.
- 10 warning annotations, 10 error annotations, and 10 notice annotations per step
- 50 annotations per job (sum of annotations from all the steps)
- 50 annotations per run (separate from the job annotations, these annotations arent created by users)
If a workflow run exceeds these annotation counts, consider filtering the log messages which the problem matcher is exposed to (e.g. by PR touched files, lines, etc.).
## Single-Line Matchers
Consider the following ESLint compact output:
```plain
badFile.js: line 50, col 11, Error - 'myVar' is defined but never used. (no-unused-vars)
```
The following problem matcher detects input in this format:
```json
{
"problemMatcher": [
{
"owner": "eslint-compact",
"pattern": [
{
"regexp": "^(.+):\\sline\\s(\\d+),\\scol\\s(\\d+),\\s(Error|Warning|Info)\\s-\\s(.+)\\s\\((.+)\\)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"message": 5,
"code": 6
}
]
}
]
}
```
The following fields are available for problem matchers:
```json
{
"owner": "(Required) An ID field that can be used to remove or replace the problem matcher.",
"severity": "Indicates the default severity: either 'warning' or 'error' (case-insensitive). Defaults to 'error'.",
"pattern": [
{
"regexp": "(Required) The regex pattern that provides the groups to match against.",
"file": "A group number containing the file name.",
"fromPath": "A group number containing a file path used to root the file (e.g. a project file).",
"line": "A group number containing the line number.",
"column": "A group number containing the column information.",
"severity": "A group number containing either 'warning' or 'error' case-insensitive. Defaults to `error`",
"code": "A group number containing the error code",
"message": "(Required) A group number containing the error message. At least one pattern must set the message.",
"loop": "Whether to loop until a match is not found. Only valid on the last pattern of a multipattern matcher."
}
]
}
```
## Multiline Matching
Consider the following output:
```plain
test.js
1:0 error Missing "use strict" statement strict
5:10 error 'addOne' is defined but never used no-unused-vars
✖ 2 problems (2 errors, 0 warnings)
```
The file name is printed once, yet multiple error lines are printed. The `loop` keyword provides a way to discover multiple errors in outputs.
The following problem matcher catches this output and creates two annotations.
```json
{
"problemMatcher": [
{
"owner": "eslint-stylish",
"pattern": [
{
// Matches the 1st line in the output.
"regexp": "^([^\\s].*)$",
"file": 1
},
{
// Matches the 2nd and 3rd line in the output.
"regexp": "^\\s+(\\d+):(\\d+)\\s+(error|warning|info)\\s+(.*)\\s\\s+(.*)$",
// The "file" property is carried through from the previous pattern,
// so we define the rest of the groups.
"line": 1,
"column": 2,
"severity": 3,
"message": 4,
"code": 5,
"loop": true
}
]
}
]
}
```
The first pattern matches the `test.js` line and records the file information. This line is not decorated in the UI. The second pattern loops through the remaining lines (`"loop": true`) until it fails to find a match. Any matches are surfaced prominently in the UI.
**Note:** Pattern matches must be on consecutive lines. The following would not result in any match findings.
```plain
test.js
extraneous log line of no interest
1:0 error Missing "use strict" statement strict
5:10 error 'addOne' is defined but never used no-unused-vars
✖ 2 problems (2 errors, 0 warnings)
```
## Adding and Removing Problem Matchers
The `add-matcher` command enables a problem matcher using a path to a problem matcher file:
```bash
echo "::add-matcher::eslint-compact-problem-matcher.json"
```
The `remove-matcher` command removes a problem matcher:
```bash
echo "::remove-matcher owner=eslint-compact::"
```
## Duplicate Problem Matchers
Registering two problem-matchers with the same owner will result in only the last-registered problem matcher running.
## Examples
Some of the `setup-` actions are already using problem matchers:
- [setup-node](https://github.com/actions/setup-node/tree/main/.github)
- [setup-python](https://github.com/actions/setup-python/tree/main/.github)
- [setup-go](https://github.com/actions/setup-go/tree/main/.github)
- [setup-dotnet](https://github.com/actions/setup-dotnet/tree/main/.github)
## Troubleshooting
### Regular Expression not Matching
- Use ECMAScript regular expression syntax when testing patterns.
### File Property Getting Dropped
This usually happens when the file does not exist or is not under the workflow repo.
- [Enable debug logging](https://docs.github.com/en/actions/monitoring-and-troubleshooting-workflows/enabling-debug-logging) to determine why the file is getting dropped.