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(replacements): support for replacement name templating #20905

Merged
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
72bb0e9
feat(auto-replace): support package prefix replacements
setchy Mar 12, 2023
448b0ac
refactor: extract replacement logic into helper functions. add suppo…
setchy Mar 13, 2023
8890fae
fix(lint): add import
setchy Mar 13, 2023
dbabf27
rename functions
setchy Mar 13, 2023
ddb1c66
refactor based on PR feedback
setchy Mar 13, 2023
5340e45
use nonEmptyString instead of not nullOrUndefined
setchy Mar 13, 2023
2476e90
remove config.versioning - redundant
setchy Mar 13, 2023
b3565ff
Merge branch 'main' into feature/20890-replacement-prefix-add-remove
setchy Mar 13, 2023
a45b53f
fix typo
setchy Mar 14, 2023
0b39e24
pivot to a replacementNameTemplate config option
setchy Mar 16, 2023
6ed5650
fix lint error
setchy Mar 16, 2023
1a4ef21
Merge branch 'main' into feature/20890-replacement-prefix-add-remove
setchy Mar 16, 2023
a50ee1f
update
setchy Mar 19, 2023
6c2041a
pivot to using a single new template
setchy Mar 19, 2023
f8c81c3
set compile to true so that only allowedValues are passed
setchy Mar 19, 2023
c3930ad
Merge branch 'main' into feature/20890-replacement-prefix-add-remove
setchy Mar 19, 2023
d5e0dd3
remove new template string. can use replace helper
setchy Mar 19, 2023
d3138dc
update tests
setchy Mar 19, 2023
ef8a350
revert
setchy Mar 19, 2023
ecb536c
update test
setchy Mar 20, 2023
c86c96a
Update lib/workers/repository/process/lookup/utils.ts
setchy Mar 20, 2023
27f1911
docs: improve docs
setchy Mar 21, 2023
99a6ad7
Merge branch 'main' into feature/20890-replacement-prefix-add-remove
setchy Mar 21, 2023
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
22 changes: 21 additions & 1 deletion docs/usage/configuration-options.md
Original file line number Diff line number Diff line change
Expand Up @@ -2134,9 +2134,29 @@ Managers which do not support replacement:
- `regex`

Use the `replacementName` config option to set the name of a replacement package.
Must be used with `replacementVersion` (see example below).

Can be used in combination with `replacementVersion`, `replacementPrefixAdd` and `replacmeentPrefixRemove`.
setchy marked this conversation as resolved.
Show resolved Hide resolved

You can suggest a new community package rule by editing [the `replacements.ts` file on the Renovate repository](https://github.com/renovatebot/renovate/blob/main/lib/config/presets/internal/replacements.ts) and opening a pull request.

### replacementPrefixAdd

Use the `replacementPrefixAdd` config option to add a new prefix to the name of the replacement package.

This is useful for situations such as migrating container registries / mirrors.

Can be used in combination with `replacementName`, `replacementVersion` and `replacmeentPrefixRemove`.

### replacementPrefixRemove

Use the `replacementPrefixRemove` config option to remove a prefix from the replacement package.

This is useful for situations such as migrating container registries / mirrors.

Can be used in combination with `replacementVersion` and `replacmeentPrefixAdd`.

If a `replacementName` has been used in the package rule, this will take priority.

### replacementVersion

This config option only works with some managers.
Expand Down
20 changes: 20 additions & 0 deletions lib/config/options/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1207,6 +1207,26 @@ const options: RenovateOptions[] = [
cli: false,
env: false,
},
{
name: 'replacementPrefixAdd',
description:
'The name of the new prefix to add to the old deprecated dependency.',
type: 'string',
stage: 'package',
parent: 'packageRules',
cli: false,
env: false,
},
{
name: 'replacementPrefixRemove',
description:
'The name of the new prefix to add to the old deprecated dependency.',
type: 'string',
stage: 'package',
parent: 'packageRules',
cli: false,
env: false,
},
{
name: 'replacementVersion',
description:
Expand Down
218 changes: 218 additions & 0 deletions lib/workers/repository/process/lookup/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1958,6 +1958,224 @@ describe('workers/repository/process/lookup/index', () => {
]);
});

it('handles replacements - can remove old prefix', async () => {
config.packageName = 'mirror.some.org/library/openjdk';
config.currentValue = '17.0.0';
config.replacementPrefixRemove = 'mirror.some.org/library/';
config.datasource = DockerDatasource.id;
getDockerReleases.mockResolvedValueOnce({
releases: [
{
version: '17.0.0',
},
{
version: '18.0.0',
},
],
});

expect((await lookup.lookupUpdates(config)).updates).toMatchObject([
{
updateType: 'replacement',
newName: 'openjdk',
newValue: '17.0.0',
},
{
updateType: 'major',
newMajor: 18,
newValue: '18.0.0',
newVersion: '18.0.0',
},
]);
});

it('handles replacements - will skip if prefix to remove does not match', async () => {
config.packageName = 'mirror.some.org/library/openjdk';
config.currentValue = '17.0.0';
config.replacementPrefixRemove = 'mirror.some.com/registry/';
config.datasource = DockerDatasource.id;
getDockerReleases.mockResolvedValueOnce({
releases: [
{
version: '17.0.0',
},
{
version: '18.0.0',
},
],
});

expect((await lookup.lookupUpdates(config)).updates).toMatchObject([
{
updateType: 'major',
newMajor: 18,
newValue: '18.0.0',
newVersion: '18.0.0',
},
]);
});

it('handles replacements - will add new prefix', async () => {
config.packageName = 'openjdk';
config.currentValue = '17.0.0';
config.replacementPrefixAdd = 'mirror.some.org/library/';
config.datasource = DockerDatasource.id;
getDockerReleases.mockResolvedValueOnce({
releases: [
{
version: '17.0.0',
},
{
version: '18.0.0',
},
],
});

expect((await lookup.lookupUpdates(config)).updates).toMatchObject([
{
updateType: 'replacement',
newName: 'mirror.some.org/library/openjdk',
newValue: '17.0.0',
},
{
updateType: 'major',
newMajor: 18,
newValue: '18.0.0',
newVersion: '18.0.0',
},
]);
});

it('handles replacements - can swap prefixes', async () => {
config.packageName = 'old.registry.net/library/openjdk';
config.currentValue = '17.0.0';
config.replacementPrefixRemove = 'old.registry.net/library/';
config.replacementPrefixAdd = 'new.registry.io/library/';
config.datasource = DockerDatasource.id;
getDockerReleases.mockResolvedValueOnce({
releases: [
{
version: '17.0.0',
},
{
version: '18.0.0',
},
],
});

expect((await lookup.lookupUpdates(config)).updates).toMatchObject([
{
updateType: 'replacement',
newName: 'new.registry.io/library/openjdk',
newValue: '17.0.0',
},
{
updateType: 'major',
newMajor: 18,
newValue: '18.0.0',
newVersion: '18.0.0',
},
]);
});

it('handles replacements - prefix to be removed not matched, but adds new prefix', async () => {
config.packageName = 'mirror.com/library/openjdk';
config.currentValue = '17.0.0';
config.replacementPrefixRemove = 'old.registry.net/library/';
config.replacementPrefixAdd = 'new.registry.io/library/';
config.datasource = DockerDatasource.id;
getDockerReleases.mockResolvedValueOnce({
releases: [
{
version: '17.0.0',
},
{
version: '18.0.0',
},
],
});

expect((await lookup.lookupUpdates(config)).updates).toMatchObject([
{
updateType: 'replacement',
newName: 'new.registry.io/library/mirror.com/library/openjdk',
newValue: '17.0.0',
},
{
updateType: 'major',
newMajor: 18,
newValue: '18.0.0',
newVersion: '18.0.0',
},
]);
});

it('handles replacements - replace name and prefix', async () => {
config.packageName = 'old.registry.net/library/openjdk';
config.currentValue = '17.0.0';
config.replacementPrefixRemove = 'old.registry.net/library/';
config.replacementPrefixAdd = 'new.registry.io/library/';
config.replacementName = 'eclipse-temurin';
config.datasource = DockerDatasource.id;
getDockerReleases.mockResolvedValueOnce({
releases: [
{
version: '17.0.0',
},
{
version: '18.0.0',
},
],
});

expect((await lookup.lookupUpdates(config)).updates).toMatchObject([
{
updateType: 'replacement',
newName: 'new.registry.io/library/eclipse-temurin',
newValue: '17.0.0',
},
{
updateType: 'major',
newMajor: 18,
newValue: '18.0.0',
newVersion: '18.0.0',
},
]);
});

it('handles replacements - replace prefixes and version', async () => {
config.packageName = 'old.registry.net/library/openjdk';
config.currentValue = '17.0.0';
config.replacementPrefixRemove = 'old.registry.net/library/';
config.replacementPrefixAdd = 'new.registry.io/library/';
config.replacementVersion = '18.0.0';
config.datasource = DockerDatasource.id;
getDockerReleases.mockResolvedValueOnce({
releases: [
{
version: '17.0.0',
},
{
version: '18.0.0',
},
],
});

expect((await lookup.lookupUpdates(config)).updates).toMatchObject([
{
updateType: 'replacement',
newName: 'new.registry.io/library/openjdk',
newValue: '18.0.0',
},
{
updateType: 'major',
newMajor: 18,
newValue: '18.0.0',
newVersion: '18.0.0',
},
]);
});

it('rollback for invalid version to last stable version', async () => {
config.currentValue = '2.5.17';
config.packageName = 'vue';
Expand Down
39 changes: 10 additions & 29 deletions lib/workers/repository/process/lookup/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ import { filterInternalChecks } from './filter-checks';
import { generateUpdate } from './generate';
import { getRollbackUpdate } from './rollback';
import type { LookupUpdateConfig, UpdateResult } from './types';
import {
addReplacementUpdateIfValid,
isReplacementNameRulesConfigured,
isReplacementRulesConfigured,
} from './utils';

export async function lookupUpdates(
inconfig: LookupUpdateConfig
Expand Down Expand Up @@ -157,27 +162,10 @@ export async function lookupUpdates(
}
let rangeStrategy = getRangeStrategy(config);

if (config.replacementName && !config.replacementVersion) {
res.updates.push({
updateType: 'replacement',
newName: config.replacementName,
newValue: currentValue!,
});
if (isReplacementRulesConfigured(config)) {
addReplacementUpdateIfValid(res.updates, config);
}

if (config.replacementName && config.replacementVersion) {
res.updates.push({
updateType: 'replacement',
newName: config.replacementName,
newValue: versioning.getNewValue({
// TODO #7154
currentValue: currentValue!,
newVersion: config.replacementVersion,
rangeStrategy: rangeStrategy!,
isReplacement: true,
})!,
});
}
// istanbul ignore next
if (
isVulnerabilityAlert &&
Expand Down Expand Up @@ -344,19 +332,12 @@ export async function lookupUpdates(
} else {
delete res.skipReason;
}
} else if (
!currentValue &&
config.replacementName &&
!config.replacementVersion
) {
} else if (!currentValue && isReplacementNameRulesConfigured(config)) {
logger.debug(
`Handle name-only replacement for ${packageName} without current version`
);
res.updates.push({
updateType: 'replacement',
newName: config.replacementName,
newValue: currentValue!,
});

addReplacementUpdateIfValid(res.updates, config);
} else {
res.skipReason = 'invalid-value';
}
Expand Down
2 changes: 2 additions & 0 deletions lib/workers/repository/process/lookup/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ export interface LookupUpdateConfig
packageName: string;
minimumConfidence?: string;
replacementName?: string;
replacementPrefixAdd?: string;
replacementPrefixRemove?: string;
replacementVersion?: string;
}

Expand Down
Loading