Documentation / Guides / Merge Checks
Merge Checks
Use WorkerRun as a final merge gate that runs after your CI passes.
A common pattern is to run your full CI pipeline (lint, test, build) on standard runners, then use WorkerRun for a lightweight final check before merging. Because the merge gate only needs to call the GitHub API, it completes in milliseconds on a V8 isolate — no VM spin-up required.
Note: This example uses actions/github-script@v8 for inline JavaScript. WorkerRun also supports run: steps with 80+ built-in shell commands (echo, curl, jq, grep, sed, etc.) in V8 mode, and full bash in container mode. See Supported Actions for details.
Full Workflow
.github/workflows/merge-check.yml
name: Merge Check
on:
pull_request:
types: [opened, synchronize, labeled, unlabeled]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: bun run lint
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: bun test
merge-gate:
runs-on: worker-run
needs: [lint, test]
steps:
- name: Check merge readiness
uses: actions/github-script@v8
with:
script: |
const { data: pr } = await github.rest.pulls.get({
...context.repo,
pull_number: context.issue.number,
});
const labels = pr.labels.map((l) => l.name);
if (!labels.includes("ready to merge")) {
core.setFailed('Missing "ready to merge" label');
return;
}
if (pr.mergeable_state === "dirty") {
core.setFailed("PR has merge conflicts");
}How It Works
- 1.The
lintandtestjobs run onubuntu-latestas normal CI. - 2.
needs: [lint, test]ensures the merge gate only runs after both CI jobs succeed. - 3.The script checks that the PR has the
ready to mergelabel and has no merge conflicts. - 4.If either check fails, the job fails and the PR cannot be merged (when configured as a required status check).