Skip to content

Commit afd6415

Browse files
fix(workers/auto-replace): correctly handle prefix replacements (#35265)
1 parent 790d0ea commit afd6415

File tree

2 files changed

+116
-5
lines changed

2 files changed

+116
-5
lines changed

lib/workers/repository/update/branch/auto-replace.spec.ts

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -757,6 +757,76 @@ describe('workers/repository/update/branch/auto-replace', () => {
757757
);
758758
});
759759

760+
it('updates with helm value image/repository wrong version', async () => {
761+
const yml = codeBlock`
762+
parser:
763+
test: 3.14.3
764+
image:
765+
repository: docker.io/securecodebox/parser-nmap
766+
tag: 2.14.3
767+
`;
768+
upgrade.manager = 'helm-values';
769+
upgrade.depName = 'docker.io/securecodebox/parser-nmap';
770+
upgrade.replaceString = '3.14.3';
771+
upgrade.currentValue = '3.14.3';
772+
upgrade.depIndex = 0;
773+
upgrade.updateType = 'replacement';
774+
upgrade.newName = 'iteratec/juice-balancer';
775+
upgrade.newValue = 'v5.1.0';
776+
upgrade.packageFile = 'values.yml';
777+
await expect(
778+
doAutoReplace(upgrade, yml, reuseExistingBranch),
779+
).rejects.toThrowError(WORKER_FILE_UPDATE_FAILED);
780+
});
781+
782+
it('updates with helm value image/repository prefix replacement', async () => {
783+
const yml = codeBlock`
784+
parser:
785+
image:
786+
repository: example.org/securecodebox/parser-nmap
787+
tag: 3.14.3
788+
`;
789+
upgrade.manager = 'helm-values';
790+
upgrade.depName = 'example.org/securecodebox/parser-nmap';
791+
upgrade.replaceString = '3.14.3';
792+
upgrade.currentValue = '3.14.3';
793+
upgrade.depIndex = 0;
794+
upgrade.updateType = 'replacement';
795+
upgrade.newName = 'docker.example.org/securecodebox/parser-nmap';
796+
upgrade.newValue = 'v5.1.0';
797+
upgrade.packageFile = 'values.yml';
798+
const res = await doAutoReplace(upgrade, yml, reuseExistingBranch);
799+
expect(res).toBe(
800+
yml
801+
.replace(upgrade.depName, upgrade.newName)
802+
.replace(upgrade.currentValue, upgrade.newValue),
803+
);
804+
});
805+
806+
it('updates with helm value image/repository version prefix replacement', async () => {
807+
const yml = codeBlock`
808+
parser:
809+
image:
810+
tag: 3.14.3
811+
repository: docker.io/securecodebox/parser-nmap
812+
`;
813+
upgrade.manager = 'helm-values';
814+
upgrade.depName = 'docker.io/securecodebox/parser-nmap';
815+
upgrade.replaceString = '3.14.3';
816+
upgrade.currentValue = '3.14.3';
817+
upgrade.depIndex = 0;
818+
upgrade.updateType = 'replacement';
819+
upgrade.newName = 'iteratec/juice-balancer';
820+
upgrade.newValue = 'v3.14.3';
821+
upgrade.packageFile = 'values.yml';
822+
const res = await doAutoReplace(upgrade, yml, reuseExistingBranch);
823+
expect(res).toBe(
824+
yml
825+
.replace(upgrade.depName, upgrade.newName)
826+
.replace(upgrade.currentValue, upgrade.newValue),
827+
);
828+
});
829+
760830
it('updates with jenkins plugin replacement', async () => {
761831
const txt = 'script-security:1175\n';
762832
upgrade.manager = 'jenkins';

lib/workers/repository/update/branch/auto-replace.ts

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,21 @@ function getDepsSignature(deps: PackageDependency[]): string {
134134
.join(',');
135135
}
136136

137+
function firstIndexOf(
138+
existingContent: string,
139+
depName: string,
140+
currentValue: string,
141+
position = 0,
142+
): number {
143+
const depIndex = existingContent.indexOf(depName, position);
144+
const valIndex = existingContent.indexOf(currentValue, position);
145+
const index = depIndex < valIndex ? depIndex : valIndex;
146+
if (index < 0) {
147+
return position === 0 ? -1 : existingContent.length;
148+
}
149+
return index;
150+
}
151+
137152
export async function checkBranchDepsMatchBaseDeps(
138153
upgrade: BranchUpgradeConfig,
139154
branchContent: string,
@@ -218,9 +233,7 @@ export async function doAutoReplace(
218233
logger.trace({ depName, replaceString }, 'autoReplace replaceString');
219234
let searchIndex: number;
220235
if (replaceWithoutReplaceString) {
221-
const depIndex = existingContent.indexOf(depName!);
222-
const valIndex = existingContent.indexOf(currentValue!);
223-
searchIndex = depIndex < valIndex ? depIndex : valIndex;
236+
searchIndex = firstIndexOf(existingContent, depName!, currentValue!);
224237
} else {
225238
searchIndex = existingContent.indexOf(replaceString!);
226239
}
@@ -317,8 +330,13 @@ export async function doAutoReplace(
317330
`Found depName at index ${searchIndex}`,
318331
);
319332
if (nameReplaced) {
320-
startIndex += 1;
321-
searchIndex = startIndex;
333+
startIndex = firstIndexOf(
334+
existingContent,
335+
depName!,
336+
currentValue!,
337+
startIndex + 1,
338+
);
339+
searchIndex = startIndex - 1;
322340
await writeLocalFile(upgrade.packageFile!, existingContent);
323341
newContent = existingContent;
324342
nameReplaced = false;
@@ -329,6 +347,7 @@ export async function doAutoReplace(
329347
newContent = replaceAt(newContent, searchIndex, depName!, newName);
330348
await writeLocalFile(upgrade.packageFile!, newContent);
331349
nameReplaced = true;
350+
searchIndex += newName.length - 1;
332351
} else if (
333352
newValue &&
334353
matchAt(newContent, searchIndex, currentValue!)
@@ -337,6 +356,20 @@ export async function doAutoReplace(
337356
{ packageFile, currentValue },
338357
`Found currentValue at index ${searchIndex}`,
339358
);
359+
if (valueReplaced) {
360+
startIndex = firstIndexOf(
361+
existingContent,
362+
depName!,
363+
currentValue!,
364+
startIndex + 1,
365+
);
366+
searchIndex = startIndex - 1;
367+
await writeLocalFile(upgrade.packageFile!, existingContent);
368+
newContent = existingContent;
369+
nameReplaced = false;
370+
valueReplaced = false;
371+
continue;
372+
}
340373
// Now test if the result matches
341374
newContent = replaceAt(
342375
newContent,
@@ -346,11 +379,19 @@ export async function doAutoReplace(
346379
);
347380
await writeLocalFile(upgrade.packageFile!, newContent);
348381
valueReplaced = true;
382+
searchIndex += newValue.length - 1;
349383
}
350384
if (nameReplaced && valueReplaced) {
351385
if (await confirmIfDepUpdated(upgrade, newContent)) {
352386
return newContent;
353387
}
388+
startIndex = firstIndexOf(
389+
existingContent,
390+
depName!,
391+
currentValue!,
392+
startIndex + 1,
393+
);
394+
searchIndex = startIndex - 1;
354395
await writeLocalFile(upgrade.packageFile!, existingContent);
355396
newContent = existingContent;
356397
nameReplaced = false;

0 commit comments

Comments
 (0)