Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: renovatebot/renovate
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 34.157.0
Choose a base ref
...
head repository: renovatebot/renovate
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 34.157.1
Choose a head ref
  • 7 commits
  • 9 files changed
  • 6 contributors

Commits on Mar 4, 2023

  1. Copy the full SHA
    865608a View commit details
  2. chore(deps): update dependency eslint-formatter-gha to v1.4.2 (#20747)

    Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
    renovate[bot] authored Mar 4, 2023
    Copy the full SHA
    a610800 View commit details

Commits on Mar 5, 2023

  1. Copy the full SHA
    d0f66ed View commit details
  2. chore(deps): update dependency eslint to v8.35.0 (#20757)

    Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
    renovate[bot] authored Mar 5, 2023
    Copy the full SHA
    06b9f70 View commit details
  3. chore(deps): update dependency type-fest to v3.6.1 (#20758)

    Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
    renovate[bot] authored Mar 5, 2023
    Copy the full SHA
    939c793 View commit details
  4. fix(datasource/docker): Artifactory next link is broken for tags api (#…

    …20745)
    
    Co-authored-by: Rhys Arkins <rhys@arkins.net>
    Co-authored-by: Michael Kriese <michael.kriese@visualon.de>
    3 people authored Mar 5, 2023
    Copy the full SHA
    eb5db5b View commit details
  5. Copy the full SHA
    923755e View commit details
2 changes: 1 addition & 1 deletion .github/workflows/update-data.yml
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@ on:
workflow_dispatch:

env:
NODE_VERSION: 16
NODE_VERSION: 18

permissions:
contents: write
4 changes: 3 additions & 1 deletion lib/modules/datasource/docker/common.ts
Original file line number Diff line number Diff line change
@@ -10,6 +10,8 @@ export const gitRefLabel = 'org.opencontainers.image.revision';

const JFROG_ARTIFACTORY_RES_HEADER = 'x-jfrog-version';

export function isArtifactoryServer(res: HttpResponse | undefined): boolean {
export function isArtifactoryServer<T = unknown>(
res: HttpResponse<T> | undefined
): boolean {
return is.string(res?.headers[JFROG_ARTIFACTORY_RES_HEADER]);
}
66 changes: 40 additions & 26 deletions lib/modules/datasource/docker/index.spec.ts
Original file line number Diff line number Diff line change
@@ -5,6 +5,7 @@ import {
} from '@aws-sdk/client-ecr';
import { mockClient } from 'aws-sdk-client-mock';
import { getDigest, getPkgReleases } from '..';
import { range } from '../../../../lib/util/range';
import * as httpMock from '../../../../test/http-mock';
import { logger, mocked } from '../../../../test/util';
import {
@@ -1193,32 +1194,45 @@ describe('modules/datasource/docker/index', () => {
await expect(getPkgReleases(config)).rejects.toThrow(EXTERNAL_HOST_ERROR);
});

it.each([[true], [false]])(
'jfrog artifactory - retry tags for official images by injecting `/library` after repository and before image, abortOnError=%p',
async (abortOnError) => {
hostRules.find.mockReturnValue({ abortOnError });
const tags = ['18.0.0'];
httpMock
.scope('https://org.jfrog.io/v2')
.get('/virtual-mirror/node/tags/list?n=10000')
.reply(200, '', {})
.get('/virtual-mirror/node/tags/list?n=10000')
.reply(404, '', { 'x-jfrog-version': 'Artifactory/7.42.2 74202900' })
.get('/virtual-mirror/library/node/tags/list?n=10000')
.reply(200, '', {})
.get('/virtual-mirror/library/node/tags/list?n=10000')
.reply(200, { tags }, {})
.get('/')
.reply(200, '', {})
.get('/virtual-mirror/node/manifests/18.0.0')
.reply(200, '', {});
const res = await getPkgReleases({
datasource: DockerDatasource.id,
depName: 'org.jfrog.io/virtual-mirror/node',
});
expect(res?.releases).toHaveLength(1);
}
);
it('jfrog artifactory - retry tags for official images by injecting `/library` after repository and before image', async () => {
const tags1 = [...range(1, 10000)].map((i) => `${i}.0.0`);
const tags2 = [...range(10000, 10050)].map((i) => `${i}.0.0`);
httpMock
.scope('https://org.jfrog.io/v2')
.get('/virtual-mirror/node/tags/list?n=10000')
.reply(200, '', { 'x-jfrog-version': 'Artifactory/7.42.2 74202900' })
.get('/virtual-mirror/node/tags/list?n=10000')
.reply(404, '', { 'x-jfrog-version': 'Artifactory/7.42.2 74202900' })
.get('/virtual-mirror/library/node/tags/list?n=10000')
.reply(200, '', {})
.get('/virtual-mirror/library/node/tags/list?n=10000')
// Note the Link is incorrect and should be `</virtual-mirror/library/node/tags/list?n=10000&last=10000>; rel="next", `
// Artifactory incorrectly returns a next link without the virtual repository name
// this is due to a bug in Artifactory https://jfrog.atlassian.net/browse/RTFACT-18971
.reply(
200,
{ tags: tags1 },
{
'x-jfrog-version': 'Artifactory/7.42.2 74202900',
link: '</library/node/tags/list?n=10000&last=10000>; rel="next", ',
}
)
.get('/virtual-mirror/library/node/tags/list?n=10000&last=10000')
.reply(
200,
{ tags: tags2 },
{ 'x-jfrog-version': 'Artifactory/7.42.2 74202900' }
)
.get('/')
.reply(200, '', {})
.get('/virtual-mirror/node/manifests/10050.0.0')
.reply(200, '', {});
const res = await getPkgReleases({
datasource: DockerDatasource.id,
depName: 'org.jfrog.io/virtual-mirror/node',
});
expect(res?.releases).toHaveLength(10050);
});

it('uses lower tag limit for ECR deps', async () => {
httpMock
10 changes: 9 additions & 1 deletion lib/modules/datasource/docker/index.ts
Original file line number Diff line number Diff line change
@@ -883,7 +883,15 @@ export class DockerDatasource extends Datasource {
}
tags = tags.concat(res.body.tags);
const linkHeader = parseLinkHeader(res.headers.link);
url = linkHeader?.next ? URL.resolve(url, linkHeader.next.url) : null;
if (isArtifactoryServer(res)) {
// Artifactory incorrectly returns a next link without the virtual repository name
// this is due to a bug in Artifactory https://jfrog.atlassian.net/browse/RTFACT-18971
url = linkHeader?.next?.last
? `${url}&last=${linkHeader.next.last}`
: null;
} else {
url = linkHeader?.next ? URL.resolve(url, linkHeader.next.url) : null;
}
page += 1;
} while (url && page < 20);
return tags;
46 changes: 32 additions & 14 deletions lib/workers/repository/update/branch/auto-replace.spec.ts
Original file line number Diff line number Diff line change
@@ -233,6 +233,24 @@ describe('workers/repository/update/branch/auto-replace', () => {
await expect(res).rejects.toThrow(WORKER_FILE_UPDATE_FAILED);
});

it('fails with digest mismatch', async () => {
const dockerfile = codeBlock`
FROM java:11@sha256-1234 as build
`;
upgrade.manager = 'dockerfile';
upgrade.pinDigests = true;
upgrade.depName = 'java';
upgrade.currentValue = '11';
upgrade.currentDigest = 'sha256-1234';
upgrade.depIndex = 0;
upgrade.newName = 'java';
upgrade.newValue = '11';
upgrade.newDigest = 'sha256-5678';
upgrade.packageFile = 'Dockerfile';
const res = doAutoReplace(upgrade, dockerfile, reuseExistingBranch);
await expect(res).rejects.toThrow(WORKER_FILE_UPDATE_FAILED);
});

it('updates with docker replacement', async () => {
const dockerfile = 'FROM bitnami/redis:6.0.8';
upgrade.manager = 'dockerfile';
@@ -1044,12 +1062,12 @@ describe('workers/repository/update/branch/auto-replace', () => {
FROM ubuntu:18.04
`;
upgrade.manager = 'dockerfile';
upgrade.updateType = 'replacement';
upgrade.pinDigests = true;
upgrade.depName = 'ubuntu';
upgrade.currentValue = '18.04';
upgrade.currentDigest = undefined;
upgrade.depIndex = 0;
upgrade.pinDigests = true;
upgrade.updateType = 'replacement';
upgrade.replaceString = 'ubuntu:18.04';
upgrade.newName = 'alpine';
upgrade.newValue = '3.16';
@@ -1068,12 +1086,12 @@ describe('workers/repository/update/branch/auto-replace', () => {
FROM ubuntu:18.04@sha256:q1w2e3r4t5z6u7i8o9p0
`;
upgrade.manager = 'dockerfile';
upgrade.updateType = 'replacement';
upgrade.pinDigests = true;
upgrade.depName = 'ubuntu';
upgrade.currentValue = '18.04';
upgrade.currentDigest = 'sha256:q1w2e3r4t5z6u7i8o9p0';
upgrade.depIndex = 0;
upgrade.pinDigests = true;
upgrade.updateType = 'replacement';
upgrade.replaceString = 'ubuntu:18.04@sha256:q1w2e3r4t5z6u7i8o9p0';
upgrade.newName = 'alpine';
upgrade.newValue = '3.16';
@@ -1090,6 +1108,7 @@ describe('workers/repository/update/branch/auto-replace', () => {
it('regex: updates with pinDigest enabled but no currentDigest value', async () => {
const yml = 'image: "some.url.com/my-repository:1.0"';
upgrade.manager = 'regex';
upgrade.updateType = 'replacement';
upgrade.pinDigests = true;
upgrade.depName = 'some.url.com/my-repository';
upgrade.currentValue = '1.0';
@@ -1111,6 +1130,7 @@ describe('workers/repository/update/branch/auto-replace', () => {
const yml =
'image: "some.url.com/my-repository:1.0@sha256:q1w2e3r4t5z6u7i8o9p0"';
upgrade.manager = 'regex';
upgrade.updateType = 'replacement';
upgrade.pinDigests = true;
upgrade.depName = 'some.url.com/my-repository';
upgrade.currentValue = '1.0';
@@ -1131,7 +1151,7 @@ describe('workers/repository/update/branch/auto-replace', () => {
);
});

it('github-actions: update with newValue only', async () => {
it('github-actions: updates with newValue only', async () => {
const githubAction = codeBlock`
jobs:
build:
@@ -1140,15 +1160,14 @@ describe('workers/repository/update/branch/auto-replace', () => {
- uses: actions/checkout@v1.0.0
`;
upgrade.manager = 'github-actions';
upgrade.updateType = 'replacement';
upgrade.autoReplaceStringTemplate =
'{{depName}}@{{#if newDigest}}{{newDigest}}{{#if newValue}} # {{newValue}}{{/if}}{{/if}}{{#unless newDigest}}{{newValue}}{{/unless}}';
upgrade.depName = 'actions/checkout';
upgrade.currentValue = 'v1.0.0';
upgrade.currentDigest = undefined;
upgrade.currentDigestShort = undefined;
upgrade.depIndex = 0;
upgrade.pinDigests = true;
upgrade.updateType = 'replacement';
upgrade.replaceString = 'actions/checkout@v1.0.0';
upgrade.newValue = 'v2.0.0';
upgrade.newDigest = undefined;
@@ -1169,7 +1188,7 @@ describe('workers/repository/update/branch/auto-replace', () => {
);
});

it('github-actions: update with newValue and newDigest', async () => {
it('github-actions: updates with newValue and newDigest', async () => {
const githubAction = codeBlock`
jobs:
build:
@@ -1178,15 +1197,14 @@ describe('workers/repository/update/branch/auto-replace', () => {
- uses: actions/checkout@v1.0.0
`;
upgrade.manager = 'github-actions';
upgrade.updateType = 'replacement';
upgrade.autoReplaceStringTemplate =
'{{depName}}@{{#if newDigest}}{{newDigest}}{{#if newValue}} # {{newValue}}{{/if}}{{/if}}{{#unless newDigest}}{{newValue}}{{/unless}}';
upgrade.depName = 'actions/checkout';
upgrade.currentValue = 'v1.0.0';
upgrade.currentDigest = undefined;
upgrade.currentDigestShort = undefined;
upgrade.depIndex = 0;
upgrade.pinDigests = true;
upgrade.updateType = 'replacement';
upgrade.replaceString = 'actions/checkout@v1.0.0';
upgrade.newValue = 'v2.0.0';
upgrade.newDigest = '1cf887';
@@ -1216,15 +1234,15 @@ describe('workers/repository/update/branch/auto-replace', () => {
- uses: actions/checkout@v1.0.0
`;
upgrade.manager = 'github-actions';
upgrade.updateType = 'replacement';
upgrade.pinDigests = true;
upgrade.autoReplaceStringTemplate =
'{{depName}}@{{#if newDigest}}{{newDigest}}{{#if newValue}} # {{newValue}}{{/if}}{{/if}}{{#unless newDigest}}{{newValue}}{{/unless}}';
upgrade.depName = 'actions/checkout';
upgrade.currentValue = 'v1.0.0';
upgrade.currentDigest = undefined;
upgrade.currentDigestShort = undefined;
upgrade.depIndex = 0;
upgrade.pinDigests = true;
upgrade.updateType = 'replacement';
upgrade.replaceString = 'actions/checkout@v1.0.0';
upgrade.newName = 'some-other-action/checkout';
upgrade.newValue = 'v2.0.0';
@@ -1255,14 +1273,14 @@ describe('workers/repository/update/branch/auto-replace', () => {
- uses: actions/checkout@2485f4 # tag=v1.0.0
`;
upgrade.manager = 'github-actions';
upgrade.updateType = 'replacement';
upgrade.pinDigests = true;
upgrade.autoReplaceStringTemplate =
'{{depName}}@{{#if newDigest}}{{newDigest}}{{#if newValue}} # {{newValue}}{{/if}}{{/if}}{{#unless newDigest}}{{newValue}}{{/unless}}';
upgrade.depName = 'actions/checkout';
upgrade.currentValue = 'v1.0.0';
upgrade.currentDigestShort = '2485f4';
upgrade.depIndex = 0;
upgrade.pinDigests = true;
upgrade.updateType = 'replacement';
upgrade.replaceString = 'actions/checkout@2485f4 # tag=v1.0.0';
upgrade.newName = 'some-other-action/checkout';
upgrade.newValue = 'v2.0.0';
57 changes: 32 additions & 25 deletions lib/workers/repository/update/branch/auto-replace.ts
Original file line number Diff line number Diff line change
@@ -14,15 +14,7 @@ export async function confirmIfDepUpdated(
upgrade: BranchUpgradeConfig,
newContent: string
): Promise<boolean> {
const {
manager,
packageFile,
newValue,
newDigest,
depIndex,
currentDigest,
pinDigests,
} = upgrade;
const { manager, packageFile, depIndex } = upgrade;
let newUpgrade: PackageDependency;
try {
const newExtract = await extractPackageFile(
@@ -63,35 +55,50 @@ export async function confirmIfDepUpdated(
return false;
}

if (newValue && newUpgrade.currentValue !== newValue) {
if (upgrade.newName && upgrade.newName !== newUpgrade.depName) {
logger.debug(
{
manager,
packageFile,
currentDepName: upgrade.depName,
newDepName: newUpgrade.depName,
},
'depName is not updated'
);
return false;
}

if (upgrade.newValue && upgrade.newValue !== newUpgrade.currentValue) {
logger.debug(
{
manager,
packageFile,
expectedValue: newValue,
expectedValue: upgrade.newValue,
foundValue: newUpgrade.currentValue,
},
'Value is not updated'
);
return false;
}

if (!newDigest) {
return true;
}
if (newUpgrade.currentDigest === newDigest) {
return true;
}
if (!currentDigest) {
if (!pinDigests) {
return true;
} else if (newDigest) {
return true;
}
if (
upgrade.newDigest &&
(upgrade.isPinDigest || upgrade.currentDigest) &&
upgrade.newDigest !== newUpgrade.currentDigest
) {
logger.debug(
{
manager,
packageFile,
expectedValue: upgrade.newDigest,
foundValue: newUpgrade.currentDigest,
},
'Digest is not updated'
);
return false;
}

// istanbul ignore next
return false;
return true;
}

function getDepsSignature(deps: PackageDependency[]): string {
25 changes: 7 additions & 18 deletions lib/workers/repository/update/branch/schedule.spec.ts
Original file line number Diff line number Diff line change
@@ -264,24 +264,13 @@ describe('workers/repository/update/branch/schedule', () => {
});

describe('supports timezone', () => {
const cases: [string, string, string, boolean][] = [
['after 4pm', 'Asia/Singapore', '2017-06-30T15:59:00.000+0800', false],
['after 4pm', 'Asia/Singapore', '2017-06-30T16:01:00.000+0800', true],
[
'before 3am on Monday',
'Asia/Tokyo',
'2017-06-26T02:59:00.000+0900',
true,
],
[
'before 3am on Monday',
'Asia/Tokyo',
'2017-06-26T03:01:00.000+0900',
false,
],
];

test.each(cases)('%p, %p, %p', (sched, tz, datetime, expected) => {
test.each`
sched | tz | datetime | expected
${'after 4pm'} | ${'Asia/Singapore'} | ${'2017-06-30T15:59:00.000+0800'} | ${false}
${'after 4pm'} | ${'Asia/Singapore'} | ${'2017-06-30T16:01:00.000+0800'} | ${true}
${'before 3am on Monday'} | ${'Asia/Tokyo'} | ${'2017-06-26T02:59:00.000+0900'} | ${true}
${'before 3am on Monday'} | ${'Asia/Tokyo'} | ${'2017-06-26T03:01:00.000+0900'} | ${false}
`('$sched, $tz, $datetime', ({ sched, tz, datetime, expected }) => {
config.schedule = [sched];
config.timezone = tz;
mockDate.set(datetime);
Loading