Skip to content

fix(gitlab): a failed child pipeline no longer shows as a passing check - #24688

Merged
maria-rcks merged 3 commits into
pingdotgg:mainfrom
only21mil:fix/c090-05-whole-pipeline-collapses-into-one-check
Oct 31, 2026
Merged

maria-rcks merged 3 commits into
pingdotgg:mainfrom
only21mil:fix/c090-05-whole-pipeline-collapses-into-one-check

Conversation

@only21mil

Copy link
Copy Markdown
Contributor

Problem

A GitLab trigger job without strategy: depend succeeds as soon as it starts its child pipeline. If the child then fails, head_pipeline.status stays success. T3 Code turns that one status into its only GitLab check, so the merge request reads "All checks passed" while the child pipeline is red. This is the false pass in #13431.

Change

The merge request detail makes one more read, the head pipeline's trigger jobs (GET /projects/:id/pipelines/:pipeline_id/bridges?per_page=100). Each trigger job that started a downstream pipeline adds one check named after the job, with the downstream pipeline's status and link. The existing "Pipeline" check is unchanged.

  • The read uses head_pipeline.project_id and head_pipeline.id, so a fork's pipeline is read from the project it ran in.
  • It is best-effort. A failed read or a full page adds no rows, and the detail looks the same as today.
  • A downstream failure on a trigger job with allow_failure: true reads as neutral, like manual, so it does not mark the merge request as failing.
  • A trigger job with no downstream pipeline yet adds no row. [Bug]: GitLab merge requests show the whole pipeline as one check #13431 suggested showing the trigger job's own status there; without per-job checks that status already counts toward the Pipeline check, so this leaves it out.
  • No per-job checks, job pagination or caching. Only the detail and checks reads make the extra call; the permission check before each write and the reviewer reads skip it.
  • It asks for bridges, not trigger_jobs. GitLab 19.2 deprecates the old name but still serves it, and older self-managed installs only know bridges.

With a failed child pipeline the header now reads "1 of 2 failing" while GitLab's own pipeline badge is still green. That is the fix, and it is a check-semantics change.

Scope and approval

Fixes the false pass in #13431, a triaged bug labeled accepted. A maintainer confirmed it there, said the child failure shows only if the trigger row uses downstream_pipeline.status, and called a red header beside GitLab's green badge "the right reading of this issue". They asked for the extra read to stay best-effort inside the detail read, falling back to today's "Pipeline" check.

#13434 built all of #13431, per-job checks included, and was closed as too large, with a request to agree check semantics in an Ideas discussion and propose a much smaller fix. This is that smaller fix: one read, no per-job checks, pagination or caching. No Ideas discussion exists yet, so the semantics above await maintainer review. If you would rather settle them in a discussion first, I'm happy to move it there. Per-job checks and the list row's missing check state are out of scope.

Verification

In packages/source-control-gitlab:

  • vp test run src/server/GitLabPullRequestCli.test.ts src/server/gitLabMergeRequestJson.test.ts: 75 passed. On main 3afb9b366f, 3 fail. The regression test, "shows a failed child pipeline that left the head pipeline green", fails because the detail has only the green "Pipeline" check. The other two cover the fallback and the allow_failure path, which don't exist on main. A fourth test checks that the detail read skips the trigger jobs when the permission check opts out. It passes on main, which never reads them, and fails here if the opt-out stops skipping that read.
  • The provider, rate-limit and legacy CLI test files: 22 passed.
  • Package typecheck, and lint and format on the five changed files: clean.

The focused tests on main, with the regression test's diff.

Focused tests failing on main

The same tests on this branch.

Focused tests passing on this branch

For the web captures, a dev server ran against a stub glab serving one merge request: a green head pipeline and one trigger job whose child pipeline failed. Before, with no trigger job read in the stub's log:

Before: one passing Pipeline check and All checks passed

After, with the bridges read in the stub's log:

After: Pipeline passed, deploy-preview failed, 1 of 2 failing

The desktop app (a Linux dev build), the iOS 26.5 simulator and the Android 16 emulator then opened the same merge request from their pull request lists, against the same stub. Each before capture used main's server and each after capture used this branch's. The app code is the same in both, since only the server changed.

Desktop before: only the Pipeline check, passed, and All checks passed.

Desktop before: only the Pipeline check, passed, and All checks passed

Desktop after: Pipeline passed, deploy-preview failed, 1 of 2 failing.

Desktop after: Pipeline passed, deploy-preview failed, 1 of 2 failing

iOS before: All checks passed, 1 of 1, with only the Pipeline check.

iOS before: All checks passed, 1 of 1

iOS after: 1 check failing; deploy-preview, a downstream pipeline, failed; Pipeline passed.

iOS after: 1 check failing, deploy-preview failed

Android before: All checks passed, 1 of 1, with only the Pipeline check.

Android before: All checks passed, 1 of 1

Android after: 1 check failing; deploy-preview, a downstream pipeline, failed; Pipeline passed.

Android after: 1 check failing, deploy-preview failed

Not checked:

Prior PRs

Production fix, tests, PR description and images by Claude Opus 5.5 in T3 Code Nightly.

🤖 Generated with Claude Opus 5.5 in T3 Code Nightly

only21mil and others added 3 commits October 24, 2026 16:49
A trigger job without `strategy: depend` succeeds as soon as it starts its
downstream pipeline, so the merge request's head pipeline, and its one
"Pipeline" check, stay green when that pipeline fails.

The merge request detail now reads the head pipeline's trigger jobs once,
best-effort, and adds one check per trigger job carrying its downstream
pipeline's status and link. A failed read or a full page adds no rows.

Refs pingdotgg#13431

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… job read

getViewerPermissions read the merge request through the detail read that now also
fetches the head pipeline's trigger jobs, so every write and picker waited on a
second glab api call whose checks it threw away. It now reads the merge request
alone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…d on the detail call

Drops the separate getMergeRequestPermissions CLI method. getMergeRequestDetail takes an
optional downstreamChecks flag instead, and getViewerPermissions passes false, so the
provider keeps calling the same CLI method it calls on main and a mock of that service
needs no new member.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 25, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

Only developers with an assigned seat can use this organization's usage-based review budget, and seats here are assigned manually. Ask an admin to assign a seat, or change the review continuation mode in Billing.

Next included review available in 12 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used all 10 included reviews currently available.

Learn how review limits work.

Review configuration:

Run configuration
Commits

Reviewing files that changed from the base of the PR and between 24c80f3 and 3109b62.

Files selected for processing: 5
  • packages/source-control-gitlab/src/server/GitLabPullRequestCli.test.ts
  • packages/source-control-gitlab/src/server/GitLabPullRequestCli.ts
  • packages/source-control-gitlab/src/server/GitLabPullRequestProvider.ts
  • packages/source-control-gitlab/src/server/gitLabMergeRequestJson.test.ts
  • packages/source-control-gitlab/src/server/gitLabMergeRequestJson.ts
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Oct 25, 2026
@macroscopeapp

macroscopeapp Bot commented Oct 25, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 3109b62

Macroscope's review found this PR approvable — This is a contained GitLab bug fix that adds downstream-pipeline status to the existing merge-request checks, while preserving the prior result when the optional read fails or is incomplete. The change is isolated to GitLab parsing/provider logic and includes regression and fallback tests.

You can add or adjust custom eligibility rules. Learn more.

Copy link
Copy Markdown
Collaborator

Note

Written by gpt-6.1-sol on behalf of Maria

Verified in a real dev environment

result: unverifiable on this vm. no changed application behavior was verified.

inspected the description, discussion, commits and production diff for head 3109b622512b39822b8f9bcccc521eb256f6c1ff. the pr is open and none of its commits are authored by juliusmarminge or t3dotgg. github reports passing checks, which i have not treated as runtime proof.

created a separate github/main worktree at 32ecd71726fee16f335484c1f95cbce126d461f6 and ran vp i successfully. checked out the exact pr head and ran vp i successfully. installed the missing real glab executable, then checked gitlab authentication:

$ glab auth status
gitlab.com: GET https://gitlab.com/api/v4/user: 401 Unauthorized
No token provided

$ glab api user
{"message":"401 Unauthorized"}

prerequisite command transcript

Not verified

there is no configured gitlab authentication or task-owned gitlab project available to create a real merge request with a successful parent pipeline and failed child pipeline. that blocks the original bug reproduction on main and the after comparison through the running app. no dev server or provider turn was started, and no screenshots or recording were captured. no mocks, fixtures or stub glab were used.

the downstream failure row, allowed-failure neutral status, successful/no-child case, best-effort fallback, and merge permission path remain unverified at runtime. native mobile, desktop, macos and windows were not exercised. codex access alone cannot supply the required live gitlab pipeline state.

resuming requires authenticated gitlab access to a project with working ci where these pipeline states can be created. no source changes or pushes were made.

Copy link
Copy Markdown
Collaborator

Note

Written by gpt-6.1-sol on behalf of Maria

Verified in a real dev environment

result: unverifiable. no changed application behavior was verified in this attempt.

read the description, discussion, commits and production diff for head 3109b622512b39822b8f9bcccc521eb256f6c1ff. the pr remains open; none of its three commits are authored by juliusmarminge or t3dotgg. git.cafe reports 28 successful checks, zero failing and zero pending. those checks are not runtime proof.

created the separate github/main worktree at 6fc9144a60c4a5f45089316ddd5f7371bafd3bf2 and installed its dependencies. checked out the exact pr head. installed the real glab executable and checked live gitlab access:

$ glab auth status
gitlab.com: api call failed: GET https://gitlab.com/api/v4/user: 401 Unauthorized
No token provided
$ glab api user
{"message":"401 Unauthorized"}

uploaded command transcript

Not verified

there is no configured gitlab authentication or supplied task-owned gitlab project with runnable ci. the required main reproduction needs a real merge request whose successful parent pipeline started a failed child pipeline. without access to create that state, neither the original false pass nor the pr correction could be exercised. no dev server, browser scenario or codex turn was started. no mocks, fixtures or demo data were used, and no screenshots or recording are claimed.

the downstream failure check, allowed-failure neutral result, successful/no-child case, best-effort fallback and permission-read behavior remain unverified through the running app. native mobile, desktop, macos and windows were not exercised. codex proxy access cannot provide the missing gitlab pipeline state.

no source changes or pushes were made. resuming requires authenticated gitlab access to a task-owned project with working ci.

@maria-rcks
maria-rcks merged commit 4146e51 into pingdotgg:main Oct 31, 2026
28 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M 30-99 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants