Problems

RWX can scan the output of tasks for problems associated to specific lines of code, such as linter or compiler errors. The RWX UI will highlight the problems each task produces, making it easy to see what issues caused a task to fail at a glance.

RWX can detect problems from log output and from files written to the filesystem.

Detecting problems from log output

To scan log output for problems, you can configure RWX to use problem matchers, which are regex patterns that produce structured data. RWX uses the same configuration format as GitHub Action's Problem Matchers.

RWX has several built-in problem matchers:

  • brakeman: Create problems from warnings produced by Brakeman.
  • checkstyle: Create problems from Checkstyle text output.
  • clang-tidy: Create problems from clang-tidy output.
  • clippy: Create problems from Clippy output.
  • cppcheck: Create problems from Cppcheck output.
  • credo: Create problems from Credo output. Both the default and "oneline" output formats are supported.
  • dart: Create problems from dart analyze output.
  • detekt: Create problems from detekt errors.
  • erb-lint: Create problems from erb-lint linters errors and warnings.
  • eslint: Create problems from ESLint linter errors and warnings.
  • eslint-only-errors: Create problems from ESLint linter errors only.
  • golangci-lint: Create problems from Golangci-lint output.
  • htmlhint: Create problems from HTMLHint errors and warnings.
  • jshint: Create problems from JSHint errors and warnings.
  • ktlint: Create problems from Ktlint errors.
  • luacheck: Create problems from Luacheck output.
  • php_codesniffer: Create problems from PHP_CodeSniffer output.
  • psalm: Create problems from Psalm output.
  • PSScriptAnalyzer: Create problems from PSScriptAnalyzer CSV output (for example, by running PSScriptAnalyzer | ConvertTo-Csv).
  • pylint: Create problems from Pylint errors and warnings.
  • roslyn: Create problems from .NET code analysis findings.
  • rubocop: Create problems from Rubocop linter errors and warnings.
  • rubocop-only-errors: Create problems from Rubocop linter errors only.
  • ruff: Create problems from Ruff errors. Both the default and "concise" output formats are supported.
  • shellcheck: Create problems from ShellCheck linter errors and warnings.
  • sqlfluff: Create problems from SQLFluff errors.
  • stylelint: Create problems from stylelint errors and warnings. Both the default and "compact" output formats are supported.
  • swiftlint: Create problems from SwiftLint output.
  • tailor: Create problems from Tailor output.
  • tsc: Create problems from errors and warnings produced by the TypeScript compiler.

You can specify which built-in problem matchers you want to use in the outputs section of a task, like so:

tasks:
  - key: lint
    run: npm run lint
    outputs:
      problems:
        - matcher: eslint

If you want to use a problem matcher that is not built into RWX, you can also specify a URL to a problem matcher, like so:

tasks:
  - key: lint
    run: npm run lint
    outputs:
      problems:
        - matcher: https://raw.githubusercontent.com/actions/setup-node/8f152de45cc393bb48ce5d89d36b731f54556e65/.github/eslint-stylish.json

Detecting problems from a file

Some linting tools support writing files containing the issues they detect. You can configure RWX to read files after your task completes and generate problems based on those files.

RWX currently supports three different file formats for generating problems:

  • RWX Problem JSON
  • GitHub Annotations JSON
  • GitHub Actions annotations-action JSON

The schema of each of these formats is detailed below. To detect problems from a file, you can configure the outputs section of a task like so:

tasks:
  - key: write-problem
    run: |
      echo '[{"file": "path/to/file.js", "line": 5, "owner": "owner", "message": "my message", "severity": "error", "code": "XYZ"}]' > ./problem.json
    outputs:
      problems:
        - path: problem.json

RWX will automatically detect the format of your file and parse it appropriately.

RWX Problem JSON

RWX's native problem format follows the following schema:

type Problem = {
  owner: string
  message: string
  severity: 'error' | 'warning' | 'info'
  code?: string
  file?: string
  fromPath?: string
  line?: number
  column?: number
  end_line?: number
  end_column?: number
}
type RwxProblemJson = Problem[]

For example:

[
  {
    "owner": "my-lint-tool",
    "message": "my message",
    "severity": "error",
    "code": "MYTOOL-500",
    "file": "path/to/file.js",
    "line": 5,
    "column": 3
  }
]

GitHub Annotations JSON

RWX supports the format used by the GitHub API for GitHub annotations, which follows this schema:

type GitHubAnnotation = {
  path: string
  message: string
  end_line: number
  start_line: number
  annotation_level: 'warning' | 'failure' | 'notice'
  title?: string | undefined
  end_column?: number | undefined
  start_column?: number | undefined
  raw_details?: string | undefined
  blob_href?: string | undefined
}
type GitHubAnnotationJson = GitHubAnnotation[]

For example:

[
  {
    "path": "path/to/file.js",
    "message": "my message",
    "end_line": 4,
    "start_line": 4,
    "annotation_level": "failure",
    "title": "my-tool",
    "start_column": 3
  }
]

GitHub Actions annotations-action JSON

RWX supports the format used by the GitHub Actions reusable action annotations-action, which follows this schema:

type GitHubAnnotationsActionPayload = {
  message: string
  annotation_level: 'warning' | 'failure' | 'notice'
  path?: string | undefined
  title?: string | undefined
  file?: string | undefined
  line?: number | undefined
  end_line?: number | undefined
  end_column?: number | undefined
  start_line?: number | undefined
  start_column?: number | undefined
  raw_details?: string | undefined
  blob_href?: string | undefined
}
type GitHubAnnotationsActionJson = GitHubAnnotationsActionPayload[]

For example:

[
  {
    "message": "my message",
    "annotation_level": "failure",
    "path": "path/to/file.js",
    "title": "my-tool",
    "line": 4,
    "start_column": 3
  }
]