Conversation
b08c766 to
b274a2e
Compare
andygrove
left a comment
There was a problem hiding this comment.
LGTM but I would like to merge #5842 first so we can unblock setting up the merge queue to reduce CI resource usage. I reviewed this PR assuming that it will go in after #5842.
Once #5842 is in, two things will need to happen on the rebase here:
-
ci.ymlmerges cleanly between the two PRs, but #5842 adds arequired_checksaggregator whoseneeds:must list everyci.ymljob, and a preflight guard incheck-ci-config.pythat enforces it. The merged file fails that guard untilpr_build_linux_checksandbuild_linux_nativeare added torequired_checks.needs. The guard message names them, so the rebase will tell you.build_linux_nativein particular has to be there and cannot be exempted: if the producer fails, GitHub marks all nine consumersskipped, and the aggregator treatsskippedas pass, so without the producer inneedsa broken native build would produce a greenRequired Checks. -
#5842 hardens
Lint Scala (syntactic)against Maven Central connection resets by splitting it into a retriedcs launch scalafix:0.14.6 -- --versionwarm-up followed by the real check undercs launch --mode offline. Since this PR moves that job intopr_build_linux_checks.yml, that split needs to come along. Theiceberg_spark_test_reusable.ymlchange in #5842 (routing the shard-inventory upload throughupload-artifact-retry) merges cleanly onto yourprepare-shardsversion.
After both land, check-ci-config.py will carry two hand-rolled YAML readers (block_mapping here and the line regexes in #5842), both justified by PyYAML not being on the preflight runner. I will open a follow-up issue to install PyYAML in preflight and collapse them rather than leave both in place.
I verified the two-way compatibility locally: your checker passes against a ci.yml that includes the required_checks job, and the #5842 checker passes against your ci.yml once the two ids are added.
|
One more heads-up from the merge-queue side, following on from my review above. #5843 (the PR that actually enables the queue, stacked on #5842) changes That will break Also FYI, |
232560c to
2b6d68d
Compare
andygrove
left a comment
There was a problem hiding this comment.
Three things, all about the rebase rather than the design. The producer and consumer wiring itself looks right to me, and I checked that build_linux_native is the exact union of the nine consumer outputs on this head.
#5852 landed on main after this branch was last pushed, adding a Bootstrap Maven step calling ./.github/actions/maven-bootstrap to five jobs in pr_build_linux.yml. Three of those five are the jobs this PR moves into pr_build_linux_checks.yml, namely lint-java, build-spark-4-1 and celeborn-reflection-compatibility. A rebase cannot carry that step into a file this branch creates from scratch, and pr_build_linux.yml conflicts, so the natural resolution is to take the deletion and lose the retry for those three. The two TPC jobs stay behind and keep theirs. Nothing in check-ci-config.py verifies that a job calling a bare ./mvnw has the bootstrap step ahead of it, so this would be silent until the next Maven Central blip takes out a queue-gating job. Could you add it back to those three after the rebase, and update the ROUTING_CASES comment that says the composite is called only from pr_build_linux.yml? Given how easily it drops out in a file move, is it worth a guard for it?
NATIVE_CONSUMERS is a flat list of output keys, one per consumer job, and #5871 has already broken that assumption on main. It added spark_4_1_hive as a second output feeding the same spark_4_1 job, which is now gated on needs.changes.outputs.spark_4_1 == 'true' || needs.changes.outputs.spark_4_1_hive == 'true'. On a labeled run with run-spark-4.1-hive-tests, spark_4_1 is false and spark_4_1_hive is true, so the union computes build_linux_native as false, the producer is skipped, and spark_4_1 is then skipped through its needs even though its if is true. The label would quietly do nothing and Required Checks would still go green. compute-changes.py is the one file that auto-merges cleanly here, so the union will miss the new key silently. native_selection_failures will fail preflight on the if: string mismatch, but the tempting fix there is to relax the comparison, which leaves the hole. Would it make sense to let a consumer map to a set of output keys rather than one?
Last one is coverage. The hosted run only selected pr_build_linux, spark_4_1 and iceberg_1_11, so six of the nine rewired consumers have not run against the shared artifact. spark_3_4 is the one I would most want to see, because its build job in spark_sql_test_reusable.yml is the only consumer whose toolchain setup actually changed, swapping ./.github/actions/setup-builder for a bare actions/setup-java@v4 at JDK 11, and it now consumes a libcomet.so linked against JDK 17. The linux-test Spark 3.4 lane already proves the library loads under JDK 11, but the new setup path has no coverage. These are queue-tier jobs, so a break blocks every merge rather than one PR. Could you apply run-spark-3.4-tests, run-spark-3.5-tests, run-spark-4.0-tests and run-iceberg-tests once on the rebased head?
2b6d68d to
79c161b
Compare
|
@andygrove, addressed the three items from your latest review and rebased onto
Local validation passed: 36 configuration regression tests, 21 native-selection tests (299,008 combinations), actionlint, suite/benchmark inventory checks, 15 Iceberg shard tests, 4 PR-label tests, Markdown formatting, and whitespace checks. The PR description now reflects the implementation and pending hosted coverage. |
andygrove
left a comment
There was a problem hiding this comment.
Happy to approve once the following issues are resolved.
Thanks for the quick turnaround on the last round. All three items are addressed: the Maven bootstrap is back in the three moved jobs and guarded, NATIVE_CONSUMERS maps callers to tuples so the Hive-only label starts the producer, and all four label runs came back green, so every one of the nine consumers has now run against the shared artifact, including the Spark 3.4 setup-java-only build path. I also ran the three Python checks locally on 79c161b and they pass in about five seconds total, so the preflight cost is fine.
-
Rebase hazard from #5897.
chore: drop support for JDK 11landed onmainafter this head was pushed. It edits thelint-javamatrix inpr_build_linux.yml(the Spark 3.4 entry becomes JDK 17 andJAVA_TOOL_OPTIONSdrops the version conditional), and flipsjava: 11to17forspark_3_4andiceberg_1_8inci.ymland for preflight. Theci.ymlandlinux-testhunks should auto-merge, but thelint-javahunk conflicts with this PR's deletion of that block, andpr_build_linux_checks.ymlis a new file, so the natural resolution drops the change and the new file keeps JDK 11. Same shape as the bootstrap step last time. It fails loudly this time because the new Maven enforcer rejects JDK 11, so no guard is needed, but could you carry those edits intopr_build_linux_checks.ymlon the rebase? -
Contributor doc pointer.
docs/source/contributor-guide/adding_a_new_spark_version.md(around line 112) tells authors to add the compile-only job topr_build_linux.yml, butbuild-spark-4-1now lives inpr_build_linux_checks.yml. Could you update the file name there? The suite-matrix instructions indevelopment.mdandcheck-suites.pystill point atpr_build_linux.ymlcorrectly sincelinux-teststays put.
Nothing else from me. The wiring, the main-only cache write on the single producer, artifact retention, the permissions blocks, and the README rewrite all look right.
79c161b to
a126925
Compare
|
@andygrove, both items from your latest review are addressed. Rebased onto
The rebase also preserves Spark 3.4's new label/manual-only policy. Updated the selection regression to verify that queue runs select the other eight consumers, that a Spark 3.4-only queue change does not start native compilation, and that labels cannot opt Spark 3.4 back into a queue run. Its label and manual paths remain covered through both Python and the CLI. Local checks passed: 36 configuration tests, 21 selection tests (including 299,008 combinations), actionlint, suite/benchmark checks, 15 Iceberg shard tests, 4 PR-label tests, Markdown formatting, and whitespace checks. Updated the PR description with the previous green coverage and the fresh CI run. The four opt-in labels remain applied; results on this rebased head are pending. |
andygrove
left a comment
There was a problem hiding this comment.
One rebase item, and this time only half of it is loud.
#5930 landed on main after this head. It adds a cache-refresh-only input to pr_build_linux.yml so that push to main runs only the jobs that own an actions/cache entry, and check-ci-config.py grew a sixth invariant pinning which jobs survive it. Three of the five jobs it names, lint, build-native and linux-test-rust, are jobs this PR moves into the two new workflows.
I merged main into a126925b7 locally. Four files conflict and compute-changes.py auto-merges correctly, the FILTERS["build_linux_full"] = FILTERS["build_linux"] alias picks up your two new paths for free. Preflight then fails on the three stale CACHE_REFRESH_JOBS names, on linux-test having lost its guard in the move, and on two ROUTING_CASES entries needing build_linux_full. All of that is loud and the messages say what to do.
The silent part is what is left after you do it. I dropped the three stale names, put the guard back on linux-test, and check-ci-config.py prints CI config checks passed. Both of your test suites pass too, 21 and 36. But pr_build_linux_checks.yml is gated on build_linux, which has a push tier, and it has no cache-refresh-only input, so the whole thing runs on every push to main. I confirmed the selection with EVENT_NAME=push python3 dev/ci/compute-changes.py on the merged tree: build_linux=true, build_linux_full=false. Using this PR's own durations that is lint-java x4 at 19m10s, Celeborn x2 at 12m03s, build-spark-4-1 at 4m21s and scalafix-syntactic at 25s, about 36 runner-minutes a push. #5930 took the push tier from 587 to about 73, so this puts it back to roughly 109.
Could you carry the input into pr_build_linux_checks.yml on the rebase, wired from ci.yml the same way as pr_build_linux with ${{ needs.changes.outputs.build_linux_full != 'true' }}, and guard those four jobs? lint and linux-test-rust should stay unguarded, since linux-test-rust owns the cargo-debug cache and lint gates it, which is the same reasoning #5930 used for the originals. Passing an input does not change the caller's if:, so your linux_checks_failures invariant that the two callers share a condition still holds.
The guard itself also needs to become multi-workflow. CACHE_REFRESH_WORKFLOW is a single Path today, and once the cache writers live in three files a table of {workflow: {job: reason}} is what actually expresses the invariant. Would it be worth extending the CACHE_REFRESH_INPUT check the same way, so a caller that forgets the input for either workflow fails preflight rather than only the pr_build_linux one? Your test-ci-config.py mutation harness is the natural place to pin it, a mutation that drops the guard from a job in pr_build_linux_checks.yml would have caught exactly what I hit.
Two smaller pieces of the same rebase. docs/source/contributor-guide/ci.md lines 55-60 and 214 name the five cache-writing jobs and tell contributors to add the guard when they add a job to pr_build_linux.yml. That file is not in this PR and merges clean, so it goes stale without saying anything. And the build_linux comment in POLICY still says the push tier is there for "main's cargo-ci, cargo-debug, Maven and TPC-H/TPC-DS caches", but cargo-ci now lives in build_linux_native.yml and cargo-debug in pr_build_linux_checks.yml, so that one output is load-bearing for three workflows now rather than one. Worth spelling out, because it is the thing that keeps the shared producer running on push at all.
Nothing else from me. The producer and consumer wiring, the union over NATIVE_CONSUMERS, the Maven bootstrap guard and the JDK 17 carry-over all look right on this head, and all nine consumers came back green.
a126925 to
3c31e5a
Compare
Which issue does this PR close?
Part of #5830. Follow-up to #3249, which shared native artifacts within individual workflows.
Rationale for this change
The Linux, Spark SQL, and Iceberg workflows compile the same default Linux native library separately. Under the current routing policy, a shared source change selects three native-consuming callers in the merge queue, six in the nightly run, and nine on manual dispatch. Build the library once and share it with those callers to reduce duplicate compilation. Actual time savings depend on cache state and still need measurement in CI.
Splitting the Linux workflow must also preserve the cheaper push-to-main mode: refresh the Cargo, Maven, and TPC dataset caches without repeating Java/Scala lint, compilation checks, Celeborn checks, or JVM/query tests that already ran.
What changes are included in this PR?
ciprofile, JDK 17, compiler flags, artifact retries, and one-day retention. All nine native-consuming callers depend on it, and its result feeds Required Checks.setup-javawithout Rust setup; Spark/JDK-specific JVM artifacts remain separate.cache-refresh-onlyandprofilesinputs to both Linux callers. On main pushes, retain the native producer, Rust formatting/debug tests, and both TPC cache-population jobs. Nightly runs skip previously completed checks and TPC work. Cargo CI/debug caches are saved only on push.prepare-matrixjob after moving lint. Preserve the default, nightly, and all-profile matrices.How are these changes tested?
Rebased onto
mainat343143fb9. Independent comparison verified the moved job definitions, consumer test steps and suite matrices, all nine artifact dependencies, Required Checks coverage, and profile selection (1/4/5 rows for PR/nightly/all).Passed locally on
3c31e5aa8:Fresh hosted validation is pending: commit CI and Spark 4.1 opt-in CI. The existing four opt-in labels remain applied; the additional Spark 4.1 label requests the ninth consumer now that it is queue-only by default.
No native or Spark runtime build was run locally. Hosted push/nightly execution and failed-job reruns after artifact expiry remain unverified; after the shared artifact expires, rerun the full workflow.