DEV Community

Cover image for Show svelte-check's errors in your GitLab merge requests (and GitHub pull requests)
faissalrez
faissalrez

Posted on

Show svelte-check's errors in your GitLab merge requests (and GitHub pull requests)

If your SvelteKit project runs svelte-check in CI, you've probably seen this: the job fails, and the type errors are somewhere in the job log. Reviewers have to open the log, scroll, and map each line back to the diff. Meanwhile, ESLint's errors show up right in the merge request, because ESLint has formatters for GitLab and GitHub.

svelte-check doesn't, and that's on purpose: its maintainers prefer not to add output formats, and point to its machine-readable output instead. So I wrote the conversion: svelte-check-reporter. This post explains how it works, and the parts that weren't obvious.

What svelte-check gives you

With --output machine-verbose, svelte-check prints one JSON diagnostic per line, after a timestamp:

1762500000000 START "/builds/my-app"
1762500001000 {"type":"ERROR","filename":"src/lib/cart.ts","start":{"line":3,"character":56},"end":{"line":3,"character":61},"message":"Property 'prise' does not exist on type 'Product'. Did you mean 'price'?","code":2551}
1762500001000 COMPLETED 12 FILES 1 ERRORS 0 WARNINGS 1 FILES_WITH_PROBLEMS
Enter fullscreen mode Exit fullscreen mode

Everything a report needs is there: the file, the range, the message, the code, and whether it's an error or a warning.

GitLab: a Code Quality report

GitLab shows problems in a merge request from a Code Quality report, a JSON file that a job declares as an artifact:

check:
  image: node:24-alpine
  script:
    - npm ci
    - npx svelte-kit sync
    - npx svelte-check --output machine-verbose | npx svelte-check-reporter --output-file gl-codequality.json
  artifacts:
    when: always
    reports:
      codequality: gl-codequality.json
Enter fullscreen mode Exit fullscreen mode

GitLab compares the merge request's report with the target branch's. The widget then lists only the problems the merge request adds, and the ones it fixes:

The Code Quality widget of a GitLab merge request: 3 new findings and 1 fixed finding

And the Changes tab marks each new problem in the margin of the diff:

Code Quality markers in a GitLab merge request's diff, with one finding opened

Two details in that job matter:

  • when: always: the job fails when svelte-check finds errors, which is exactly when you want the report uploaded.
  • The job must also run on the target branch. Without a report there, GitLab has nothing to compare with.

The tricky part: the fingerprint

To tell new problems from existing ones, GitLab matches them across pipelines by a fingerprint field. It's up to the report to compute it, and the obvious choice is wrong.

If the fingerprint includes the line number, adding one line at the top of a file changes the fingerprint of every error below it. GitLab then reports all of them as new, and all the old ones as fixed. On a project with existing errors, every merge request would look like it broke everything.

So the fingerprint is a hash of the file, the error code and the message, without the line. That raises the opposite problem: two identical errors in the same file, say the same typo twice, would get the same fingerprint. They're told apart by their order in the file: the first one is #1, the second #2. Moving code around doesn't change that order, unless you swap two identical errors, which doesn't matter.

This is the same approach as eslint-formatter-codeclimate, and it's what makes the widget useful on a real project. One more detail: the reporter can prefix messages (--prefix '[svelte-check] ') to tell them apart from other tools' in the widget, and the prefix isn't part of the fingerprint, so adding it later doesn't mark everything as new.

GitHub: annotations or code scanning

On GitHub, there are two ways to put errors on a pull request's diff.

Annotations need nothing but the command, in any repository:

- run: npx svelte-check --output machine-verbose | npx svelte-check-reporter --format github
Enter fullscreen mode Exit fullscreen mode

A Svelte warning and a type error annotated on a GitHub pull request's diff

They have two limits: GitHub doesn't compare them with the base branch, so existing errors are annotated too, and it shows at most 10 error and 10 warning annotations per step.

Code scanning takes a SARIF file, uploaded with github/codeql-action/upload-sarif and the security-events: write permission. It compares each pull request with the base branch, so it only comments on the problems a pull request adds, without a limit:

A code scanning comment on a type error in a GitHub pull request

Pick one: both put problems on the same lines, so using both shows each one twice. The README has the full workflow, including the push to main that gives code scanning its baseline.

Small things that bit me

  • Lines are 0-based in machine-verbose, unlike --output machine, which is 1-based. GitLab, GitHub and SARIF all expect 1-based lines. The svelte-check team won't change it, since it would break existing tools.
  • An empty report can lie. If svelte-check crashes, there's no COMPLETED line, and converting what's there gives an empty report: a clean-looking merge request. The reporter fails instead.
  • Warnings don't fail the job, as with svelte-check: only errors do.

Try it

npm install --save-dev svelte-check-reporter
Enter fullscreen mode Exit fullscreen mode

The README has the setup for each integration, and the demo project shows the result in real GitHub pull requests and a GitLab merge request. Feedback and issues are welcome.

Top comments (0)