Skip to content

Speed up the java_sdk e2e Gradle builds with concurrency and caching#69239

Merged
jason810496 merged 3 commits into
apache:mainfrom
jason810496:ci/java-sdk/refactor-e2e-gradle-deps
Jul 10, 2026
Merged

Speed up the java_sdk e2e Gradle builds with concurrency and caching#69239
jason810496 merged 3 commits into
apache:mainfrom
jason810496:ci/java-sdk/refactor-e2e-gradle-deps

Conversation

@jason810496

Copy link
Copy Markdown
Member

Why

The java_sdk e2e job builds the two example bundles sequentially and starts from an empty GRADLE_USER_HOME on every run, forcing a full re-download of the bundles' dependency tree (Spark alone is ~1GB) each time.

What

  • Build the example and scala_spark_example bundles concurrently; they are independent Gradle builds that both only consume the SDK artifact published beforehand.
    • The bundle containers run with --network=host: Gradle's cross-process lock handover pings the lock owner over loopback, which isolated container network namespaces would break (60s lock timeouts).
    • Each build's output is captured and printed under its own header, so concurrent logs do not interleave and failures name their bundle.
  • Cache java-sdk/.gradle (caches, wrapper, jdks) in the e2e workflow for the java_sdk mode.
    • actions/cache/restore + actions/cache/save split with if: always(), so a completed Gradle warm-up is saved even when the e2e tests later fail.
    • The key hashes both Groovy and Kotlin DSL build files plus the version catalog, and includes runner.arch so arch-specific auto-provisioned JDKs do not cross between amd64 and arm64 runners.

Was generative AI tooling used to co-author this PR?

@jason810496 jason810496 self-assigned this Jul 2, 2026
@jason810496
jason810496 marked this pull request as ready for review July 2, 2026 09:31
@jason810496
jason810496 requested review from phanikumv and uranusjr July 2, 2026 09:31
Comment thread airflow-e2e-tests/tests/airflow_e2e_tests/conftest.py Outdated
Comment thread .github/workflows/airflow-e2e-tests.yml
Comment thread .github/workflows/airflow-e2e-tests.yml
Comment thread airflow-e2e-tests/tests/airflow_e2e_tests/conftest.py Outdated
Comment thread airflow-e2e-tests/tests/airflow_e2e_tests/conftest.py Outdated
Comment thread airflow-e2e-tests/tests/airflow_e2e_tests/conftest.py Outdated
The example and scala_spark_example bundles are independent Gradle builds
that both consume the SDK artifact published to the local Maven repo, so the
Scala Spark dependency resolution no longer has to wait for the Java example
build to finish before it starts.

The bundle containers run with --network=host because Gradle's cross-process
lock handover pings the lock owner over loopback, which isolated container
network namespaces would break, and each build's output is captured and
printed under its own header so concurrent logs do not interleave.
The java_sdk e2e job builds the SDK and its example bundles with Gradle on
every canary and java-sdk-touching run, starting from an empty
GRADLE_USER_HOME each time. That forces a full re-download of the example
bundles' dependency tree (Spark alone is around 1GB) on every run. Reusing
the resolved dependencies across runs removes that repeated download.

The restore/save split saves the warm-up even when the e2e tests fail, the
key hashes the Kotlin-DSL build files and version catalog that pin the SDK
dependencies, and runner.arch keeps the arch-specific auto-provisioned JDKs
in .gradle/jdks from crossing between amd64 and arm64 runners.
Excludes churny *.lock/journal files from the Gradle cache per GitHub's
own caching guidance, makes bundle build output print stdout/stderr
symmetrically through Rich with markup disabled so raw Gradle text
can't be misparsed as markup, ties the build pool size to the bundle
list instead of a hardcoded count, and cites the Gradle lock-handover
mechanism the --network=host workaround depends on.
@jason810496
jason810496 force-pushed the ci/java-sdk/refactor-e2e-gradle-deps branch from f5be378 to f0287aa Compare July 9, 2026 10:21
@uranusjr

uranusjr commented Jul 9, 2026

Copy link
Copy Markdown
Member

#69411 introduced a different approach to caching, we might want to think about this with both in context. This does not block the merge since the two are fundamentally different components and don’t conflict.

@jason810496
jason810496 merged commit 7a4c059 into apache:main Jul 10, 2026
155 of 156 checks passed
@github-actions

Copy link
Copy Markdown
Contributor

Backport failed to create: v3-3-test. View the failure log Run details

Note: As of Merging PRs targeted for Airflow 3.X
the committer who merges the PR is responsible for backporting the PRs that are bug fixes (generally speaking) to the maintenance branches.

In matter of doubt please ask in #release-management Slack channel.

Status Branch Result
v3-3-test Commit Link

You can attempt to backport this manually by running:

cherry_picker 7a4c059 v3-3-test

This should apply the commit to the v3-3-test branch and leave the commit in conflict state marking
the files that need manual conflict resolution.

After you have resolved the conflicts, you can continue the backport process by running:

cherry_picker --continue

If you don't have cherry-picker installed, see the installation guide.

@jason810496

Copy link
Copy Markdown
Member Author

#69411 introduced a different approach to caching, we might want to think about this with both in context. This does not block the merge since the two are fundamentally different components and don’t conflict.

Yes, I will follow-up to check whether building Java-SDK artifact natively in CI be better (it should but still worthwhile to double check).

No need to backport, Lang-SDK lives in main.

@jason810496 jason810496 removed the backport-to-v3-3-test Backport to v3-3-test label Jul 10, 2026
jason810496 added a commit to jason810496/airflow that referenced this pull request Jul 13, 2026
The java_sdk e2e mode and the lang-SDK k8s test solved the same
cold-build problem two different ways (containerized Gradle with a
repo-local cache vs host toolchain with salted home-dir caches), which
a review follow-up on apache#69239 asked to reconcile. Converge the e2e mode
on the apache#69411 native-toolchain convention: CI provisions the JDK with
actions/setup-java and caches ~/.gradle, dropping the per-run
eclipse-temurin image pull and the --network=host Gradle lock-handover
workaround; local runs keep the containerized build so a dev host
still needs no JDK.
jason810496 added a commit to jason810496/airflow that referenced this pull request Jul 13, 2026
The java_sdk e2e mode and the lang-SDK k8s test solved the same
cold-build problem two different ways (containerized Gradle with a
repo-local cache vs host toolchain with salted home-dir caches), which
a review follow-up on apache#69239 asked to reconcile. Converge the e2e mode
on the apache#69411 native-toolchain convention: CI provisions the JDK with
actions/setup-java and caches ~/.gradle, dropping the per-run
eclipse-temurin image pull and the --network=host Gradle lock-handover
workaround; local runs keep the containerized build so a dev host
still needs no JDK.
jason810496 added a commit to jason810496/airflow that referenced this pull request Jul 15, 2026
The java_sdk e2e mode and the lang-SDK k8s test solved the same
cold-build problem two different ways (containerized Gradle with a
repo-local cache vs host toolchain with salted home-dir caches), which
a review follow-up on apache#69239 asked to reconcile. Converge the e2e mode
on the apache#69411 native-toolchain convention: CI provisions the JDK with
actions/setup-java and caches ~/.gradle, dropping the per-run
eclipse-temurin image pull and the --network=host Gradle lock-handover
workaround; local runs keep the containerized build so a dev host
still needs no JDK.
jason810496 added a commit that referenced this pull request Jul 15, 2026
The java_sdk e2e mode and the lang-SDK k8s test solved the same
cold-build problem two different ways (containerized Gradle with a
repo-local cache vs host toolchain with salted home-dir caches), which
a review follow-up on #69239 asked to reconcile. Converge the e2e mode
on the #69411 native-toolchain convention: CI provisions the JDK with
actions/setup-java and caches ~/.gradle, dropping the per-run
eclipse-temurin image pull and the --network=host Gradle lock-handover
workaround; local runs keep the containerized build so a dev host
still needs no JDK.
joshuabvarghese pushed a commit to joshuabvarghese/airflow that referenced this pull request Jul 16, 2026
…pache#69239)

* Build the Java SDK and Scala Spark e2e bundles concurrently

The example and scala_spark_example bundles are independent Gradle builds
that both consume the SDK artifact published to the local Maven repo, so the
Scala Spark dependency resolution no longer has to wait for the Java example
build to finish before it starts.

The bundle containers run with --network=host because Gradle's cross-process
lock handover pings the lock owner over loopback, which isolated container
network namespaces would break, and each build's output is captured and
printed under its own header so concurrent logs do not interleave.

* Cache the Java SDK Gradle dependencies in the e2e job

The java_sdk e2e job builds the SDK and its example bundles with Gradle on
every canary and java-sdk-touching run, starting from an empty
GRADLE_USER_HOME each time. That forces a full re-download of the example
bundles' dependency tree (Spark alone is around 1GB) on every run. Reusing
the resolved dependencies across runs removes that repeated download.

The restore/save split saves the warm-up even when the e2e tests fail, the
key hashes the Kotlin-DSL build files and version catalog that pin the SDK
dependencies, and runner.arch keeps the arch-specific auto-provisioned JDKs
in .gradle/jdks from crossing between amd64 and arm64 runners.

* Address java_sdk e2e review feedback on caching and build output

Excludes churny *.lock/journal files from the Gradle cache per GitHub's
own caching guidance, makes bundle build output print stdout/stderr
symmetrically through Rich with markup disabled so raw Gradle text
can't be misparsed as markup, ties the build pool size to the bundle
list instead of a hardcoded count, and cites the Gradle lock-handover
mechanism the --network=host workaround depends on.
joshuabvarghese pushed a commit to joshuabvarghese/airflow that referenced this pull request Jul 16, 2026
The java_sdk e2e mode and the lang-SDK k8s test solved the same
cold-build problem two different ways (containerized Gradle with a
repo-local cache vs host toolchain with salted home-dir caches), which
a review follow-up on apache#69239 asked to reconcile. Converge the e2e mode
on the apache#69411 native-toolchain convention: CI provisions the JDK with
actions/setup-java and caches ~/.gradle, dropping the per-run
eclipse-temurin image pull and the --network=host Gradle lock-handover
workaround; local runs keep the containerized build so a dev host
still needs no JDK.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants