Verify · Source Control
GitLab
Configure merge request verification, GitLab CI previews, Review Apps, and merge protection.
On this page
Test the user journeys affected by a GitLab merge request, using its exact source commit, and keep one results note and commit status current. Configure the project once, then run automatically on updates or request a manual rerun.
Connect and configure a GitLab project
You need GitLab and Verify enabled for your organization and administrator access in Composal. GitLab.com projects use the same scenario selection, preview admission, run history, findings, recordings, and feedback as GitHub PRs. Connect GitLab through Repositories → Import → GitLab, authorize Composal, and import the project. Your GitLab account needs Maintainer or Owner access to manage the signed project webhook, read merge requests and diffs, write notes, and publish commit statuses. OAuth uses the api scope. Self-managed GitLab instances are not currently supported.
Wait for the import to become Ready before configuring verification. If a repository worker is starting or capacity is temporarily unavailable, the import stays queued and retries automatically at the same repository. A failed import displays its error; resolve the cause and use Retry. Pausing an import stops further progress until you resume it.
- Prepare a scenario pack for the connected Composal repository, with journeys, personas, and observable outcomes. Map product areas to source paths and dependencies for focused selection.
- Prepare a ready external Verify environment template for the same repository. Its personas, credential references, and safety policy carry over to each MR URL. Confirm that a browser can reach and sign in to the preview.
- Open Verify → Integrations → GitLab at
/{org}/verify/integrations/gitlab. Choose the project, including its group/subgroup path, its scenario pack, and its environment template. - Choose a preview source below. Use Advanced Settings for excluded paths, 1–20 concurrent browsers, and a 30–3,600 second time budget; organization limits still apply. Select Save Settings before starting a manual run.
- Enable Automatic Verification for MR updates. Use Verify an MR for an existing MR, then Rerun verification on its history page for another run.
Members can view settings. Administrators can save them and start runs; the configuring user must retain administrator access for automatic runs to continue. Repository-specific links use ?repository_id={repository_id}. Switching repositories or leaving the page prompts you to keep or discard unsaved edits.
Saving upgrades the project's existing signed webhook to receive MR events as well as source pushes. Automatic verification responds to MR updates, including new commits, reopening, and becoming ready for review. Draft, closed, and merged MRs cannot start a new browser run. Manual verification remains available when automatic updates are off.
Choose a preview source
Choose where the ready deployment of the MR source commit comes from:
- Your CI: deploy the exact MR source commit, wait until its preview is ready, then hand off the URL or a ready Verify environment using the helper below.
- GitLab Environment: configure the GitLab environment name, such as
review/{branch_slug}orreview/mr-{mr}.{mr}expands to the MR IID,{branch}to its source branch, and{branch_slug}to GitLab’s lowercase, normalized, 63-character ref slug. Verify uses only an available, non-production environment with a successful latest deployment whose SHA matches the current MR head and an external URL. Use a separate review environment for each MR; a shared environment's newer deployment cannot verify an older commit. - Composal Preview: select an existing preview profile and entry service. The exact MR source commit must be available in the connected Composal repository. Verify provisions, deploys, and waits for that revision before testing.
Select the affected journeys
Verify compares changed paths and available hunks with your scenario pack’s product areas and dependencies. Configure Advanced Settings → Paths That Need No Browser Testing for explicit exclusions, such as docs/** and README.md. A request is skipped only when every changed path, including rename sources, matches those exclusions. See how selection works.
Incomplete GitLab file listings broaden selection to the full scenario pack. A truncated or oversized diff cannot accidentally qualify for a documentation-only skip. Rename sources count as changed paths.
Use the GitLab CI helper
Include the versioned template in your project's .gitlab-ci.yml, extend .composal-verify, and run it after your deployment job. Store an administrator Composal API token as a masked GitLab CI/CD variable named COMPOSAL_TOKEN. Do not put the token in YAML or artifacts. Protected variables are available only to pipelines GitLab allows to access them; use a dedicated test organization token appropriate for your trusted MR branches. Fork pipelines must not receive it.
include:
- remote: https://composal.ai/ci/verify/v1/gitlab.yml
# Your existing deployment job must deploy CI_COMMIT_SHA and wait for readiness.
# Export its ready URL as PREVIEW_URL in a dotenv artifact.
# deploy-preview:
# stage: deploy
# ...
# artifacts:
# reports:
# dotenv: preview.env
verify-preview:
extends: .composal-verify
# Keep these rules directly in this file to enable MR pipelines.
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_EVENT_TYPE == "detached" && $CI_PROJECT_ID == $CI_MERGE_REQUEST_SOURCE_PROJECT_ID && $CI_PROJECT_ID == $CI_MERGE_REQUEST_PROJECT_ID'
needs:
- job: deploy-preview
artifacts: true
variables:
COMPOSAL_ORG: my-org
COMPOSAL_REPOSITORY: my-composal-repo-slug
COMPOSAL_PREVIEW_URL: $PREVIEW_URL
GitLab identifies the MR target project with CI_MERGE_REQUEST_PROJECT_ID. The rules require both the source project and MR project to match the pipeline project, keeping the token-bearing job out of fork pipelines.
Replace deploy-preview with your deployment job, and use the connected Composal repository slug, which can differ from the GitLab project name. The helper uses Node 24 and the final .post stage, reads the MR IID and source SHA from GitLab, requests verification, supplies the ready preview, and waits for its own run. Failed, blocked, cancelled, superseded, and timed-out results fail the CI job. Passed and explicitly skipped runs succeed. Its composal-verify.json artifact contains result links and IDs, without the token or preview URL.
| Variable | Purpose |
|---|---|
COMPOSAL_TOKEN | Administrator API token; masked CI/CD variable. |
COMPOSAL_ORG | Composal organization slug. |
COMPOSAL_REPOSITORY | Connected Composal repository slug; defaults to CI_PROJECT_NAME. |
COMPOSAL_PREVIEW_URL | Ready URL serving the exact MR source commit. |
COMPOSAL_ENVIRONMENT | Ready Verify preview environment slug, instead of a URL. Its revision must attest the MR source SHA. |
COMPOSAL_VERIFY_WAIT | true by default. false returns after handoff and does not wait for a verdict. |
COMPOSAL_VERIFY_TIMEOUT | Wait timeout in minutes, 1–60; defaults to 15. Verification continues if the job times out. |
Use ordinary detached MR pipelines. Merged-results pipelines and merge trains deploy a synthetic merge commit, so this helper rejects them rather than claiming their preview covers the MR source head. The included job runs only for source branches in the connected project. If you override its rules, the helper still rejects fork pipelines and other pipeline types before calling Composal. Use MR rules for your deployment job too. If your project already defines workflow: rules, allow merge_request_event there and preserve your existing branch and tag rules. Configure workflow rules to avoid duplicate branch and MR pipelines.
For a custom Node-based job, download https://composal.ai/ci/verify/v1/verify.mjs and https://composal.ai/ci/verify/v1/gitlab.mjs into the same directory, then execute node gitlab.mjs with the variables above. Pin the remote include's integrity hash in GitLab when your organization requires immutable includes.
Use the com CLI or API
Install the CLI. For local use, run com login, then select your organization with com context switch my-org. CI uses its secret store instead of an interactive login: expose the Composal token as VEX_API_TOKEN, and pass --org and --repo explicitly. See CLI configuration.
Use com verify merge-requests --help to check support for the MR command. The existing pull-requests spelling remains compatible with a configured GitLab repository. The examples use MR 45, organization my-org, and the connected Composal repository slug my-repo.
Start an existing MR using its saved preview source:
com verify merge-requests run 45 --org my-org --repo my-repo \
--idempotency-key mr-45-review-1 --json
For a CI-owned ready Verify environment, pin the deployed source SHA on the request and handoff:
com verify --org my-org --repo my-repo merge-requests run 45 \
--head-sha "$CI_COMMIT_SHA" --idempotency-key "gitlab-$CI_PIPELINE_ID" --json
com verify --org my-org --repo my-repo merge-requests preview 45 \
--head-sha "$CI_COMMIT_SHA" --environment mr-45 --json
run creates a verification request using the saved preview source. In CI, --head-sha refuses an outdated pipeline before it can request a newer revision. Run preview only after its Verify environment is ready and records the full deployed SHA in source_revision. Keep that preview alive through browser execution and cleanup. Reuse an idempotency key to retry an uncertain response; use a new key for an intentional rerun.
Inspect the stable MR ID returned by run, then follow its browser sweep when one exists:
com verify merge-requests get <mr-id> --org my-org --json
com verify sweeps get <sweep-id> --org my-org --repo my-repo --json
com verify sweeps watch <sweep-id> \
--org my-org --repo my-repo --timeout-seconds 900 --json
A successful submission means accepted. sweeps watch succeeds when the sweep becomes terminal, even when assertions fail. Use the GitLab CI helper's default waiting behavior to gate a job, or explicitly inspect the final outcome. Skipped and blocked requests can finish before a sweep exists.
The API also exposes POST /api/v1/organizations/{org}/verify/merge_requests, POST .../merge_requests/preview, GET .../merge_requests/{id}, and POST .../merge_requests/{id}/rerun. These routes require a GitLab-configured repository. The request and preview fields match the corresponding pull_requests endpoints. A stale head returns HTTP 409 and cannot hand a preview to a newer run.
Read results and protect merges
Composal maintains one MR note with selection, the tested source commit, outcomes, problems, and links to protected recordings and complete run history. Notes are written as the GitLab account that connected the project; reconnect with that account to retain ownership of its result note. MR !45 and the GitLab group/project identify the source throughout Verify.
The Composal Verify commit status follows the latest run for each source commit. Queued and preview-waiting runs are pending; browser runs are running; passed runs succeed; failed or blocked runs fail; superseded or cancelled runs are cancelled; explicit skips are skipped. When the MR has a matching source pipeline, the status is attached to that pipeline.
For merge protection, enable GitLab's Pipelines must succeed project setting and keep verify-preview blocking with COMPOSAL_VERIFY_WAIT: "true". Verify does not change your project's merge policy. Skipped pipeline behavior depends on your GitLab project settings. Do not override the job with allow_failure: true if its verdict should block merging.
Resolve GitLab setup and CI problems
| What you see | What to check |
|---|---|
| Configuration has no GitLab project | Confirm GitLab is enabled for your organization, the project import is Ready, and the connecting account retains administrator access in Composal. |
| GitLab Review App never appears | Check the environment name or pattern, non-production tier, available environment, successful latest deployment, exact MR source SHA, and external_url. |
| Waiting for preview | Deploy the current MR source SHA and supply its ready target, or finish the configured Composal preview rollout. After one hour, request a rerun once the preview is ready. |
| Stale or conflicting handoff | Use the current MR head. Retry the same target for the same request; request a new run to intentionally change targets. A stale head returns HTTP 409. |
| CI token is unavailable | Check masked/protected variable access for the trusted MR branch. Fork pipelines must not receive the token. |
| Helper rejects the pipeline | Use detached MR pipelines in the connected source project. Merged-results pipelines and merge trains use synthetic merge commits. |
| Missing results note or commit status | Check OAuth connection health, the connecting account's GitLab permissions, and the configuring user's Composal administrator access. Reconnect with the same GitLab account to retain note ownership. |
| Login or access blocker | Check preview visibility, personas, and credentials before treating the result as an application defect. |
| CI wait timed out | Open the returned run-history link. The server run continues; increase the helper and job timeouts for later runs. |
merge-requests is unrecognized | Install the current CLI or use the compatible pull-requests spelling. |
Continue with the Source Control overview, scenario setup, or preview hosting guide.