This is an automated email from the ASF dual-hosted git repository.
the-other-tim-brown pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-xtable.git
The following commit(s) were added to refs/heads/main by this push:
new ef88e020 [MINOR] Persist the Maven build cache between CI runs (#882)
ef88e020 is described below
commit ef88e0202beef1c3c22e39ec709e294225ff5049
Author: Sylwester Lachiewicz <[email protected]>
AuthorDate: Thu Aug 20 14:57:06 2026 +0200
[MINOR] Persist the Maven build cache between CI runs (#882)
* [MINOR] Persist the Maven build cache between CI runs
.mvn/extensions.xml enables maven-build-cache-extension, but the cache
never survives a CI run: actions/setup-java's `cache: maven` persists
~/.m2/repository only, while the extension writes to ~/.m2/build-cache.
The effect is visible in any recent build log - ten modules, ten
"Local build was not found by checksum" lines, zero restores - so every
run rebuilds and retests all ten modules from scratch, including for
pull requests that touch only the website or a single module.
Restore ~/.m2/build-cache before the build and save it afterwards. Only
main writes an entry; pull requests restore from main's rather than each
branch consuming the repository-wide 10 GB cache budget.
Source Build Check is deliberately left alone - it passes
-Dmaven.build.cache.enabled=false and skips `cache: maven` on purpose,
to prove the source release builds without prebuilt artifacts.
* Keep the bundled jars out of the persisted build cache
Persisting ~/.m2/build-cache as the previous commit does is only useful
if the entry is small enough to live alongside the ~/.m2/repository
caches in the repository-wide 10 GB budget. Measured, it is not: one
generation is 1.2 GB, and 1.17 GB of that is three bundled jars -
xtable-utilities (1.0 GB), xtable-hive-metastore (125 MB) and
xtable-aws (42 MB).
Those three modules are worth about 3 minutes of a 27 minute build.
xtable-core and xtable-service are 84% of the time and about 1 MB of
cache between them. Caching is worth it in inverse proportion to
artifact size here, so opt the bundle producers out with the
extension's per-project property, which disables both restore and save
for that module. A cold build then writes 12 MB instead of 1.2 GB while
still caching everything expensive; measured locally, a fully warm run
restores 7 of 7 remaining modules.
Also in this commit:
- Add .mvn/maven-build-cache-config.xml pinning maxBuildsCached to 1,
disabling the remote cache explicitly, and reconciling the surefire
skip flags. Command line flags are not part of a module's checksum,
so without reconciliation a build that skipped tests and one that ran
them are indistinguishable to the cache. The flags are tracked
without a skipValue attribute deliberately: skipValue relaxes the
comparison rather than tightening it.
- Bump maven-build-cache-extension 1.1.0 -> 1.2.3. Two invalidation
fixes land in 1.2.1: MBUILDCACHE-87, plugin dependencies missing from
the checksum, and MBUILDCACHE-99, moved files not always detected.
Both affect whether a restore is correct, so they matter more once
the cache actually persists.
- Guard the save step on the cache directory staying under 100 MB, and
warn when it does not, so a future module that starts caching large
artifacts is visible rather than silently churning the budget.
- Pass -Dmaven.build.cache.enabled=false when publishing a release.
versions:set rewrites the version immediately beforehand, while cache
restoration is version-agnostic. That runner keeps no cache directory
today, so this is a guard against it gaining one, and it matches what
source-build-check.yml already does deliberately.
- Add the JDK to the Actions cache key, since the extension does not
hash the JDK, and raise the job timeout from 30 to 40 minutes - a
cold build is already 27 minutes against it, independent of caching.
- Teach the spotless license-header delimiter about <cache, the root
element of the new config file, alongside the <extensions entry that
is already there for .mvn/extensions.xml.
* Drop this project's own artifacts before the m2 repository cache is saved
`mvn install` puts xtable's own artifacts into ~/.m2/repository, and that
includes the bundled jars - about 1.2 GB, of which xtable-utilities alone
is roughly 1 GB. actions/setup-java caches that directory wholesale and
offers no way to exclude a path, so remove them in a final step, which
runs before its post-save hook.
They are rebuilt from source on every run, so they can never produce a
useful cache hit, and a stale SNAPSHOT sitting in the local repository
can shadow a reactor build.
This is a guard rather than a fix. License Check currently reserves the
shared cache key first - it downloads the whole dependency tree to
inspect each jar's license, which is the useful half - and because it
only runs `package`, the saved entry has never contained this project's
artifacts. That is why this job logs "Unable to reserve cache with key"
at the end of every run. The arrangement is the one we want, but it
holds by ordering rather than by construction: if License Check ever
fails or is cancelled before its post step, this job would win the key
and save roughly 2.15 GB into a repository-wide 10 GB budget.
* Manage the Maven repository cache explicitly, with one writer
Both jobs used setup-java's `cache: maven`, which has two problems here.
It restores on an exact key match only. setup-java sets no restore-keys
deliberately, "to start with a clear cache after dependency update"
(actions/setup-java#269), so any change to a pom or to extensions.xml
made every job re-download the entire dependency tree from Central.
Keying the same way but adding a prefix fallback warms from the previous
entry and downloads only the delta. This commit changes both files, so
it pays that cost once itself.
It also gave the two jobs the same key, and cache entries are immutable,
so whichever finished first reserved it and the other's save failed.
License Check finishes in about two minutes and the full build takes 27,
so in practice License Check always won and Maven CI Build logged
"Unable to reserve cache with key" on every run.
That outcome was the right one, which is why this makes it explicit
rather than trying to win the race. License Check has to resolve every
dependency in order to inspect each jar's license, so it populates
exactly what the other jobs need, and it stops at `package`, so its
entry never contains this project's own artifacts. It is now the sole
writer; Maven CI Build restores the same key read-only and no longer
attempts a save.
The wrapper distribution was cached separately by setup-java, keyed on
the wrapper properties so it survives pom changes. That is reproduced
here rather than lost.
Both jobs also clear ~/.m2/repository/org/apache/xtable before the
post-job save, as Source Build Check already does. On the writer that
guards the invariant above; on the reader it is belt and braces.
* Write the Maven repository cache only from main
The entry measures 981 MB against a repository-wide 10 GB budget, so a
handful of concurrent pull requests with differing pom hashes would
crowd out the entry they all restore from. Split restore and save so
only main writes, matching what this branch already does for the build
cache. Pull requests warm from main through the prefix fallback and
re-download only their own delta.
Saving is also conditional on the exact key having missed. Cache entries
are immutable, so writing over an existing key just fails; that check is
what actions/cache performs internally when restore and save are not
split.
The wrapper cache is left unsplit. At ~9 MB it is not worth gating, and
it is keyed on the wrapper properties, which rarely change.
* Reconcile the flags that skip tests without changing the checksum
Failsafe is bound in the parent POM to integration-test and verify, and
CI runs `install`, so integration tests run on every build and a
restored module skips them exactly as it skips unit tests. Reconciles
are matched per goal, and the two goals expose different parameters:
testFailureIgnore is on verify only, and naming a parameter a goal does
not have earns a warning on every build.
The compiler entry closes a hole the surefire block does not reach.
-Dmaven.test.skip=true never gets to surefire here, because the parent
POM pins <skip>${skipUTs}</skip> and explicit plugin configuration wins
over the user property, so surefire's skip parameter reads identically
either way and the module checksum is byte-identical across the two.
What the flag actually suppresses is test compilation.
Verified on xtable-api, Temurin 11: seeding the cache with
-Dmaven.test.skip=true and then running a plain `clean install`
restored the untested build before this commit, and after it logs
"Plugin parameter mismatch found. Parameter: skip, expected: true,
actual: false" and runs the tests. A plain build still restores a plain
build, and buildinfo.xml records all nine failsafe parameters as
tracked="true" with no "Cannot find a Mojo parameter" warnings.
* Derive the JDK in the cache keys from one place
The JDK is in these keys because the build cache extension does not hash
it, and the two workflows have to agree on the key or the reader stops
finding what the writer saved. Four literal "jdk11" strings across two
files could not express that; bumping actions/setup-java's java-version
would have left them asserting a JDK that is no longer in use.
* Resolve the whole reactor in the job that writes the repository cache
"License Check has to resolve every dependency in order to inspect each
jar's license" is not true, and the previous commit made it load-
bearing. apache-rat:check declares no dependency resolution;
dependency:tree collects poms rather than jars; and the shaded-bundle
step names three modules and reaches only their -am closure. -am makes
dependencies, not dependents, so the two leaves are outside it: nothing
in the job resolves xtable-service's Quarkus stack, xtable-utilities'
bundled dependencies, or maven-install-plugin, which only an `install`
pulls.
Maven CI Build is restore-only by construction, so it cannot fill that
gap itself - it would re-download the delta from Central on every run,
permanently. dependency:go-offline over the full reactor covers what the
license steps do not. It runs only on main, where the save happens, and
its failure must not fail a license check: an incomplete entry costs
download time on the next run and nothing else.
Verified: `./mvnw -B -ntp -q dependency:go-offline
-Dmaven.build.cache.enabled=false` exits 0 across the reactor.
* Bound the build cache save on both sides
The save gated on `size_mb < 100` while the warning fired above 100, so
a directory of exactly 100 MB - reachable, du -sm rounds up - was
skipped silently, the one outcome the guard exists to make visible. It
also treated the `${size_mb:-0}` fallback for a missing directory as a
pass, handing actions/cache/save a path that is not there.
Saving is now also conditional on the exact key having missed on
restore. Cache entries are immutable, so a re-run of a main commit would
try to write over its own entry and log "Unable to reserve cache with
key" - the message the earlier commits removed by giving the two jobs
separate keys. The repository cache save already carries this check.
---
.github/workflows/mvn-ci-build.yml | 114 ++++++++++++++++++++++++++++++--
.github/workflows/mvn-license-check.yml | 89 ++++++++++++++++++++++++-
.github/workflows/package-deploy.yml | 8 ++-
.mvn/extensions.xml | 2 +-
.mvn/maven-build-cache-config.xml | 100 ++++++++++++++++++++++++++++
pom.xml | 3 +-
xtable-aws/pom.xml | 11 +++
xtable-hive-metastore/pom.xml | 11 +++
xtable-utilities/pom.xml | 11 +++
9 files changed, 339 insertions(+), 10 deletions(-)
diff --git a/.github/workflows/mvn-ci-build.yml
b/.github/workflows/mvn-ci-build.yml
index 92e47894..40114833 100644
--- a/.github/workflows/mvn-ci-build.yml
+++ b/.github/workflows/mvn-ci-build.yml
@@ -29,19 +29,125 @@ on:
branches:
- "main"
+# The build cache extension does not hash the JDK, so it is part of every cache
+# key below. Defined once here rather than repeated, so that changing the JDK
+# cannot leave a key asserting the old one.
+env:
+ JDK_VERSION: '11'
+
jobs:
build:
runs-on: ubuntu-latest
- timeout-minutes: 30
+ # A cold build is ~27 min, which left no headroom under the previous 30.
+ timeout-minutes: 40
steps:
- uses: actions/checkout@v7
- - name: Set up JDK 11
+ - name: Set up JDK ${{ env.JDK_VERSION }}
uses: actions/setup-java@v5
with:
- java-version: '11'
+ java-version: ${{ env.JDK_VERSION }}
distribution: 'temurin'
- cache: maven
+
+ # Restore only. License Check writes this cache, and only on `main`: it
+ # finishes in a couple of minutes against this job's 27, and it stops at
+ # `package` so the entry never carries this project's artifacts. It
+ # resolves the reactor explicitly for this job's benefit; its own license
+ # steps reach only part of it.
+ # Previously both jobs used setup-java's `cache: maven`, which gave them
+ # the same key, and whichever finished first reserved it - this job then
+ # logged "Unable to reserve cache with key" on every single run. Making
+ # the reader explicit removes the race rather than winning it.
+ #
+ # A warm start, not a guarantee: `install` here runs plugins that a build
+ # stopping at `package` never resolves, so expect a delta every run.
+ - name: Restore Maven repository cache
+ uses: actions/cache/restore@v6
+ with:
+ path: ~/.m2/repository
+ key: m2-repository-${{ runner.os }}-jdk${{ env.JDK_VERSION }}-${{
hashFiles('**/pom.xml', '**/.mvn/extensions.xml') }}
+ restore-keys: |
+ m2-repository-${{ runner.os }}-jdk${{ env.JDK_VERSION }}-
+
+ - name: Restore Maven wrapper cache
+ uses: actions/cache/restore@v6
+ with:
+ path: ~/.m2/wrapper/dists
+ key: m2-wrapper-${{ runner.os }}-${{
hashFiles('**/.mvn/wrapper/maven-wrapper.properties') }}
+
+ # A separate cache from the repository above: the build cache extension
+ # configured in .mvn/extensions.xml writes to ~/.m2/build-cache, so
+ # without this it starts empty every run and never restores a module.
+ # Only `main` writes an entry, so pull requests warm up from `main`
instead
+ # of each branch filling the repository-wide cache budget.
+ #
+ # The modules producing large bundled jars opt out of the cache entirely
+ # with <maven.build.cache.enabled>false</maven.build.cache.enabled> in
their
+ # own poms, which keeps this entry around 12 MB. Without that opt-out the
+ # entry is 1.2 GB, 97% of it three shaded jars that account for only ~3
of
+ # the 27 minutes a cold build takes.
+ #
+ # Note: a cache-restored xtable-service does not reproduce
+ # target/quarkus-app. No step consumes that directory today; anything
added
+ # later that does must not rely on it being present.
+ - name: Restore Maven build cache
+ id: build-cache
+ uses: actions/cache/restore@v6
+ with:
+ path: ~/.m2/build-cache
+ key: maven-build-cache-${{ runner.os }}-jdk${{ env.JDK_VERSION
}}-${{ github.sha }}
+ restore-keys: |
+ maven-build-cache-${{ runner.os }}-jdk${{ env.JDK_VERSION }}-
- name: Build all module with Maven
run: ./mvnw clean install -ntp -B
+
+ # Guard against a module starting to cache large artifacts again: warn
and
+ # skip the save rather than churn the repository-wide 10 GB cache budget,
+ # which is otherwise mostly the ~/.m2/repository entries above. Checking
the
+ # size rather than specific paths keeps this working across module
renames.
+ - name: Check Maven build cache size
+ id: build-cache-size
+ if: success() && github.ref == 'refs/heads/main'
+ run: |
+ size_mb=$(du -sm ~/.m2/build-cache 2>/dev/null | cut -f1)
+ size_mb=${size_mb:-0}
+ echo "size_mb=${size_mb}" >> "$GITHUB_OUTPUT"
+ echo "~/.m2/build-cache is ${size_mb} MB"
+ # The two bounds below are what the save step gates on, so they have
to
+ # cover the whole range between them: 0 means the extension wrote
+ # nothing and there is no path for the save action to read.
+ if [ "${size_mb}" -eq 0 ]; then
+ echo "::warning title=Maven build cache not
saved::~/.m2/build-cache is empty or absent. The build cache extension did not
write anything; check that .mvn/extensions.xml is still in effect."
+ elif [ "${size_mb}" -ge 100 ]; then
+ echo "::warning title=Maven build cache not
saved::~/.m2/build-cache is ${size_mb} MB (limit 100 MB). A module is caching
large artifacts; opt it out with
<maven.build.cache.enabled>false</maven.build.cache.enabled> in its pom."
+ fi
+
+ # Skipped when the exact key already hit on restore - a re-run of the
same
+ # commit would otherwise try to write over an immutable entry and log the
+ # "Unable to reserve cache with key" that splitting these jobs removed.
+ - name: Save Maven build cache
+ if: >
+ success() && github.ref == 'refs/heads/main'
+ && steps.build-cache.outputs.cache-hit != 'true'
+ && steps.build-cache-size.outputs.size_mb > 0
+ && steps.build-cache-size.outputs.size_mb < 100
+ uses: actions/cache/save@v6
+ with:
+ path: ~/.m2/build-cache
+ key: maven-build-cache-${{ runner.os }}-jdk${{ env.JDK_VERSION
}}-${{ github.sha }}
+
+ # `install` above puts this project's own artifacts into
~/.m2/repository,
+ # including the bundled jars (~1.2 GB, xtable-utilities alone is ~1 GB).
+ # actions/setup-java caches that whole directory with no way to exclude a
+ # path, so drop them before its post step runs. They are rebuilt from
+ # source on every run and can never produce a useful cache hit, and a
+ # stale SNAPSHOT left in the local repository can shadow a reactor build.
+ # Source Build Check clears the same path for the same reason.
+ #
+ # This job no longer saves that cache, so nothing depends on this today.
+ # It is kept so the invariant holds by construction rather than by which
+ # step happens to write last.
+ - name: Drop this project's own artifacts from the Maven repository
+ if: always()
+ run: rm -rf ~/.m2/repository/org/apache/xtable
diff --git a/.github/workflows/mvn-license-check.yml
b/.github/workflows/mvn-license-check.yml
index 889c363b..ed618693 100644
--- a/.github/workflows/mvn-license-check.yml
+++ b/.github/workflows/mvn-license-check.yml
@@ -29,18 +29,62 @@ on:
branches:
- "main"
+# Kept in step with mvn-ci-build.yml: this job writes the cache that job reads,
+# and the JDK is part of the key on both sides.
+env:
+ JDK_VERSION: '11'
+
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- - name: Set up JDK 11
+ - name: Set up JDK ${{ env.JDK_VERSION }}
uses: actions/setup-java@v5
with:
- java-version: '11'
+ java-version: ${{ env.JDK_VERSION }}
distribution: 'temurin'
- cache: maven
+
+ # ~/.m2/repository is cached here rather than via setup-java's
+ # `cache: maven`, which restores on an exact key match only - it sets no
+ # restore-keys by design (actions/setup-java#269), so any pom change made
+ # every job re-download the whole dependency tree from Central. The
prefix
+ # fallback below warms from the previous entry and downloads just the
delta.
+ #
+ # This job is the writer for that cache, and deliberately the only one:
+ # it is the short job, so making it the writer costs the least, and it
+ # stops at `package`, so this project's own artifacts never enter the
+ # entry. Maven CI Build restores the same key read-only.
+ #
+ # Being the only writer means this job has to resolve what the readers
+ # need, which the license steps below do not do on their own - they build
+ # the shaded modules and their `-am` closure, which excludes the two
+ # leaves, xtable-utilities and xtable-service. The explicit resolve step
+ # after them covers the rest of the reactor.
+ #
+ # Restore and save are split so that only `main` writes. The entry is
+ # ~1 GB against a repository-wide 10 GB budget, so letting every branch
+ # write one would crowd out the entry they all restore from. Pull
requests
+ # warm from `main` via the prefix and re-download only their own delta.
+ - name: Restore Maven repository cache
+ id: m2-repository
+ uses: actions/cache/restore@v6
+ with:
+ path: ~/.m2/repository
+ key: m2-repository-${{ runner.os }}-jdk${{ env.JDK_VERSION }}-${{
hashFiles('**/pom.xml', '**/.mvn/extensions.xml') }}
+ restore-keys: |
+ m2-repository-${{ runner.os }}-jdk${{ env.JDK_VERSION }}-
+
+ # Replaces the separate wrapper cache that setup-java's `cache: maven`
+ # used to provide. Keyed only on the wrapper properties, which change
+ # rarely, so it survives the pom changes that rotate the key above. Left
+ # unsplit unlike the repository cache: at ~9 MB it is not worth gating.
+ - name: Cache Maven wrapper
+ uses: actions/cache@v6
+ with:
+ path: ~/.m2/wrapper/dists
+ key: m2-wrapper-${{ runner.os }}-${{
hashFiles('**/.mvn/wrapper/maven-wrapper.properties') }}
- name: Apache License Check
run: ./mvnw apache-rat:check -B
@@ -61,3 +105,42 @@ jobs:
- name: Validate Bundled License Texts
run: python3 release/scripts/validate_bundled_license_texts.py
+
+ # Nothing above this line resolves xtable-utilities or xtable-service:
+ # `apache-rat:check` requires no dependency resolution, `dependency:tree`
+ # collects poms rather than jars, and the shaded-bundle build reaches
only
+ # the `-am` closure of the three modules it names, which excludes both
+ # leaves. Without this step the entry never gains the Quarkus stack or
+ # xtable-utilities' bundled dependencies, and Maven CI Build - which
+ # cannot write the cache - would re-download them from Central on every
+ # run, permanently. This job exists to warm the cache for that one, so it
+ # has to cover the whole reactor even where a license check does not.
+ #
+ # Failure here must not fail a license check, hence `|| true`: an
+ # incomplete cache entry costs download time on the next run and nothing
+ # else. `go-offline` does not catch plugin dependencies resolved at
+ # execution time, so expect a small delta regardless.
+ - name: Resolve the rest of the reactor for the cache
+ if: success() && github.ref == 'refs/heads/main'
+ run: ./mvnw -B -ntp -q dependency:go-offline
-Dmaven.build.cache.enabled=false || true
+
+ # This job writes the repository cache, so the invariant that the entry
+ # holds third-party dependencies only is enforced here. The steps above
+ # stop at `package`, so this is a no-op today; it exists so that adding
+ # an `install` later cannot silently add ~1.2 GB of bundled jars to the
+ # entry. Must stay ahead of the save below.
+ - name: Drop this project's own artifacts from the Maven repository
+ if: always()
+ run: rm -rf ~/.m2/repository/org/apache/xtable
+
+ # Only when the exact key missed - entries are immutable, so saving over
+ # an existing key just fails. This is what actions/cache does internally
+ # when restore and save are not split.
+ - name: Save Maven repository cache
+ if: >
+ success() && github.ref == 'refs/heads/main'
+ && steps.m2-repository.outputs.cache-hit != 'true'
+ uses: actions/cache/save@v6
+ with:
+ path: ~/.m2/repository
+ key: m2-repository-${{ runner.os }}-jdk${{ env.JDK_VERSION }}-${{
hashFiles('**/pom.xml', '**/.mvn/extensions.xml') }}
diff --git a/.github/workflows/package-deploy.yml
b/.github/workflows/package-deploy.yml
index 7083a8f7..078d0455 100644
--- a/.github/workflows/package-deploy.yml
+++ b/.github/workflows/package-deploy.yml
@@ -35,6 +35,12 @@ jobs:
- name: Set Version
run: ./mvnw versions:set -DnewVersion="$VERSION"
- name: Publish package
- run: ./mvnw -ntp --batch-mode deploy -DskipTests
+ # Never build a release from cached module output. `versions:set`
above has
+ # just rewritten the version, while cache restoration is
version-agnostic —
+ # it stamps the current project version onto whatever it restores. This
+ # runner keeps no build-cache directory today, so the flag is a guard
+ # against that changing, and it also saves checksumming every module
for a
+ # cache that can never hit. Same reasoning as source-build-check.yml.
+ run: ./mvnw -ntp --batch-mode deploy -DskipTests
-Dmaven.build.cache.enabled=false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
\ No newline at end of file
diff --git a/.mvn/extensions.xml b/.mvn/extensions.xml
index 1fb0710e..2d3d23d2 100644
--- a/.mvn/extensions.xml
+++ b/.mvn/extensions.xml
@@ -20,6 +20,6 @@
<extension>
<groupId>org.apache.maven.extensions</groupId>
<artifactId>maven-build-cache-extension</artifactId>
- <version>1.1.0</version>
+ <version>1.2.3</version>
</extension>
</extensions>
diff --git a/.mvn/maven-build-cache-config.xml
b/.mvn/maven-build-cache-config.xml
new file mode 100644
index 00000000..172161ff
--- /dev/null
+++ b/.mvn/maven-build-cache-config.xml
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one or more
+ ~ contributor license agreements. See the NOTICE file distributed with
+ ~ this work for additional information regarding copyright ownership.
+ ~ The ASF licenses this file to You under the Apache License, Version 2.0
+ ~ (the "License"); you may not use this file except in compliance with
+ ~ the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+-->
+<cache xmlns="http://maven.apache.org/BUILD-CACHE-CONFIG/1.3.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/BUILD-CACHE-CONFIG/1.3.0
https://maven.apache.org/xsd/build-cache-config-1.3.0.xsd">
+ <configuration>
+ <enabled>true</enabled>
+ <remote enabled="false"/>
+ <local>
+ <!--
+ One generation per module. The default of 3 accumulates
generations,
+ which matters because CI persists this directory between runs; a
+ single generation keeps the saved entry at one build's size.
+ -->
+ <maxBuildsCached>1</maxBuildsCached>
+ </local>
+ </configuration>
+ <executionControl>
+ <reconcile>
+ <plugins>
+ <!--
+ Command line flags are not part of a module's checksum, so
without
+ this a build that skipped tests and one that ran them are
+ indistinguishable to the cache. Listing a property makes any
+ difference between the cached build and the current run a
cache
+ miss, in both directions.
+
+ Deliberately no skipValue attribute: skipValue is a
relaxation, not
+ a guard. It tells the cache to tolerate a mismatch when the
current
+ run is the one skipping, which is exactly the exemption we
do not
+ want on a release build.
+ -->
+ <plugin artifactId="maven-surefire-plugin" goal="test">
+ <reconciles>
+ <reconcile propertyName="skip"/>
+ <reconcile propertyName="skipExec"/>
+ <reconcile propertyName="skipTests"/>
+ <reconcile propertyName="testFailureIgnore"/>
+ </reconciles>
+ </plugin>
+ <!--
+ Failsafe is bound in the parent POM to integration-test and
verify,
+ and CI runs `install`, so integration tests run on every
build and a
+ restored module skips them exactly as it skips unit tests.
-DskipITs
+ is a command line flag, so the same gap applies. Reconciles
are
+ matched per goal, hence both entries; the parameter lists
differ
+ because testFailureIgnore exists on verify only, and naming a
+ parameter a goal does not have earns a warning on every
build.
+ -->
+ <plugin artifactId="maven-failsafe-plugin"
goal="integration-test">
+ <reconciles>
+ <reconcile propertyName="skip"/>
+ <reconcile propertyName="skipExec"/>
+ <reconcile propertyName="skipITs"/>
+ <reconcile propertyName="skipTests"/>
+ </reconciles>
+ </plugin>
+ <plugin artifactId="maven-failsafe-plugin" goal="verify">
+ <reconciles>
+ <reconcile propertyName="skip"/>
+ <reconcile propertyName="skipExec"/>
+ <reconcile propertyName="skipITs"/>
+ <reconcile propertyName="skipTests"/>
+ <reconcile propertyName="testFailureIgnore"/>
+ </reconciles>
+ </plugin>
+ <!--
+ -Dmaven.test.skip=true never reaches surefire in this build:
the
+ parent POM pins <skip>${skipUTs}</skip>, and explicit plugin
+ configuration wins over the user property, so surefire's skip
+ parameter reads identically whether the flag is present or
not.
+ What the flag actually suppresses is test compilation.
Without
+ this entry the module checksum is byte-identical across the
two,
+ and a cache seeded by a `-Dmaven.test.skip=true` build
restores
+ into a plain `install` with the tests never having run.
+ -->
+ <plugin artifactId="maven-compiler-plugin" goal="testCompile">
+ <reconciles>
+ <reconcile propertyName="skip"/>
+ </reconciles>
+ </plugin>
+ </plugins>
+ </reconcile>
+ </executionControl>
+</cache>
diff --git a/pom.xml b/pom.xml
index 910d794b..80a73f6b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -946,7 +946,8 @@
</excludes>
<licenseHeader>
<file>style/xml-license-header</file>
-
<delimiter>^<project|^<configuration|^<Configuration|^<extensions|^<component</delimiter>
+ <!-- ^<cache is the root element of
.mvn/maven-build-cache-config.xml -->
+
<delimiter>^<project|^<configuration|^<Configuration|^<extensions|^<component|^<cache</delimiter>
<skipLinesMatching>^<.*xml.+?$</skipLinesMatching>
</licenseHeader>
</pom>
diff --git a/xtable-aws/pom.xml b/xtable-aws/pom.xml
index 3d0a6639..9652042d 100644
--- a/xtable-aws/pom.xml
+++ b/xtable-aws/pom.xml
@@ -27,6 +27,17 @@
<artifactId>xtable-aws</artifactId>
<name>XTable AWS</name>
+ <properties>
+ <!--
+ This module produces a large bundled jar (~42 MB). Keep it out of the
+ maven-build-cache entirely: the property disables both restore and
save
+ for this project, so the artifact never enters the cache directory
that
+ CI persists between runs. Shading is cheap relative to the test
suites
+ the cache is there to skip, so there is nothing worth caching here.
+ See .mvn/maven-build-cache-config.xml.
+ -->
+ <maven.build.cache.enabled>false</maven.build.cache.enabled>
+ </properties>
<dependencies>
diff --git a/xtable-hive-metastore/pom.xml b/xtable-hive-metastore/pom.xml
index 36071bfe..e6af6d15 100644
--- a/xtable-hive-metastore/pom.xml
+++ b/xtable-hive-metastore/pom.xml
@@ -27,6 +27,17 @@
<artifactId>xtable-hive-metastore</artifactId>
<name>XTable HMS</name>
+ <properties>
+ <!--
+ This module produces a large bundled jar (~125 MB). Keep it out of
the
+ maven-build-cache entirely: the property disables both restore and
save
+ for this project, so the artifact never enters the cache directory
that
+ CI persists between runs. Shading is cheap relative to the test
suites
+ the cache is there to skip, so there is nothing worth caching here.
+ See .mvn/maven-build-cache-config.xml.
+ -->
+ <maven.build.cache.enabled>false</maven.build.cache.enabled>
+ </properties>
<dependencies>
<dependency>
diff --git a/xtable-utilities/pom.xml b/xtable-utilities/pom.xml
index 53ad1497..fd706ebf 100644
--- a/xtable-utilities/pom.xml
+++ b/xtable-utilities/pom.xml
@@ -27,6 +27,17 @@
<artifactId>xtable-utilities_${scala.binary.version}</artifactId>
<name>XTable Project Utilities</name>
+ <properties>
+ <!--
+ This module produces a large bundled jar (~1 GB). Keep it out of the
+ maven-build-cache entirely: the property disables both restore and
save
+ for this project, so the artifact never enters the cache directory
that
+ CI persists between runs. Shading is cheap relative to the test
suites
+ the cache is there to skip, so there is nothing worth caching here.
+ See .mvn/maven-build-cache-config.xml.
+ -->
+ <maven.build.cache.enabled>false</maven.build.cache.enabled>
+ </properties>
<dependencies>
<dependency>