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

5.5 KiB
Raw Blame History

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 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:

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:

{
  "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:

{
  "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:

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.

{
  "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.

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:

echo "::add-matcher::eslint-compact-problem-matcher.json"

The remove-matcher command removes a problem matcher:

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:

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.