Skip to content

feat: support updateLockFiles for all managers #35993

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

Open
wants to merge 28 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
9640339
add option skipArtifactUpdating
reduckted May 15, 2025
bb83707
updated docs
reduckted May 15, 2025
40431d8
Removed `.only` test.
reduckted May 17, 2025
f0437a0
Changed debug log about running artifact updating.
reduckted May 17, 2025
816fb91
Fixed docs.
reduckted May 17, 2025
6cd89ff
Fixed test for skipping artifact updating with no updates.
reduckted May 17, 2025
8ac7a05
Updated docs.
reduckted May 18, 2025
6386fe1
Changed skipArtifactUpdating to be set against the branch config base…
reduckted May 18, 2025
7e4d8ba
Removed unused property.
reduckted May 18, 2025
e010a12
Merge branch 'main' into feature/33118-skip-artifact-updating
reduckted May 18, 2025
ad1f251
Added extra assertion.
reduckted May 21, 2025
509fc57
Added note about grouped upgrades.
reduckted May 21, 2025
98a1e91
Merge branch 'main' into feature/33118-skip-artifact-updating
reduckted May 21, 2025
cd80210
Updated docs.
reduckted May 25, 2025
5dda082
Avoided logging message when artifact updating would not occur anyway.
reduckted May 25, 2025
3a23c1b
Removed globalOnly from skipArtifactUpdating
reduckted May 25, 2025
280be65
Merge remote-tracking branch 'upstream/main' into feature/33118-skip-…
reduckted May 25, 2025
110f4fd
Update docs/usage/configuration-options.md
reduckted May 26, 2025
5064832
Update docs/usage/configuration-options.md
rarkins May 27, 2025
ebcdf6d
Used existing updateLockFile option instead of new skipArtifactUpdati…
reduckted May 27, 2025
e4f0355
Merge branch 'main' into feature/33118-skip-artifact-updating
reduckted May 27, 2025
656fa4b
Update lib/workers/repository/updates/generate.ts
reduckted May 29, 2025
1df4a57
Revert "Update lib/workers/repository/updates/generate.ts"
reduckted May 29, 2025
b7534ca
Merge branch 'main' into feature/33118-skip-artifact-updating
reduckted May 29, 2025
3a2b19c
Changed log message.
reduckted May 29, 2025
19449a2
tested updateLockFiles when first config is true and false.
reduckted May 29, 2025
4453b0c
Added logging when upgrades have mixed `updateLockFiles` values.
reduckted May 30, 2025
53786e9
Merge branch 'main' into feature/33118-skip-artifact-updating
reduckted May 30, 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
8 changes: 8 additions & 0 deletions docs/usage/configuration-options.md
Original file line number Diff line number Diff line change
Expand Up @@ -4275,6 +4275,14 @@ By default, Renovate skips versions in between, like `[email protected]`.

But if you set `separateMultipleMinor=true` then you get separate PRs for each minor stream, like `[email protected]`, `[email protected]` and `[email protected]`, etc.

## skipArtifactUpdating

Use this option in cases where automatic artifact updating can be problematic, or when you would like to customize how artifacts (such as lock files) are updated. When this option is set, you should update artifacts (such as lock files), via `postUpgradeTasks` or another method such as a CI workflow.

<!-- prettier-ignore -->
!!! note
When this option is set against individual package rules, and upgrades are grouped, artifact updating will only be skipped if every upgrade in a branch wants to skip it.

## skipInstalls

By default, Renovate will use the most efficient approach to updating package files and lock files, which in most cases skips the need to perform a full module install by the bot.
Expand Down
7 changes: 7 additions & 0 deletions lib/config/options/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3120,6 +3120,13 @@ const options: RenovateOptions[] = [
default: false,
globalOnly: true,
},
{
name: 'skipArtifactUpdating',
description: "Skip Renovate's automatic artifact updating.",
type: 'boolean',
default: false,
globalOnly: false,
},
];

export function getOptions(): RenovateOptions[] {
Expand Down
1 change: 1 addition & 0 deletions lib/config/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ export interface RenovateSharedConfig {
semanticCommitScope?: string | null;
semanticCommitType?: string;
semanticCommits?: 'auto' | 'enabled' | 'disabled';
skipArtifactUpdating?: boolean;
stopUpdatingLabel?: string;
suppressNotifications?: string[];
timezone?: string;
Expand Down
31 changes: 31 additions & 0 deletions lib/modules/manager/npm/post-update/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -559,6 +559,37 @@ describe('modules/manager/npm/post-update/index', () => {
});
});

it('skip artifact updating', async () => {
expect(
await getAdditionalFiles(
{
...updateConfig,
updateLockFiles: true,
reuseExistingBranch: true,
skipArtifactUpdating: true,
upgrades: [
{
depName: 'postcss',
isRemediation: true,
managerData: {
npmLock: 'package-lock.json',
},
rangeStrategy: 'widen',
},
],
},
additionalFiles,
),
).toStrictEqual({
artifactErrors: [],
updatedArtifacts: [],
});
expect(spyNpm).not.toHaveBeenCalled();
expect(logger.logger.debug).toHaveBeenCalledWith(
'Skipping lock file generation',
);
});

it('reuse existing up-to-date', async () => {
expect(
await getAdditionalFiles(
Expand Down
2 changes: 1 addition & 1 deletion lib/modules/manager/npm/post-update/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ export async function getAdditionalFiles(
if (!packageFiles.npm?.length) {
return { artifactErrors, updatedArtifacts };
}
if (!config.updateLockFiles) {
if (!config.updateLockFiles || config.skipArtifactUpdating) {
logger.debug('Skipping lock file generation');
return { artifactErrors, updatedArtifacts };
}
Expand Down
2 changes: 2 additions & 0 deletions lib/modules/manager/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export interface UpdateArtifactsConfig {
newVersion?: string;
newMajor?: number;
registryAliases?: Record<string, string>;
skipArtifactUpdating?: boolean;
lockFiles?: string[];
}

Expand Down Expand Up @@ -324,4 +325,5 @@ export interface PostUpdateConfig<T = Record<string, any>>
reuseExistingBranch?: boolean;

isLockFileMaintenance?: boolean;
skipArtifactUpdating?: boolean;
}
141 changes: 141 additions & 0 deletions lib/workers/repository/update/branch/get-updated.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -713,6 +713,147 @@ describe('workers/repository/update/branch/get-updated', () => {
});
});

it('does not update artifacts when skipArtifactUpdating=true', async () => {
const branchName = 'renovate/wheel-0.x';
const updateType = 'patch';
const lockedVersion = '0.45.0';
const newVersion = '0.45.1';
const currentValue = '==0.45.0';
const newRegexValue = newVersion;
const newValue = '==0.45.1';

const packageFile = 'requirements.in';
const lockFile = 'requirements.txt';

const regexWheelLookup: LookupUpdate = {
newVersion,
newValue: newRegexValue,
updateType,
branchName,
};

const pipCompileWheelLookup: LookupUpdate = {
...regexWheelLookup,
newValue,
};
const pipCompileWheelDep = {
currentValue,
lockedVersion,
updates: [pipCompileWheelLookup],
};

config.manager = 'pip-compile';
config.branchName = branchName;
config.skipArtifactUpdating = true;
config.upgrades.push({
packageFile,
lockFiles: [lockFile],
manager: 'pip-compile',
updateType,
depName: 'alpha',
currentValue,
newVersion,
branchName,
});
config.upgrades.push({
packageFile,
lockFiles: [lockFile],
manager: 'pip-compile',
updateType,
depName: 'beta',
currentValue,
newVersion,
branchName,
});

config.packageFiles = {
'pip-compile': [
{
packageFile,
lockFiles: [lockFile],
deps: [pipCompileWheelDep],
},
],
};

pipCompile.updateArtifacts.mockResolvedValue([]);
autoReplace.doAutoReplace.mockResolvedValue('new content');

await getUpdatedPackageFiles(config);

expect(pipCompile.updateArtifacts).not.toHaveBeenCalled();
});

it('updates artifacts when skipArtifactUpdating=false', async () => {
const branchName = 'renovate/wheel-0.x';
const updateType = 'patch';
const lockedVersion = '0.45.0';
const newVersion = '0.45.1';
const currentValue = '==0.45.0';
const newRegexValue = newVersion;
const newValue = '==0.45.1';

const packageFile = 'requirements.in';
const lockFile = 'requirements.txt';

const regexWheelLookup: LookupUpdate = {
newVersion,
newValue: newRegexValue,
updateType,
branchName,
};

const pipCompileWheelLookup: LookupUpdate = {
...regexWheelLookup,
newValue,
};
const pipCompileWheelDep = {
currentValue,
lockedVersion,
updates: [pipCompileWheelLookup],
};

config.manager = 'pip-compile';
config.branchName = branchName;
config.upgrades.push({
packageFile,
lockFiles: [lockFile],
manager: 'pip-compile',
updateType,
depName: 'alpha',
currentValue,
newVersion,
branchName,
});
config.upgrades.push({
packageFile,
lockFiles: [lockFile],
manager: 'pip-compile',
updateType,
depName: 'beta',
currentValue,
newVersion,
branchName,
});

config.packageFiles = {
'pip-compile': [
{
packageFile,
lockFiles: [lockFile],
deps: [pipCompileWheelDep],
},
],
};

pipCompile.updateArtifacts.mockResolvedValue([]);
autoReplace.doAutoReplace.mockResolvedValue('new content');

await getUpdatedPackageFiles(config);

expect(pipCompile.updateArtifacts).toHaveBeenCalledTimes(1);
});

it('attempts updateLockedDependency and handles unsupported', async () => {
config.upgrades.push({
packageFile: 'package.json',
Expand Down
8 changes: 8 additions & 0 deletions lib/workers/repository/update/branch/get-updated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,14 @@ async function managerUpdateArtifacts(
manager: string,
updateArtifact: UpdateArtifact,
): Promise<UpdateArtifactsResult[] | null> {
if (updateArtifact.config.skipArtifactUpdating) {
logger.debug(
{ manager, packageFileName: updateArtifact.packageFileName },
'skipping artifact updating',
);
return null;
}

const updateArtifacts = get(manager, 'updateArtifacts');
if (updateArtifacts) {
return await updateArtifacts(updateArtifact);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ exports[`workers/repository/updates/generate > generateBranchConfig() > handles
"prettyDepType": "dependency",
"recreateClosed": false,
"releaseTimestamp": undefined,
"skipArtifactUpdating": false,
"skipInstalls": true,
"upgrades": [
{
Expand Down Expand Up @@ -117,6 +118,7 @@ exports[`workers/repository/updates/generate > generateBranchConfig() > handles
"prettyDepType": "dependency",
"recreateClosed": false,
"releaseTimestamp": undefined,
"skipArtifactUpdating": false,
"skipInstalls": true,
"upgrades": [
{
Expand Down Expand Up @@ -197,6 +199,7 @@ exports[`workers/repository/updates/generate > generateBranchConfig() > handles
"prettyDepType": "dependency",
"recreateClosed": true,
"releaseTimestamp": undefined,
"skipArtifactUpdating": false,
"skipInstalls": true,
"upgrades": [
{
Expand Down Expand Up @@ -244,6 +247,7 @@ exports[`workers/repository/updates/generate > generateBranchConfig() > handles
"prettyNewVersion": "v1.0.1",
"recreateClosed": false,
"releaseTimestamp": undefined,
"skipArtifactUpdating": false,
"skipInstalls": true,
"upgrades": [
{
Expand Down
Loading