GitLab Merged Results Pipelines
GitLab's merged results pipelines run against the result of merging the source and target branches, rather than against the source branch alone. This catches integration issues that branch-only pipelines miss.
Unfortunately, GitLab does not expose an API for third-party CI platforms to participate in merged results pipelines directly. GitLab only supports one top-level pipeline per merge request and exposes no webhook or trigger that fires against the merged-result SHA, so the only way to run RWX against the merged result is to dispatch the RWX run from a job inside the GitLab pipeline.
By incorporating RWX runs into a merged results pipeline:
- RWX tests the merged result, rather than the branch tip.
- Run status is reported on the top-level pipeline for each merge request, rather than buried in a secondary pipeline.
This requires two changes: dispatching the RWX run from your GitLab CI configuration, and updating your RWX run definition to accept that dispatch.
Dispatch RWX from .gitlab-ci.yml
Add a job to your .gitlab-ci.yml that dispatches an RWX run and waits for it to finish, keeping the GitLab pipeline in an "in progress" state until the run completes:
kick-off-rwx:
image: ubuntu:24.04
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
before_script: |
if [ -z "$RWX_ACCESS_TOKEN" ]; then
echo "RWX_ACCESS_TOKEN is not set"
exit 1
fi
apt-get update && apt-get install -y --no-install-recommends curl ca-certificates jq
script: |
curl -fsSL https://github.com/rwx-cloud/rwx/releases/download/latest/rwx-linux-x86_64 > rwx
chmod +x rwx
title="CI: ${CI_MERGE_REQUEST_TITLE:-$CI_COMMIT_TITLE}"
dispatch_result=$(./rwx dispatch merge-request-pipeline --ref $CI_COMMIT_SHA --title "$title" --wait --json) || exit_code=$?
run_url=$(echo "$dispatch_result" | tail -1 | jq -r '.RunURL')
echo "RWX run finished. See $run_url"
exit 0
A few notes on this snippet:
- The
if: $CI_PIPELINE_SOURCE == "merge_request_event"rule scopes the job to merge request pipelines. - The
before_scriptinstallscurl,ca-certificates, andjq. If you maintain your own base image, consider moving these dependencies upstream so the job can skip the install step. RWX_ACCESS_TOKENmust be set as a pipeline variable. Create one from Access Tokens.merge-request-pipelineis the dispatch key — it must match thekeyin the RWX run's dispatch trigger (covered below).- The "kickoff" job always exits successfully. RWX reports its own status check on the merge request, so the run's pass/fail surfaces there instead. Clicking through to RWX gives much richer context than the GitLab job logs would.
Configure a dispatch trigger in RWX
Configure your RWX run definition to use a dispatch trigger instead of the GitLab merge request trigger. The dispatch trigger only fires when the merged results pipeline calls it, so the run only ever tests the merged result.
on:
dispatch:
key: merge-request-pipeline
status-checks: true
init:
commit-sha: ${{ event.git.sha }}
keymust match the key passed torwx dispatchin.gitlab-ci.yml(merge-request-pipelinein this example).status-checks: trueopts the dispatched run into reporting status back to the GitLab pipeline. Status checks are on by default for GitLab merge request triggers, but opt-in for dispatched runs.commit-shapulls the merged-result SHA out of the dispatch event so downstream tasks can check out the right commit.
Make sure your git/clone task uses that init parameter, so it clones the merged result rather than the branch tip:
tasks:
- key: code
call: git/clone 2.0.7
with:
repository: [email protected]:YOUR_ORG/YOUR_REPO.git
ref: ${{ init.commit-sha }}
ssh-key: ${{ gitlab['YOUR_ORG/YOUR_REPO'].ssh-key }}