GitLab CI
Scan merge request previews on GitLab.com with the released QualityGate template, and post the result as a merge request note.
QualityGate supports merge request pipelines, pushes to the default branch, and scheduled pipelines on GitLab.com. Self-managed GitLab instances are not supported yet.
The scan runs in a container image published by QualityGate that already contains the browser, so there is nothing to install.
1. Create the project
In the app, go to Projects → Create project → GitLab and enter:
- the project path exactly as GitLab shows it in
CI_PROJECT_PATH, for exampleacme/weboracme/marketing/site; - the default branch, for example
main; - the allowed preview domains, for example
*.preview.example.com.
Create an API key named GitLab CI on the project card and copy it. It is shown
only once.
2. Add CI/CD variables
In GitLab, open Settings → CI/CD → Variables and add:
| Variable | Value | Settings |
|---|---|---|
QUALITYGATE_API_KEY | The project API key. | Masked, expansion off |
QUALITYGATE_GITLAB_TOKEN | A project access token for a bot user, role Reporter or higher, scope api. Only needed for merge request notes. | Masked, expansion off |
Mark them Protected if your merge request pipelines run on protected branches only. Never expose either value to pipelines from forks.
3. Include the template
Pick a release from the
QualityGate releases
page and add this to .gitlab-ci.yml, replacing v1.0.0 with that version:
include:
- remote: 'https://github.com/qualitygate/scan-action/releases/download/v1.0.0/qualitygate.gitlab-ci.yml'
qualitygate:
extends: .qualitygate
variables:
QUALITYGATE_URL: https://mr-$CI_MERGE_REQUEST_IID.preview.example.com
QUALITYGATE_BUNDLE: a11y
QUALITYGATE_FAIL_ON: critical=0,serious=0
The template runs the job for merge request pipelines, pushes to the default
branch, and scheduled pipelines, in the test stage. If you define your own
stages, include test or set stage: on the job.
The release pins the scanner image by its SHA-256 digest. To upgrade, change the
version in the include URL; do not override image.
Using a Review App URL
If a job deploys a Review App, pass its URL to QualityGate with a dotenv artifact so the scan always targets the environment that job created:
deploy_review:
stage: deploy
script:
- ./deploy-review.sh "$CI_COMMIT_REF_SLUG"
- echo "QUALITYGATE_URL=https://$CI_COMMIT_REF_SLUG.preview.example.com" >> review.env
environment:
name: review/$CI_COMMIT_REF_SLUG
url: https://$CI_COMMIT_REF_SLUG.preview.example.com
artifacts:
reports:
dotenv: review.env
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
qualitygate:
extends: .qualitygate
stage: review
needs: [deploy_review]
variables:
QUALITYGATE_BUNDLE: full
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
Add a review stage after deploy in your stages list. Variables from a
dotenv report are available to jobs that need the job that produced them.
The rules override keeps this job to merge requests, where the Review App
exists; add a second job extending .qualitygate for default-branch baselines.
Variables
| Variable | Required | Default | Purpose |
|---|---|---|---|
QUALITYGATE_API_KEY | Yes | none | Project API key. |
QUALITYGATE_URL | Yes | none | Preview URL on an allowed domain. |
QUALITYGATE_GITLAB_TOKEN | For notes | none | GitLab token with api scope, used only for merge request notes. |
QUALITYGATE_BUNDLE | No | a11y | See Bundles and checks. |
QUALITYGATE_FAIL_ON | No | critical=0,serious=0 | Limits or regression. See Gates and regression mode. |
QUALITYGATE_WAIT_FOR_URL | No | true | Wait for the preview to answer before scanning. |
QUALITYGATE_WAIT_TIMEOUT | No | 120 | Seconds to wait for the preview. |
QUALITYGATE_COMMENT | No | true | Post or update the merge request note. Set 'false' to skip it and the GitLab token. |
QUALITYGATE_ID_TOKEN | Automatic | set by the template | GitLab-signed job identity. Do not create it yourself. |
Identity and security
The template asks GitLab for an ID token with the audience
https://api.qualitygate.dev. GitLab signs it for this job only, and
QualityGate checks that it was issued by GitLab.com for the project path you
registered. Keep both secrets masked and never echo them in scripts.
Results
- The job fails when authorization is refused, the upload fails, or the gate fails. It also fails if a requested merge request note cannot be published.
- QualityGate keeps one note per merge request and updates it on each run.
- Runs on the default branch record the baseline for regression mode and post no note.
- Scheduled pipelines count as scheduled scans. Set
QUALITYGATE_URLon the schedule itself under Build → Pipeline schedules.