How QualityGate works
Where the scan runs, what leaves your CI, and who decides whether a pull request passes.
QualityGate has two halves: a small step in your CI that loads your preview in a real browser, and the QualityGate service that authorizes the run, decides the result, and keeps the history.
For a public HTTPS target, you can instead queue an on-demand cloud scan from the app. Cloud scans use the normal monthly allowance; scheduled scans have a separate allowance. Features covers the wider workflow.
One run, step by step
- Your CI starts the QualityGate step on a pull request, a push to your main branch, or a schedule.
- It waits for the preview. With
wait_for_urlon (the default), the step polls the URL until it answers with a2xxstatus, for up towait_timeoutseconds. - It asks QualityGate for permission. The step sends the repository, commit, branch, pull request number, URL, and requested bundle and limits. QualityGate checks that the project exists, the URL is on an allowed domain, your plan includes the bundle, and you have runs left this month. If everything checks out it reserves one run.
- The scan runs in your CI runner. A headless Chromium loads the page and the selected bundle inspects it. Performance uses multiple loads and deep SEO crawls a bounded set of pages. Your preview never has to be reachable from our servers.
- Findings are uploaded. QualityGate recomputes the pass or fail decision itself from the findings. The step never grades its own work.
- The result is published as a pull request comment, the job summary, and the project’s run history. The step exits with success or failure, which is what your branch protection sees.
Concepts
| Term | Meaning |
|---|---|
| Organization | Your team or agency. Owns the plan, members, projects, and report branding. |
| Project | One repository, its default branch, and the domains that may be scanned for it. |
| API key | A secret that lets a CI job act for one project. Not needed for GitHub repositories connected through the QualityGate GitHub App. |
| Bundle | Which checks run, such as a11y, seo, or full. See Bundles and checks. |
| Gate | The limits a run is judged against, set with fail_on. See Gates and regression mode. |
| Baseline | The last accepted result of a page on your main branch. Regression mode compares pull requests against it. |
| Run | One authorized scan. Runs count against your monthly allowance. |
What leaves your CI
- Sent to QualityGate: repository name, commit, branch, pull request number, the scanned URL, the requested bundle and limits, and the findings (rule, severity, message, CSS selector, page URL, help link).
- Not sent: your source code, screenshots, the page’s HTML, or your
secrets. For the
geoandseo-deepbundles, page text and structured data are uploaded for analysis, analysed in memory, and only the findings are stored.
Page URLs in the uploaded findings lose their query string, fragment, and any embedded credentials, and token-like parameters inside messages and selectors are redacted, before anything is stored or shown in a comment. Still, do not put secrets in the URL you ask QualityGate to scan.
Fail closed
A quality gate that silently passes when something breaks is worse than no gate. QualityGate fails the step when:
- authorization is denied (unknown key, domain not allowed, quota used up, and so on);
- the QualityGate service cannot be reached;
- the preview never becomes ready, or the browser cannot load it;
- the findings cannot be uploaded;
- the gate fails.
If you want QualityGate to report without blocking merges, make the step
advisory with continue-on-error: true. See
Advisory mode.
Honest limits
Automated checks find a large share of common problems, and they find them
consistently, but they are not a legal or conformance assessment. An ada
bundle pass does not mean a site is ADA or EAA compliant; qualified human review
is still required.