IMPORTANT: Developer documentation for the current development branch. This content is unreleased, may change without notice, and must not be treated as Buildish release documentation.

Cache Partitions

Built-in partitions, customization, glob rules, timestamp garbage collection, and restore cleanup for Buildish Mammoth Cache for Gradle and Maven.

The action splits the build tool’s cache directory into logical partitions. Partitions define which files are captured, compared, cleaned, and reported together inside one complete immutable cache generation. They keep unrelated file sets and ownership rules explicit; they are not saved as separate backend entries.

Built-in partitions

Gradle

The Gradle action resolves GRADLE_USER_HOME into these ordered partitions:

Partition Contents Default
modules Dependency artifacts, JARs, and resource stores enabled
transforms-metadata Artifact transforms and related metadata disabled
kotlin-dsl Compiled Kotlin DSL scripts and generated Gradle API JARs enabled
build-cache The local Gradle build cache enabled
wrapper-dists Wrapper-downloaded Gradle distributions enabled

See Gradle cache internals for details on what each partition covers and why certain directories are excluded.

Maven

The Maven action resolves the local repository (~/.m2 by default) into these partitions:

Partition Contents Default
repository Cached Maven artifact repository enabled
wrapper-dists Wrapper-downloaded Maven distributions enabled

See Maven cache internals for details on what each partition covers and why certain files are excluded.


Built-in partitions for both tools keep a deterministic order. Custom partitions are appended after the active built-ins in the order supplied by cache-partitions.

The resolved partition order plus each partition’s include/exclude set is hashed into partitionFingerprint, which is part of the cache family. Changing the active partition layout produces a different family and therefore starts a cold lineage for the complete managed state.

Include and exclude semantics

  • Includes define the files the action manages for a partition.
  • Excludes remove files from that partition after includes are matched.
  • Overriding a built-in replaces its built-in include/exclude lists.
  • Built-in overrides with includes: [] disable that built-in.
  • Custom partitions with includes: [] are rejected.
  • If the same file matches more than one active partition, manifest capture fails instead of guessing an owner.

Hard safety excludes are always applied to every active partition and cannot be removed:

Gradle

Pattern Reason
**/configuration-cache/** May contain encrypted secrets; volatile by nature
**/*.lock PID-bearing files that cause hangs if restored on another runner
caches/*/cc-keystore Configuration-cache encryption key material
caches/journal-1/** Gradle’s local-only file-access journal; migrating it causes corruption

Maven

Pattern Reason
**/*.lastUpdated Stale remote-check markers; cause silent re-resolution when shared across runners
**/resolver-status.properties Maven Resolver group-level remote-check status; per-runner state and a common distributed-merge conflict source
**/_remote.repositories Records which remote a file came from; not portable across different CI environments
**/*.lock PID-bearing resolver lock files that cause hangs if restored on another runner

Supported glob subset

All partition globs are relative to the build tool’s cache root (GRADLE_USER_HOME for Gradle, the Maven local repository for Maven).

  • Absolute paths are rejected.
  • .. traversal is rejected.
  • Negated globs are rejected.
  • Supported wildcards: * within a single path segment; ** as a whole path segment.
  • Include globs must end in /** and may not use ** anywhere except the final segment.
  • Exclude globs may use ** as a whole path segment anywhere in the pattern.
  • Other glob operators (?, character classes, braces, extglobs) are rejected.

Examples:

Glob Valid Type
caches/*/kotlin-dsl/** include
caches/modules-*/metadata-*/** exclude
**/*.lock exclude
/home/runner/.gradle/caches/** absolute path
caches/**/tmp/** ** not allowed mid-path in include
!caches/foo/** negated globs not supported

Partition customization example

 1[
 2  {
 3    "id": "modules",
 4    "includes": ["caches/modules-*/files-*/**", "caches/jars-*/**"],
 5    "excludes": ["caches/modules-*/metadata-*/**"]
 6  },
 7  {
 8    "id": "kotlin-dsl",
 9    "includes": []
10  },
11  {
12    "id": "custom-generated-jars",
13    "includes": ["caches/*/generated-gradle-jars/**"],
14    "excludes": []
15  }
16]

This example: overrides modules, disables kotlin-dsl, and adds a custom partition. The partitionFingerprint changes, so it uses a different cache family than the default layout.

Timestamp garbage collection

cache-gc-mode: timestamp is enabled by default to prevent managed cache partitions from growing without bound, especially Maven local repositories. GitHub Actions cache storage is finite, and a cache entry that only ever accumulates artifacts eventually becomes less useful or impossible to save.

Timestamp GC runs during finalize before standalone or distributed-aggregator jobs save the base cache. A file is eligible only when all of these are true:

  • The file is matched by exactly one active cache partition.
  • The file is not excluded by partition excludes or hard safety excludes.
  • Its modification time is older than cache-gc-older-than-days.
  • Its effective access time is older than cache-gc-older-than-days.

The effective access time is the newer of the file’s access time and modification time. This keeps newly written files even when access time data is stale or unavailable. The default threshold is 14 days, and the minimum accepted threshold is 2 days because common Linux, macOS, and Windows runner filesystems do not provide precise “updated on every read” access-time behavior.

Distributed-worker jobs skip timestamp GC because they upload delta artifacts instead of saving the base cache. The GC pass deletes eligible files and then removes empty parent directories. It does not delete unmanaged files elsewhere in the build tool cache directory. To disable it:

1cache-gc-mode: off

Use cache-gc-mode: off or a larger cache-gc-older-than-days value for jobs that intentionally rely on old, rarely touched artifacts and cannot redownload them.

Restore cleanup behavior

restore-cleanup-mode: prune-managed is the safe, narrow cleanup mode supported today.

  • It only runs after a base-cache hit.
  • It only deletes files currently matched by the active managed partitions.
  • After pruning, it restores the matched base cache again before the build starts.
  • It does not delete unmanaged files elsewhere in the build tool cache directory.
  • If you disable a partition, files from that now-disabled partition are no longer considered action-managed and are left untouched.
  • If the follow-up restore misses after pruning, the action fails rather than continuing with a partially pruned managed cache space.

This is intentionally narrower than “delete everything outside the include patterns” because the action does not own the entire build tool cache directory, especially on long-lived self-hosted runners.