This article explains why the merge button on a pull request is disabled, and why a failed pipeline can sometimes still be merged. After reading it, you can add on: pull_request and checkContext in the YAML so the pipeline runs on its own and writes the result back to the status check. To make “must pass” a rule that nobody can go around, put the same check name into branch protection.
A status check is a card on the pull request conversation page. Each row is one check: the name on the left, and Pending, Success, or Failed on the right. Pipelines are available on Team and Enterprise. Community has no CI/CD menu, and the steps in this article do not apply there.
The screenshots later in this article are from pull request #1 of xlliu/test-cicd-example. The source branch is verify-pr-sc0204, and the target branch is main.
1. Add a pull_request trigger in the YAML
version: "1"
name: ci
checkContext: ci
triggers:
- on: push
branches: [main]
- on: pull_request
branches: [main]
pipeline:
build:
runner:
mode: DOCKER
image: repo.anguskit.com/docker-public/angus-ci-maven:21
labels: ["linux", "docker"]
steps:
- name: Build and test
run: mvn -B -ntp clean verify
timeout: 1800
The block above is the smallest form. The check name is shown as ci. The two check names in the later screenshots come from two other real files in the repository, .anguscicd/02-matrix-build.yaml and .anguscicd/04-monorepo-change.yaml. They are not this ci.
Two places matter for a pull request:
-
on: pull_requestandbranches: [main]. Herebranchesmatches the pull request’s target branch, not the source branch. The lines above mean: every pull request that wants to merge intomainruns this pipeline. The source branch can have any name. -
checkContext: ci. This is the check name this pipeline writes back onto the pull request. When it is omitted, the pipeline name is used. Branch protection later has to be filled with the identical name, so write it explicitly. Renaming the pipeline later then leaves branch protection alone.
The pipeline reads the YAML on the pull request’s source branch. Editing an existing pipeline’s YAML on the source branch means this pull request runs the edited version. You can try the new config in the pull request and merge after it looks right. The pipeline has to exist already under CI/CD → Pipelines. A brand-new YAML that exists only on the source branch does not create a pipeline by itself.
2. When it runs
After the trigger is added, opening the pull request page does not start a new run every time. Common actions:
| What happened | Does it trigger? | Notes |
|---|---|---|
A pull request is opened to merge into main
|
Yes | The target branch matches branches: [main]
|
| New commits are pushed to this pull request’s source branch | Yes | It runs again on the latest commit and updates the status check |
| The pull request is closed and then reopened | Yes | The status check is triggered again |
| A draft pull request is opened | Yes | A draft cannot be merged, and the pipeline still runs |
| Mark ready for review is clicked on a draft pull request | Depends on whether it already ran | If that commit already ran while it was a draft, it does not run again |
| The same commit has already run once | It does not run again | You can click Re-run on the run detail |
The pull request is merged into another branch such as develop
|
No | Unless branches also lists that target branch |
3. Where to see the result
Open the pull request’s conversation page and you see the Status checks card described above. Each row has the check name on the left (for example ci) and Pending, Success, or Failed on the right.
Pull request #1 in the example has two successful status checks: .anguscicd/02-matrix-build.yaml and .anguscicd/04-monorepo-change.yaml. The merge card still says “This pull request is not ready to merge”. The reason on the card is “Reviews are still pending and must be approved before merge”. Merge pull request is disabled. When a check fails, the same card changes to “All required status checks must pass”, and the description text is Job(s) failed.
The merge card lower on the page lists these checks as “name - description”, for example ci - Pipeline passed or ci - Job(s) failed. The description text is English. It is written when the pipeline finishes.
A status-check row cannot be clicked through to the pipeline. To see which step failed, go to CI/CD → Pipelines, click this pipeline’s name, filter Trigger to Pull request in Runs, find the latest run for that branch, and open it to read the jobs and the log. How to find the error in the log is in the pipeline-failure article linked at the end.
4. Can you still merge when it is red?
Start with the merge button on the page. If any check on the pull request is not Success — Pending counts — the merge card shows “This pull request is not ready to merge” and “All required status checks must pass”, and the merge button is unavailable. For someone merging through the page, a red pipeline cannot be merged.
That limit is on the page. Whether a merge through the API is blocked, or a repository administrator can merge while Include administrators is off, depends on branch protection. To make “the pipeline must pass” a rule that nobody can go around, configure it as follows.
-
Open branch protection
Open the repository Settings → Branch Protection and edit the rule for
main. If there is no rule yet, create one. -
Require status checks
Turn on Require status checks. The description is “All status checks must pass before merging”. In Required status check contexts, enter
ci. When several pipelines must all pass, separate the names with commas, for exampleci,lint. - Apply it to administrators Turn on Include administrators. The description is “Enforce protection rules for repository administrators as well; admins cannot bypass”. With it off, a repository administrator can merge through the API and go around the protection rule.
- Save Save the rule. In the rule list, this rule shows the Require status checks mark.
The picture is Add branch protection rule for xlliu/test-cicd-example. The branch is main, Require status checks is on, and Required status check contexts lists .anguscicd/02-matrix-build.yaml, .anguscicd/04-monorepo-change.yaml. Include administrators is on. Allow force pushes and Allow deletions stay off. Require branches to be up to date is off. This repository had no saved rule yet. The picture is the form before Add rule is clicked. The names in the box are the two checks already on pull request #1. They are the pipeline file names. When your YAML sets checkContext: ci, type ci in that box instead.
After it is configured:
- The check name has to match Required status check contexts exactly, including case. If the YAML says
checkContext: ci, entercihere. - If the pipeline has not started, or it never triggered, this check is shown as pending. The message is
Waiting for the CI/CD pipeline to run. The pull request cannot be merged. The name you enter has to belong to a pipeline this pull request will actually trigger. - If Require status checks is on and Required status check contexts is left empty, the rule blocks no merge.
Repository Settings → Pull Requests also has a Require status checks switch. Its description is “Require all status checks to pass before merging”. The item that takes effect at merge time today is the one in branch protection. Configure branch protection.
5. The pipeline is red. How do you make it green?
While the check is still red, separate a code failure, a one-off failure, and a job that is still waiting for a runner (the program on a build machine that actually runs the job).
| What you see | Why | What to do |
|---|---|---|
| The check is Failed, and a test or the compile did not pass | A problem in the code itself | Change it on the source branch, commit, and push. A new run starts on its own |
| A one-off failure, for example a network blip while downloading dependencies | The environment around the job blipped | Open that latest run and click Re-run |
| It stays Pending | The job is waiting for a runner | Open that run and read the wait reason next to the job |
The status checks have no ci row at all |
The pipeline was never created, it is not enabled, or branches does not include the target branch |
Under CI/CD → Pipelines, confirm the pipeline is enabled, and check the target branch under triggers
|
Use Re-run only on the latest run. After a new commit has been pushed, re-running an older commit can write that older result over the current check status.
Common questions
Reviews and the pipeline both have to pass. Is there a required order?
No. They run at the same time and are judged separately. A reviewer can start reading the code while the pipeline is still running. At merge time, both the review condition and the status checks have to be satisfied.
A repository has several pipelines. Do they all show up in status checks?
Yes. Each pipeline this pull request triggers is one row, using its own checkContext or its name. Branch protection forces only the names filled into Required status check contexts. The merge button on the page still requires every check that is already shown to be a success.
A draft pull request also runs the pipeline. Does that waste capacity?
It does use some runner time. The benefit is that the author can see the pipeline result before the pull request is marked ready for review. The same commit runs once, so after a draft has run, Mark ready for review usually does not run it again.
Summary
To make a pull request run a pipeline on its own, add on: pull_request under triggers in the YAML, write the target branch in branches, and give the check a fixed name with top-level checkContext. Opening a pull request, pushing new commits, and reopening all trigger it. The result is shown in Status checks. The detailed log is under CI/CD → Pipelines → Runs. On the page, a merge is blocked while any shown check is not a success. To make the rule apply to the API and to administrators as well, turn on Require status checks in branch protection, enter the same check name, and turn on Include administrators.
Conclusion: In the pipeline YAML, set
on: pull_request(branchesis the target branch) andcheckContext: ci. Onmainbranch protection, turn on Require status checks, enterci, and turn on Include administrators. A merge is then allowed only after the pipeline has passed.



Top comments (0)