The best way to get instant PR feedback and block merges with Shiplight in GitLab CI
Updated on May 2, 2026
Updated on May 2, 2026
Merge requests are where quality either becomes a habit or a last-minute scramble. The difference is not how many tests you have. It is whether every PR gets fast, trustworthy feedback that is tied to the actual UI change and enforced automatically.
Shiplight AI is built for that moment. It verifies UI changes in real browsers during the coding process, generates and maintains end-to-end coverage with minimal upkeep, and fits directly into CI workflows, including GitLab CI. The result is simple: engineers get signal quickly, and GitLab prevents risky changes from reaching main.
This post walks through a practical, production-grade pattern to do two things in GitLab:
For most teams, fast feedback is not one job. It is a short sequence:
Shiplight fits particularly well because it is designed to validate UI behavior in real browsers and keep tests durable over time with intent-based execution and self-healing. That durability is what makes merge blocking realistic. If your UI tests are flaky, you eventually stop trusting the gate and the whole system collapses.
The most reliable approach in GitLab CI is:
This mirrors how high-velocity teams actually ship: protect the trunk with a small set of high-signal checks, and keep broader coverage running continuously.
Below is an example .gitlab-ci.yml structure. The Shiplight command is intentionally shown as a placeholder, because the exact invocation depends on how your Shiplight workspace is configured (suite names, project IDs, whether you trigger via CLI or API). The CI pattern is the key.
stages:
- test
- regression
workflow:
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH == "main"
variables:
SHIPLIGHT_JUNIT_PATH: "shiplight-junit.xml"
shiplight_pr_gate:
stage: test
image: alpine:3.20
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
before_script:
- apk add --no-cache bash curl ca-certificates
script:
- echo "Running Shiplight PR gate suite for MR..."
- ./shiplight run --suite "pr-gate" --junit "$SHIPLIGHT_JUNIT_PATH"
artifacts:
when: always
reports:
junit: $SHIPLIGHT_JUNIT_PATH
paths:
- $SHIPLIGHT_JUNIT_PATH
expire_in: 7 days
allow_failure: false
shiplight_full_regression:
stage: regression
image: alpine:3.20
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
needs:
- job: shiplight_pr_gate
artifacts: false
before_script:
- apk add --no-cache bash curl ca-certificates
script:
- echo "Running Shiplight full regression..."
- ./shiplight run --suite "full-regression" --junit "$SHIPLIGHT_JUNIT_PATH"
artifacts:
when: always
reports:
junit: $SHIPLIGHT_JUNIT_PATH
paths:
- $SHIPLIGHT_JUNIT_PATH
expire_in: 7 days
allow_failure: true
main or nightly for maximum coverage.To actually prevent merges, you need one policy decision in GitLab: merges must require a successful pipeline for the target branch.
Most teams implement this by enabling GitLab’s merge checks so that the default branch cannot be merged into unless the MR pipeline is green. Once that is on, the shiplight_pr_gate job becomes your enforcement mechanism.
A practical rule of thumb:
main or release branches.Instant is a product decision as much as a CI decision. The best PR gate suites share a few traits:
If you do this well, developers stop treating CI as a compliance hurdle and start using it as a feedback loop.
Fast feedback only matters if it is readable. A few best practices that improve adoption immediately:
artifacts: when: always so the MR always has test output.You can wire almost any UI framework into GitLab CI, but most teams eventually hit the same wall: maintenance overhead and flaky signal. Shiplight is designed to avoid that trap:
The best way to block merges is the way your team will keep turned on six months from now. That is ultimately a reliability and maintenance problem, not a YAML problem.
If you want this live quickly without boiling the ocean:
When you are ready, Shiplight can go further by generating tests from PR diffs, expanding coverage automatically, and keeping the merge gate aligned with what changed.