[improve][ci] Gate CI in apache/pulsar on the pull request being ready for testing - #26323
Merged
Merged
Conversation
…y for testing ### Motivation The `ready-to-test` enforcement was removed in apache#25470, so every pull request opened against apache/pulsar consumes the shared CI quota, including the ones that aren't ready to be reviewed and tested yet. Two cases are wasteful in particular: - Draft pull requests, which are work in progress by definition. - Stacked pull requests (https://docs.github.com/en/pull-requests/how-tos/stacked-pull-requests). A stacked pull request targets the branch of the pull request below it instead of a trunk branch, and it isn't filtered out by the `branches:` filter of the workflow triggers: all layers of a stack currently run the full CI pipeline in apache/pulsar although only the bottom one is mergeable. The changes of the layers below are also included in every upper layer, so the same code is tested repeatedly. Both cases are covered by Personal CI (https://pulsar.apache.org/contribute/personal-ci/), which runs the full pipeline in the contributor's own fork with a separate quota. ### Modifications Add a `check-pr-ready-to-test` composite action which fails the `preconditions` job of a workflow when a pull request isn't ready for consuming the CI resources of apache/pulsar. The action is used by the `Pulsar CI`, `Pulsar CI Flaky` and `CI - Go Functions` workflows, and failing it skips all of the jobs which depend on `preconditions`. The `ready-to-test` label passes the check immediately. Otherwise the check fails when - the pull request is a draft, or - the pull request is part of a GitHub stack and isn't the bottom one, which is resolved with the `stackEntry`/`stack` GraphQL fields of a pull request. When the stack fields aren't available, a pull request that targets a branch which isn't a trunk branch is treated as a stacked pull request. The state of the pull request is read from the API instead of the event payload so that re-running the workflow picks up a label or a review state which was changed after the run was triggered. A failing check writes instructions for proceeding to the job summary. The check is limited to `pull_request` events in the apache/pulsar repository, so it never interferes with running the CI in a fork. Assisted-by: Claude Code (Opus 5)
nodece
approved these changes
Aug 13, 2026
The entries of a GitHub stack keep their position when a pull request of the stack is merged: after apache#26317 was merged, apache#26319 still reports position 2 of stack #26321. Requiring position 1 therefore kept the CI blocked for a pull request which had already become the bottom one. Resolve the bottom of the stack as the lowest entry which is still open, and accept a pull request which targets the trunk branch of the stack as well, since GitHub retargets a pull request when the one below it is merged. Either condition is enough because the retargeting and the stack entries aren't necessarily updated at the same time. Assisted-by: Claude Code (Opus 5)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
The
ready-to-testenforcement was removed in #25470, so every pull request opened againstapache/pulsar consumes the shared CI quota, including the ones that aren't ready to be reviewed and
tested yet.
Two cases are wasteful in particular:
A stacked pull request targets the branch of the pull request below it instead of a trunk branch,
and it isn't filtered out by the
branches:filter of the workflow triggers: all layers of a stackcurrently run the full CI pipeline in apache/pulsar although only the bottom one is mergeable. The
changes of the layers below are also included in every upper layer, so the same code is tested
repeatedly.
Both cases are covered by Personal CI, which
runs the full pipeline in the contributor's own fork with a separate quota.
Modifications
Add a
check-pr-ready-to-testcomposite action which fails thepreconditionsjob of a workflowwhen a pull request isn't ready for consuming the CI resources of apache/pulsar. The action is used
by the
Pulsar CI,Pulsar CI FlakyandCI - Go Functionsworkflows, and failing it skips all ofthe jobs which depend on
preconditions.The
ready-to-testlabel passes the check immediately. Otherwise the check fails whenstackEntry/stackGraphQL fields of a pull request.The entries of a stack keep their position when a pull request of the stack is merged, so the bottom
of the stack is the lowest entry which is still open, not the entry at position 1. For example,
after #26317 was merged, #26319 is the bottom one although it remains entry 2 of stack #26321. A pull
request which targets the trunk branch of the stack is accepted as well, since GitHub retargets a
pull request when the one below it is merged; either condition is enough, because the retargeting and
the stack entries aren't necessarily updated at the same time.
When the stack fields aren't available, a pull request that targets a branch which isn't a trunk
branch is treated as a stacked pull request.
The state of the pull request is read from the API instead of the event payload so that re-running
the workflow picks up a label or a draft state which was changed after the run was triggered. A
failing check writes instructions for proceeding to the job summary, including a reference to the
Personal CI documentation.
The check is limited to
pull_requestevents in the apache/pulsar repository, so it never interfereswith running the CI in a fork. Documentation-only pull requests are exempt, since they don't run the
test jobs in the first place.
Compared with the check that was removed in #25470, the "pull request has been approved" bypass is
not restored: only the
ready-to-testlabel overrides the check.Verifying this change
This change is a CI-only change without test coverage in the repository. It was verified as follows:
without the label, stack positions 1/2/3, merged and closed entries below the pull request, a
retargeted base branch, a draft that is also a stack layer, a missing
stackEntry, an unavailablestack API,
master/branch-*/pulsar-*base branches, a non-trunk base branch, and the labeland trunk-branch inputs.
@actions/core.(merged) and [improve][client] PIP-478: Athenz and SASL v5 authentication plugins #26319 (open, entry 2, the lowest open one) are allowed to run the CI, [improve][misc] PIP-478: remove the superseded PIP-337 TLS stack #26322 (open,
entry 3, above an open pull request) is blocked, and [improve][ci] Gate CI in apache/pulsar on the pull request being ready for testing #26323 isn't in a stack and is allowed.
preconditionsjob is expected to pass.Does this pull request potentially affect one of the following parts:
If the box was checked, please highlight the changes