GitLab Code Quality reports

Enabling style compliance reports in GitLab merge requests

Use this procedure to enable the GitLab Code Quality widget for Vale. The widget reports style compliance issues in the GitLab merge request interface.

Procedure
  1. Create a .gitlab-ci.yml file at the repository root with the following content:

    image: node:16-alpine
    
    stages:
      - test
    
    code_quality:
      stage: test
      image:
        name: jdkato/vale:latest
        entrypoint: [""]
      tags: [shared]
      before_script:
        - apk update && apk add git
        - vale sync # Pull down VRH rules package specified in vale.ini
      script:
        # Get complete list of *.adoc files in the repository
        - FILES=$(find . -type f -name "*.adoc") (1)
        # Clean out conditions for wider Vale coverage in AsciiDoc
        - sed -i -e 's/ifdef::.*\|ifndef::.*\|ifeval::.*\|endif::.*/ /' ${FILES} (2)
        # Use a template to rearrange the vale JSON output
        # Run vale with --no-exit to pass the build with errors
        - vale ${FILES} --minAlertLevel=error --glob='*.adoc' --output="$(pwd)/vale-json.tmpl" > gl-code-quality-report.json
      artifacts:
        reports:
          codequality: gl-code-quality-report.json
      rules:
        - if: $CODE_QUALITY_DISABLED
          when: never
        - if: $CI_PIPELINE_SOURCE == "merge_request_event" # Run code quality job in merge request pipelines
        - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH # Run code quality job in pipelines on the default branch (but not in other branch pipelines)
        - if: $CI_COMMIT_TAG # Run code quality job in pipelines for tags
    1 Update the $FILES step to match your documentation source type, for example, use *.md for markdown.
    2 Optional. Vale does not lint inside AsciiDoc conditional statements unless you pass the conditional variables as Asciidoctor attributes. You can bypass this limitation in the CI by temporarily removing ifdef and ifeval directives before linting with Vale. This step is only useful for AsciiDoc, and can be removed for other source formats.
  2. Create a vale-json.tmpl file at the repository root:

    {{- /* Modify Vale output https://docs.errata.ai/vale/cli#--output */ -}}
    
    {{- /* Keep track of our various counts */ -}}
    
    {{- $e := 0 -}}
    {{- $w := 0 -}}
    {{- $s := 0 -}}
    {{- $f := 0 -}}
    
    {{- /* Range over the linted files */ -}}
    
    [
    {{- $first := true -}}
    {{- range $jdx, $file := .Files -}}
      {{- $f = add1 $f -}}
      {{- $path := $file.Path -}}
    
      {{- /* Range over the file's alerts */ -}}
      {{- range $idx, $a := $file.Alerts -}}
        {{- if not $first -}},{{- end -}}
        {{- $first = false -}}
    
        {{- $error := "" -}}
        {{- if eq $a.Severity "error" -}}
          {{- $error = "critical" -}}
          {{- $e = add1 $e -}}
        {{- else if eq $a.Severity "warning" -}}
          {{- $error = "major" -}}
          {{- $w = add1 $w -}}
        {{- else -}}
          {{- $error = "minor" -}}
          {{- $s = add1 $s -}}
        {{- end}}
    
        {{- /* Variables setup */ -}}
    
        {{- $loc := printf "%d" $a.Line -}}
        {{- $check := printf "%s" $a.Check -}}
        {{- $message := printf "%s" $a.Message -}}
    
        {{- /* Compute the Base64 encoded fingerprint string */ -}}
        {{- $hashInput := printf "%s:%s:%s" $path $loc $message -}}
        {{- $Base64Encoded := b64enc $hashInput -}}
    
        {{- /* Output */ -}}
        {
          "description": "{{$check}}: {{ $message }}",
          "check_name": "vale-error-report",
          "fingerprint": "{{ $Base64Encoded }}",
          "severity": "{{ $error }}",
          "location": {
            "path": "{{ $path }}",
            "lines": {
              "begin": {{ $loc }}
            }
          }
        }
      {{- end -}}
    {{- end -}}
    ]
  3. Add the following entries to .gitignore:

    .vale
    gl-code-quality-report.json
  4. Commit the files to the local repository:

    git add .
    git commit -m "Add GitLab CI/CD code quality pipeline"
  5. Push the changes to the remote repository:

    git push -u origin main

When you merge the changes to the main branch, a code quality pipeline will run for every new commit added in a merge request. The code quality report is available in the Merge Request Overview tab.

The GitLab CI job creates the code quality report by comparing a complete list of errors in the main branch and a list of errors in the merge request branch. This might cause a CI bottleneck on large repositories with 1000s of files, but for small and medium repositories, the CI processing time is negligible.

Additional resources