apache / apache/maven-build-cache-extension

Add configurable remote build cache retention with pluggable strategies

Open
#531 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Java
Stars
163
Forks
77
Avg merge
1d 2h
Merged PRs (30d)
4

Description

## Description

The Maven Build Cache Extension currently limits only the local cache. Remote cache entries and cache reports can accumulate indefinitely in shared repositories, creating unnecessary storage growth and making repository maintenance difficult.

This issue proposes opt-in remote retention with configurable strategy providers.

## Configuration

Remote retention is disabled by default:

```xml


https://nexus.example/repository/build-cache/
5
300

```

Supported built-in strategies:

- `nexus`
- `directory-listing`
- `unsupported`

JVM overrides:

```text
-Dmaven.build.cache.maxRemoteBuildsCached=5
-Dmaven.build.cache.remote.cleanup.enabled=true
-Dmaven.build.cache.remote.cleanup.gracePeriodSeconds=300
-Dmaven.build.cache.remote.retention.strategy=nexus
```

`retentionStrategy` is required whenever `cleanupEnabled="true"`. Configuration fails clearly if it is missing or names an unknown provider. There is no URL-based strategy guessing.

## Behavior

For each cache namespace:

```text
///
```

the selected strategy:

- Retains the newest configured number of cache entries.
- Orders cache entries using `buildinfo.xml` timestamps.
- Uses remote asset timestamps for grace-period protection, falling back to the build timestamp when the strategy cannot determine an upload time.
- Does not delete newly uploaded assets during the configured grace period.
- Revalidates remote asset identity and timestamp before deletion.
- Treats already-deleted assets as a successful outcome.
- Cleans stale `build-cache-report.xml` assets separately.
- Preserves namespace isolation.
- Uses best-effort cleanup by default.
- Honors the existing `failFast` behavior.

Remote cleanup has no distributed lock. Concurrent builders may temporarily retain more entries than configured, but the grace period and pre-delete revalidation reduce the risk of deleting another builder's newly uploaded cache.

## Strategy SPI

Retention uses public Maven-native Plexus/Sisu extension points:

```java
public interface RemoteCacheRetentionStrategyProvider {
String name();

RemoteCacheRetentionStrategy create(
String url,
RemoteCacheHttpClient httpClient,
CacheConfig config,
XmlService xmlService);
}
```

The core extension currently provides:

- `NexusRawRetentionStrategyProvider`
- `DirectoryListingRetentionStrategyProvider`
- `UnsupportedRemoteRetentionStrategyProvider`

Future repository-specific implementations can be packaged separately and discovered through Plexus/Sisu.

## Nexus Raw Strategy

The Nexus strategy uses the documented Assets API:

```text
GET /service/rest/v1/assets?repository=
DELETE /service/rest/v1/assets/{assetId}
```

It:

- Handles pagination.
- Normalizes Nexus asset paths.
- Filters assets locally to the exact cache namespace.
- Uses asset IDs for deletion.
- Uses `lastModified` or `blobCreated` for age checks.
- Revalidates asset ID and timestamp before deletion.
- Cleans cache artifacts and build reports.

The configured Maven server must have permission to read and delete assets from the Nexus hosted repository.

Nexus Raw paths are virtual asset paths rather than real directories. The extension deletes assets, but cannot delete empty virtual folders independently.

## Generic HTTP/WebDAV Strategy

The generic strategy uses authenticated directory listings and HTTP DELETE requests.

It is supported only when the remote server provides:

- Stable directory listings.
- Readable cache files.
- File deletion.
- Directory/collection deletion where applicable.

Generic directory listings generally do not expose reliable per-entry timestamps. Therefore:

- Cache-entry ordering falls back to `buildinfo.xml` timestamps.
- Report retention is unsupported unless reliable remote metadata is available.
- Unsupported behavior is reported safely rather than guessed.

## Compatibility

- Remote retention is disabled by default.
- Existing local retention behavior is unchanged.
- Existing remote cache entries remain readable.
- Existing remote GET/PUT behavior is preserved.
- Existing XML and JVM property names remain unchanged.
- New configuration properties are additive.
- Compatibility-safe default methods are used for newly added public API methods where applicable.

## Open Questions

1. Should Nexus-specific retention remain bundled in the core extension or move to a separate artifact?
2. Should report retention have a separate limit from cache-entry retention?
3. Should future versions add an optional distributed locking provider?
4. Should the public SPI be stabilized in a separate API module before release?

Contributor guide

No contributing guide indexed for this repository

Research direction

Start by locating the RemoteCacheRetentionStrategyProvider SPI and the listed NexusRawRetentionStrategyProvider, DirectoryListingRetentionStrategyProvider, and UnsupportedRemoteRetentionStrategyProvider implementations. Read the existing remote-cache configuration and provider-discovery paths first; done requires the retention strategies, validation, compatibility behavior, and cleanup safeguards described here, with the open design questions resolved.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
build-system
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
28/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.