Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(maven): Package cache provider #34959

Open
wants to merge 35 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 34 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
a37ca31
refactor(maven): Unify fetching utilities
zharinov Dec 9, 2024
02a7a22
Handle xml errors
zharinov Dec 9, 2024
0c36025
Add test
zharinov Dec 9, 2024
c333a04
Fix coverage
zharinov Dec 9, 2024
e0ccd67
Add log message
zharinov Dec 9, 2024
656d23a
Merge branch 'main' into refactor/maven-unify-http-fetch
zharinov Dec 10, 2024
e6b9b42
Merge branch 'main' into refactor/maven-unify-http-fetch
zharinov Dec 10, 2024
4faaf19
Better body helper
zharinov Dec 10, 2024
90acdad
Merge branch 'main' into refactor/maven-unify-http-fetch
zharinov Dec 12, 2024
fb94c0b
Merge branch 'main' into refactor/maven-unify-http-fetch
zharinov Dec 15, 2024
38d7598
refactor(maven): update body function signature to specify return type
zharinov Dec 15, 2024
6848213
Merge branch 'main' into refactor/maven-unify-http-fetch
zharinov Jan 6, 2025
dac0a11
Merge branch 'main' into refactor/maven-unify-http-fetch
zharinov Jan 6, 2025
ec1da11
Fix
zharinov Jan 6, 2025
44f530a
Revert lockfile
zharinov Jan 6, 2025
627945f
Fix lockfile
zharinov Jan 6, 2025
ae76089
Merge branch 'main' into refactor/maven-unify-http-fetch
zharinov Jan 6, 2025
871f882
Merge branch 'main' into refactor/maven-unify-http-fetch
zharinov Jan 28, 2025
fd5908d
Fix merge
zharinov Jan 28, 2025
c8d680e
Merge branch 'main' into refactor/maven-unify-http-fetch
zharinov Mar 23, 2025
0c04647
Fix test
zharinov Mar 23, 2025
db10d25
refactor(maven): change URL handling to only accept URL objects
zharinov Mar 23, 2025
5a2d96b
Correct the coverage
zharinov Mar 23, 2025
39c533b
feat: Add auth header check for package cache provider
zharinov Mar 23, 2025
984793c
Fix v8 ignore annotation in HTTP cache provider
zharinov Mar 23, 2025
a7ebba2
feat(maven): Use package cache provider
zharinov Mar 24, 2025
483c3ee
Revert unrelated changes
zharinov Mar 25, 2025
ee78e18
Merge branch 'main' into feat/maven-package-cache-provider
zharinov Mar 25, 2025
127a14d
Merge branch 'main' into feat/maven-package-cache-provider
zharinov Mar 30, 2025
a4804a7
Remove older caching
zharinov Mar 30, 2025
e4d77a2
Merge branch 'feat/cache-provider-check-auth-header' into feat/maven-…
zharinov Mar 30, 2025
d02a233
Fix params
zharinov Mar 30, 2025
a69ac2d
Merge branch 'main' into feat/maven-package-cache-provider
zharinov Mar 31, 2025
639f36e
Fix
zharinov Mar 31, 2025
867a24a
Merge branch 'main' into feat/maven-package-cache-provider
zharinov Apr 12, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions docs/usage/self-hosted-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -409,10 +409,8 @@ Valid codes for namespaces are as follows:
- `datasource-hexpm-bob`
- `datasource-java-version`
- `datasource-jenkins-plugins`
- `datasource-maven`
- `datasource-maven:head-requests-timeout`
- `datasource-maven:head-requests`
- `datasource-maven:metadata-xml`
- `datasource-maven:cache-provider`
- `datasource-maven:postprocess-reject`
- `datasource-node-version`
- `datasource-npm:data`
- `datasource-nuget-v3`
Expand Down
58 changes: 17 additions & 41 deletions lib/modules/datasource/maven/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import type { XmlDocument } from 'xmldoc';
import { GlobalConfig } from '../../../config/global';
import { logger } from '../../../logger';
import * as packageCache from '../../../util/cache/package';
import { asTimestamp } from '../../../util/timestamp';
Expand Down Expand Up @@ -42,15 +40,6 @@ function getLatestSuitableVersion(releases: Release[]): string | null {
);
}

function extractVersions(metadata: XmlDocument): string[] {
const versions = metadata.descendantWithPath('versioning.versions');
const elements = versions?.childrenNamed('version');
if (!elements) {
return [];
}
return elements.map((el) => el.val);
}

export const defaultRegistryUrls = [MAVEN_REPO];

export class MavenDatasource extends Datasource {
Expand Down Expand Up @@ -80,35 +69,16 @@ export class MavenDatasource extends Datasource {
repoUrl: string,
): Promise<string[]> {
const metadataUrl = getMavenUrl(dependency, repoUrl, 'maven-metadata.xml');

const cacheNamespace = 'datasource-maven:metadata-xml';
const cacheKey = `v2:${metadataUrl}`;
const cachedVersions = await packageCache.get<string[]>(
cacheNamespace,
cacheKey,
);
/* v8 ignore next 3 -- TODO: add test */
if (cachedVersions) {
return cachedVersions;
}

const metadataXmlResult = await downloadMavenXml(this.http, metadataUrl);
return metadataXmlResult
.transform(
async ({ isCacheable, data: mavenMetadata }): Promise<string[]> => {
const versions = extractVersions(mavenMetadata);
const cachePrivatePackages = GlobalConfig.get(
'cachePrivatePackages',
false,
);

if (cachePrivatePackages || isCacheable) {
await packageCache.set(cacheNamespace, cacheKey, versions, 30);
}

return versions;
},
)
.transform(({ data: metadata }) => {
const versions = metadata.descendantWithPath('versioning.versions');
const elements = versions?.childrenNamed('version');
if (!elements) {
return [];
}
return elements.map((el) => el.val);
})
.onError((err) => {
logger.debug(
`Maven: error fetching versions for "${dependency.display}": ${err.type}`,
Expand Down Expand Up @@ -176,7 +146,7 @@ export class MavenDatasource extends Datasource {
? `postprocessRelease:${registryUrl}:${packageName}:${versionOrig}:${version}`
: `postprocessRelease:${registryUrl}:${packageName}:${version}`;
const cachedResult = await packageCache.get<PostprocessReleaseResult>(
'datasource-maven',
'datasource-maven:postprocess-reject',
cacheKey,
);

Expand Down Expand Up @@ -205,15 +175,21 @@ export class MavenDatasource extends Datasource {
if (err) {
const result: PostprocessReleaseResult =
err.type === 'not-found' ? 'reject' : release;
await packageCache.set('datasource-maven', cacheKey, result, 24 * 60);
if (result === 'reject') {
await packageCache.set(
'datasource-maven:postprocess-reject',
cacheKey,
result,
24 * 60,
);
}
return result;
}

if (val.lastModified) {
release.releaseTimestamp = asTimestamp(val.lastModified);
}

await packageCache.set('datasource-maven', cacheKey, release, 7 * 24 * 60);
return release;
Copy link
Collaborator Author

@zharinov zharinov Mar 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now handled by cache provider

}
}
9 changes: 8 additions & 1 deletion lib/modules/datasource/maven/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { HOST_DISABLED } from '../../../constants/error-messages';
import { logger } from '../../../logger';
import { ExternalHostError } from '../../../types/errors/external-host-error';
import { type Http, HttpError } from '../../../util/http';
import { PackageHttpCacheProvider } from '../../../util/http/cache/package-http-cache-provider';
import type { HttpOptions, HttpResponse } from '../../../util/http/types';
import { regEx } from '../../../util/regex';
import { Result } from '../../../util/result';
Expand Down Expand Up @@ -63,14 +64,20 @@ function isUnsupportedHostError(err: HttpError): boolean {
return err.name === 'UnsupportedProtocolError';
}

const cacheProvider = new PackageHttpCacheProvider({
namespace: 'datasource-maven:cache-provider',
ttlMinutes: 7 * 24 * 60,
checkCacheControlHeader: false, // Maven doesn't respond with `cache-control` headers
});

export async function downloadHttpProtocol(
http: Http,
pkgUrl: URL | string,
opts: HttpOptions = {},
): Promise<MavenFetchResult> {
const url = pkgUrl.toString();
const fetchResult = await Result.wrap<HttpResponse, Error>(
http.getText(url, opts),
http.getText(url, { ...opts, cacheProvider }),
)
.transform((res): MavenFetchSuccess => {
const result: MavenFetchSuccess = { data: res.body };
Expand Down
6 changes: 2 additions & 4 deletions lib/util/cache/package/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,8 @@ export type PackageCacheNamespace =
| 'datasource-hexpm-bob'
| 'datasource-java-version'
| 'datasource-jenkins-plugins'
| 'datasource-maven'
| 'datasource-maven:head-requests-timeout'
| 'datasource-maven:head-requests'
| 'datasource-maven:metadata-xml'
| 'datasource-maven:cache-provider'
| 'datasource-maven:postprocess-reject'
| 'datasource-node-version'
| 'datasource-npm:data'
| 'datasource-nuget-v3'
Expand Down
Loading