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

fix(matchConfidence): align supported datasources list with internal preset #26420

Merged
merged 9 commits into from
Dec 27, 2023
1 change: 1 addition & 0 deletions docs/usage/merge-confidence.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ Renovate will show Merge Confidence badges for these languages:

| Language | Datasource |
| ---------- | ----------- |
| Golang | `go` |
| JavaScript | `npm` |
| Java | `maven` |
| Python | `pypi` |
Expand Down
5 changes: 5 additions & 0 deletions docs/usage/self-hosted-experimental.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,11 @@ Skip initializing `RE2` for regular expressions and instead use Node-native `Reg
If set, Renovate will query this API for Merge Confidence data.
This feature is in private beta.

## `RENOVATE_X_MERGE_CONFIDENCE_SUPPORTED_DATASOURCES`

If set, Renovate will query the merge-confidence JSON API only for datasources that are part of this list.
The expected value for this environment variable is a JSON array of strings.

## `RENOVATE_X_PLATFORM_VERSION`

If set, Renovate will use this string as GitLab server version instead of checking via the GitLab API.
Expand Down
30 changes: 12 additions & 18 deletions lib/config/presets/internal/merge-confidence.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
import type { Preset } from '../types';

export const supportedDatasources = [
'go',
'maven',
'npm',
'nuget',
'packagist',
'pypi',
'rubygems',
];

export const presets: Record<string, Preset> = {
'all-badges': {
description: 'Show all Merge Confidence badges for pull requests.',
packageRules: [
{
matchDatasources: [
'maven',
'npm',
'nuget',
'packagist',
'pypi',
'rubygems',
'go',
],
matchDatasources: supportedDatasources,
matchUpdateTypes: ['patch', 'minor', 'major'],
prBodyColumns: [
'Package',
Expand All @@ -31,15 +33,7 @@ export const presets: Record<string, Preset> = {
'Show only the Age and Confidence Merge Confidence badges for pull requests.',
packageRules: [
{
matchDatasources: [
'maven',
'npm',
'nuget',
'packagist',
'pypi',
'rubygems',
'go',
],
matchDatasources: supportedDatasources,
matchUpdateTypes: ['patch', 'minor', 'major'],
prBodyColumns: ['Package', 'Change', 'Age', 'Confidence'],
},
Expand Down
72 changes: 69 additions & 3 deletions lib/util/merge-confidence/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
initConfig,
initMergeConfidence,
isActiveConfidenceLevel,
parseSupportedDatasourceString,
resetConfig,
satisfiesConfidenceLevel,
} from '.';
Expand Down Expand Up @@ -296,8 +297,11 @@ describe('util/merge-confidence/index', () => {
});

describe('initMergeConfidence()', () => {
it('using default base url if none is set', async () => {
beforeEach(() => {
resetConfig();
});

it('using default base url if none is set', async () => {
delete process.env.RENOVATE_X_MERGE_CONFIDENCE_API_BASE_URL;
httpMock
.scope(defaultApiBaseUrl)
Expand All @@ -309,12 +313,22 @@ describe('util/merge-confidence/index', () => {
'using default merge confidence API base URL',
);
expect(logger.debug).toHaveBeenCalledWith(
{
supportedDatasources: [
'go',
'maven',
'npm',
'nuget',
'packagist',
'pypi',
'rubygems',
],
},
'merge confidence API - successfully authenticated',
);
});

it('warns and then resolves if base url is invalid', async () => {
resetConfig();
process.env.RENOVATE_X_MERGE_CONFIDENCE_API_BASE_URL =
'invalid-url.com';
httpMock
Expand All @@ -328,12 +342,12 @@ describe('util/merge-confidence/index', () => {
'invalid merge confidence API base URL found in environment variables - using default value instead',
);
expect(logger.debug).toHaveBeenCalledWith(
expect.anything(),
'merge confidence API - successfully authenticated',
);
});

it('resolves if no token', async () => {
resetConfig();
hostRules.clear();

await expect(initMergeConfidence()).toResolve();
Expand All @@ -347,6 +361,7 @@ describe('util/merge-confidence/index', () => {

await expect(initMergeConfidence()).toResolve();
expect(logger.debug).toHaveBeenCalledWith(
expect.anything(),
'merge confidence API - successfully authenticated',
);
});
Expand Down Expand Up @@ -389,6 +404,57 @@ describe('util/merge-confidence/index', () => {
'merge confidence API request failed - aborting run',
);
});

describe('parseSupportedDatasourceList()', () => {
type ParseSupportedDatasourceTestCase = {
name: string;
datasourceListString: string | undefined;
expected: string[] | undefined;
};

afterEach(() => {
delete process.env.RENOVATE_X_MERGE_CONFIDENCE_SUPPORTED_DATASOURCES;
});

it.each([
{
name: 'it should do nothing when the input is undefined',
datasourceListString: undefined,
expected: undefined,
},
{
name: 'it should successfully parse the given datasource list',
datasourceListString: `["go","npm"]`,
expected: ['go', 'npm'],
},
{
name: 'it should gracefully handle invalid json',
datasourceListString: `{`,
expected: undefined,
},
{
name: 'it should discard non-array JSON input',
datasourceListString: `{}`,
expected: undefined,
},
{
name: 'it should discard non-string array JSON input',
datasourceListString: `[1,2]`,
expected: undefined,
},
])(
`$name`,
({
datasourceListString,
expected,
}: ParseSupportedDatasourceTestCase) => {
process.env.RENOVATE_X_MERGE_CONFIDENCE_SUPPORTED_DATASOURCES =
datasourceListString;

expect(parseSupportedDatasourceString()).toStrictEqual(expected);
},
);
});
});
});
});
43 changes: 40 additions & 3 deletions lib/util/merge-confidence/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import is from '@sindresorhus/is';
import { supportedDatasources as presetSupportedDatasources } from '../../config/presets/internal/merge-confidence';
import type { UpdateType } from '../../config/types';
import { logger } from '../../logger';
import { ExternalHostError } from '../../types/errors/external-host-error';
import * as packageCache from '../cache/package';
import { parseJson } from '../common';
import * as hostRules from '../host-rules';
import { Http } from '../http';
import { MERGE_CONFIDENCE } from './common';
Expand All @@ -12,8 +14,7 @@ const hostType = 'merge-confidence';
const http = new Http(hostType);
let token: string | undefined;
let apiBaseUrl: string | undefined;

const supportedDatasources = ['npm', 'maven', 'pypi'];
let supportedDatasources: string[] = [];

export const confidenceLevels: Record<MergeConfidence, number> = {
low: -1,
Expand All @@ -25,14 +26,47 @@ export const confidenceLevels: Record<MergeConfidence, number> = {
export function initConfig(): void {
apiBaseUrl = getApiBaseUrl();
token = getApiToken();
supportedDatasources =
parseSupportedDatasourceString() ?? presetSupportedDatasources;

if (!is.nullOrUndefined(token)) {
logger.debug(`Merge confidence token found for ${apiBaseUrl}`);
}
}

export function parseSupportedDatasourceString(): string[] | undefined {
const supportedDatasourceString =
process.env.RENOVATE_X_MERGE_CONFIDENCE_SUPPORTED_DATASOURCES;

if (!is.string(supportedDatasourceString)) {
return undefined;
}

let parsedDatasourceList: unknown;
try {
parsedDatasourceList = parseJson(supportedDatasourceString, '.json5');
} catch (err) {
logger.error(
{ supportedDatasourceString, err },
'Failed to parse supported datasources list; Invalid JSON format',
);
}

if (!is.array<string>(parsedDatasourceList, is.string)) {
logger.warn(
{ parsedDatasourceList },
`Expected a string array but got ${typeof parsedDatasourceList}`,
);
return undefined;
}

return parsedDatasourceList;
}

export function resetConfig(): void {
token = undefined;
apiBaseUrl = undefined;
supportedDatasources = [];
}

export function isMergeConfidence(value: string): value is MergeConfidence {
Expand Down Expand Up @@ -190,7 +224,10 @@ export async function initMergeConfidence(): Promise<void> {
apiErrorHandler(err);
}

logger.debug('merge confidence API - successfully authenticated');
logger.debug(
{ supportedDatasources },
'merge confidence API - successfully authenticated',
);
return;
}

Expand Down