Repository navigation
Conversation
jerryshao
left a comment
There was a problem hiding this comment.
Automated review pass on the Required CI aggregation. Found a critical concurrency-group regression that affects all 13 aggregated suites, plus a lost path filter, a broken PR coverage-comment trigger, a serialization issue on the parent orchestrator, and an unrelated design doc bundled into this PR. Details inline.
Additional finding not anchorable inline (.github/workflows/coverage-comment.yml is not part of this diff, so it can't be commented on directly):
correctness: this workflow_run: workflows: ["build"] trigger (guarded elsewhere by github.event.workflow_run.event == 'pull_request') will never fire again for PRs, because build.yml no longer runs as a directly-triggered top-level workflow for pull_request events — only nested via workflow_call from required-ci.yml — and GitHub Actions does not generate a matching workflow_run completion event for a workflow invoked via workflow_call.
Every future PR's build job now only executes as part of the Required CI run, not as a standalone build workflow run triggered by pull_request; the only surviving direct trigger for build.yml is push. This event == 'pull_request' condition can then never be satisfied, silently and permanently disabling the PR coverage-report comment feature. Worth noting the PR's own test plan lists this as an unverified risk — seems worth resolving before merge rather than leaving as a known gap.
…CI check Add required-ci.yml as the sole pull_request listener that fans out to the public CI suites via workflow_call and aggregates all results into one Required CI check. Each suite gains a workflow_call trigger with a required_ci input and loses its direct pull_request trigger (parent is the sole listener, avoiding duplicate runs); push triggers and path-based skips are unchanged. conflict-marker-check and asf-allowlist-check stay standalone. This gives main one enforceable check a ruleset can require, gating merges on CI and enabling auto-merge. Foundation for the CI speed epic (apache#3834). Co-authored-by: Cursor <cursoragent@cursor.com>
…ress false) The parent's cancel-in-progress: true cancelled Required CI runs mid-flight when multiple pull_request events fired for the same PR (opened/synchronize), leaving a failed Required CI check and blocking the PR. Set cancel-in-progress: false so a run, once started, completes and reports a stable aggregate. Also restrict pull_request types to [opened, synchronize, reopened] to cut redundant runs (upstream has no opt-in label). Co-authored-by: Cursor <cursoragent@cursor.com>
When called via workflow_call from required-ci.yml, all 14 child suites shared the same concurrency group (required-<PR>) with cancel-in-progress: true, so they cancelled each other mid-flight, leaving Required CI red with ~13 cancelled jobs. Add github.workflow to each child's group so they are unique per suite and no longer cancel each other. Co-authored-by: Cursor <cursoragent@cursor.com>
github.workflow is not unique under workflow_call (it evaluates to the same value for all child suites), so the prior fix still left all 14 children sharing one concurrency group with cancel-in-progress: true, cancelling each other before starting (last to start won; web_ui has no concurrency block so it ran fine). Use a literal unique key per suite (required-build, required-backend, ...) so each child's group is truly unique and suites no longer cancel each other. Co-authored-by: Cursor <cursoragent@cursor.com>
e64f3ef to
159e30f
Compare
|
Seems like other CI workflow doesn't run anymore. |
Lock the parent/child workflow contract without starting Actions: fourteen reusable suites, a static always-on Required CI aggregate, unique required concurrency keys, and a standalone conflict-marker check. Co-authored-by: Cursor <cursoragent@cursor.com>
Shared 'standalone' concurrency cancelled every push-to-main suite. Use github.workflow on the standalone path, restore web-ui's internal web/web/** filter, and cancel superseded parent PR runs. Co-authored-by: Cursor <cursoragent@cursor.com>
|
@jerryshao The other suite names no longer show up as their own workflows because they no longer listen on Your Aug 21 review comments are addressed in 5b48b8a:
Nevin |
coverage-comment.yml waited for a standalone build run. PRs no longer start that workflow, so the Jacoco comment would never post. Listen for Required CI instead; the called build still uploads the artifact onto that parent run. Co-authored-by: Cursor <cursoragent@cursor.com>
Required CI printed only failures, so a green check hid whether a suite ran. Print every call result. When the coverage sidecar finds no artifact, log ACTION=skip and the reason instead of failing. Co-authored-by: Cursor <cursoragent@cursor.com>
|
@jerryshao On the coverage-comment finding in your Aug 21 review: We kept the sidecar (fork PRs cannot comment from the If the artifact is missing (path-skip, build failed before upload), the sidecar logs
Nevin |
|
Hi @jerryshao — I addressed your comments. Tip is d5caca4.
Also added Adding @jerryshao @yuqi1129 and @roryqi as reviewers. We are improving CI so PTAL, thanks! If it looks good, please approve. Nevin |
A later ruleset that requires only Required CI plus conflict-marker-check could still merge a red chart or allowlist run. Both are now reusable calls in the aggregate; skipped chart paths still report success. conflict-marker-check stays standalone. The contract script discovers yml/yaml PR listeners and runs from Required CI. Co-authored-by: Cursor <cursoragent@cursor.com>
Cancelled Required CI runs still uploaded coverage-report, and the sidecar trusted a fork-controlled PR number. Skip cancelled runs, resolve the PR from workflow_run, and post only when the live head SHA, repo, and branch match. The comment includes the SHA. Co-authored-by: Cursor <cursoragent@cursor.com>
Move skip/post logic into coverage_comment.py so unit tests can reject cancelled runs and fork PR numbers without GitHub, and keep the sidecar YAML plus jacoco_report.py on the same marker and SHA line. Co-authored-by: Cursor <cursoragent@cursor.com>
workflow_call cannot paths-ignore, so docs-assets-only PRs ran assemble and web-v2 src changes entered the full Gradle build. Restore the old skip via build_relevant.py and gate compile-check and build on it. Co-authored-by: Cursor <cursoragent@cursor.com>
The sidecar checks out trusted coverage_comment.py then downloaded the fork-controlled coverage zip into the same workspace, so a later PR could overwrite that script and run with pull-requests: write. Extract into coverage-artifact/ instead, and refuse to post markdown that lacks the coverage marker or exceeds GitHub's comment size. Push concurrency no longer evaluates workflow_call inputs, which can be undefined on branch builds. An empty changed-file list now fails closed so Required CI cannot go green with no compile or build. urlopen times out; path normalize only strips a literal ./ so .github stays intact. Co-authored-by: Cursor <cursoragent@cursor.com>
|
@jerryshao @yuqi1129 @roryqi @laserninja @bharos I addressed the review feedback. PTAL, and thanks for moving this forward. Roku: Akshay ( #12545 — Since last time: Jerry’s Aug 21 pass was already in. This round is Yuqi’s Aug 31 threads plus follow-up hardening:
Another pass and approve if it looks right. Ready for review, not claiming ready-to-merge until Required CI is green on Nevin |
…w_call github.workflow is the caller name in a reusable workflow, so the old event_name == workflow_call guard collapsed every suite onto Required CI-<pr> and cancel-in-progress kept only one. Hardcode per-suite ids and evaluate them in the caller context. Co-authored-by: Cursor <cursoragent@cursor.com>
|
A callee still sees the caller Each suite now hardcodes a unique group ( Nevin |
What changes were proposed in this pull request?
mainlater gets one stable check namedRequired CI. This PR is the parent that fans out to the 14 public suites and ANDs their results. Suites no longer listen onpull_request; they areworkflow_call+push. Path filters stay inside each suite (dorny). A skipped inner job still makes the reusable callsuccess, so a docs-only PR can stay green.flowchart LR PR["PR opened / synchronize"] --> Parent["Required CI parent"] Parent --> Suites["14 reusable suites"] Suites --> Agg["Required CI job<br/>always(); fail if any call != success"] Agg --> Gate{"later main ruleset"} Gate -->|green| Merge["merge"] Gate -->|red or missing| Block["block"]Review follow-ups already in this branch: unique standalone concurrency (
github.workflow, not a shared'standalone'key),web-ui-testshas an internalweb/web/**filter, parentcancel-in-progress: true, coverage sidecar listens forRequired CIinstead of a standalonebuildrun, and the aggregate prints every suite result.Why are the changes needed?
mainhas no required status checks, so a PR can merge on review alone when CI is red. A failing suite reportsUNSTABLE, notBLOCKED(#12531). One namedRequired CIcheck is what a later ruleset can require, and it is the foundation for the CI speed epic (#3834).Does this PR introduce any user-facing change?
No API or property changes.
Contributor-facing: PRs no longer start 14 top-level suite workflow runs. Suites show as nested checks under Required CI (
build / …,spark / …). Logs are one click deeper.pushtomain/branch-*is unchanged (each suite still starts itself).Coverage comments:
coverage-comment.ymlstill posts from a sidecar (fork PRs cannot comment from thepull_requestrun). It now waits for Required CI, notbuild. Missing artifact →ACTION=skip, sidecar stays green. That listener is loaded from the default branch, so it takes effect after merge. This PR will not get a coverage comment from the new YAML.How was this patch tested?
python3 dev/ci/test_required_ci.py— source contract only; does not start Actions. Locks parent fan-out, unique concurrency, web-ui internal filter, coverage listener name, and the skip path.workflow_runworkflows are loaded frommain, which still listens forbuild. Canary is the next PR after merge.Fix: #12544
Nevin
Sent from my 🤖 (Cursor)
Fixes DAT-643