From 73cb30d272d57d88fce7042d7b11379cffb60cc4 Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Fri, 1 Nov 2024 12:10:23 +0100 Subject: [PATCH 1/6] build!: Update to Node v22 (#32182) Updates Renovate's package.json>engines to add support for Node v22 LTS, and updates Renovate official Docker images to run on Node v22 instead of Node v20. Closes #32068 BREAKING CHANGE: Renovate Docker images will now be based on Node.js v22 instead of v20 --- .github/workflows/build.yml | 2 +- .github/workflows/update-data.yml | 2 +- .nvmrc | 2 +- package.json | 4 ++-- tools/docker/Dockerfile | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 57f2de4f596902..3c43b76838a55d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -30,7 +30,7 @@ concurrency: env: DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} - NODE_VERSION: 20 + NODE_VERSION: 22 PDM_VERSION: 2.20.0.post1 # renovate: datasource=pypi depName=pdm DRY_RUN: true TEST_LEGACY_DECRYPTION: true diff --git a/.github/workflows/update-data.yml b/.github/workflows/update-data.yml index d4de7915483334..93b68aafd8baaf 100644 --- a/.github/workflows/update-data.yml +++ b/.github/workflows/update-data.yml @@ -5,7 +5,7 @@ on: workflow_dispatch: env: - NODE_VERSION: 20 + NODE_VERSION: 22 permissions: contents: read diff --git a/.nvmrc b/.nvmrc index 2a393af592b8cd..7af24b7ddbde0c 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -20.18.0 +22.11.0 diff --git a/package.json b/package.json index 7dfcd6da83e255..c2ba4869a45cc5 100644 --- a/package.json +++ b/package.json @@ -135,11 +135,11 @@ }, "homepage": "https://renovatebot.com", "engines": { - "node": "^20.15.1", + "node": "^20.15.1 || ^22.11.0", "pnpm": "^9.0.0" }, "volta": { - "node": "20.18.0", + "node": "22.11.0", "pnpm": "9.12.3" }, "dependencies": { diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile index 87d980acba86e1..920a7569cec206 100644 --- a/tools/docker/Dockerfile +++ b/tools/docker/Dockerfile @@ -19,7 +19,7 @@ FROM --platform=$BUILDPLATFORM ghcr.io/renovatebot/base-image:7.41.2@sha256:b104 # We want a specific node version here # renovate: datasource=node-version -RUN install-tool node 20.18.0 +RUN install-tool node 22.11.0 WORKDIR /usr/local/renovate From 72fead3cb9bddc6bcc8710c0439255438ebf8138 Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Fri, 1 Nov 2024 12:18:02 +0100 Subject: [PATCH 2/6] feat(Dockerfile): set binarySource=global for full image (#32272) Sets RENOVATE_BINARY_SOURCE=global in Renovate official "-full" images. Closes #32136 BREAKING CHANGE: Renovate -full images will now use binarySource=global. Set RENOVATE_BINARY_SOURCE=install to revert to dynamic tool installation. --- tools/docker/Dockerfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile index 920a7569cec206..cba137b8698cf5 100644 --- a/tools/docker/Dockerfile +++ b/tools/docker/Dockerfile @@ -12,6 +12,8 @@ FROM ghcr.io/renovatebot/base-image:7.41.2@sha256:b104d2a8ae0072f205f29b972769e4 # -------------------------------------- FROM ghcr.io/renovatebot/base-image:7.41.2-full@sha256:3365becc7d7b50b210f793e58e4e871ead00976280f3451fd97230417c02f423 AS full-base +ENV RENOVATE_BINARY_SOURCE=global + # -------------------------------------- # build image # -------------------------------------- From a162bd344eb155fceeaa5c3ad20cf07cb85e56ce Mon Sep 17 00:00:00 2001 From: Philippe Ballandras Date: Fri, 1 Nov 2024 07:23:55 -0400 Subject: [PATCH 3/6] fix(github)!: change automerge priority order to prefer squash (#32016) Changes the priority order so that squash merges are preferred over rebase merge and merge commits. Doing so allows GitHub to sign the resulting commit on the base branch. BREAKING CHANGE: Renovate will now prefer squash merges over others in GitHub, if they are allowed. --- lib/modules/platform/github/index.spec.ts | 36 +++++++++++------------ lib/modules/platform/github/index.ts | 20 ++++++------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/lib/modules/platform/github/index.spec.ts b/lib/modules/platform/github/index.spec.ts index e7e4ea1b89f87a..374c60079c1fbe 100644 --- a/lib/modules/platform/github/index.spec.ts +++ b/lib/modules/platform/github/index.spec.ts @@ -532,7 +532,7 @@ describe('modules/platform/github/index', () => { } describe('initRepo', () => { - it('should rebase', async () => { + it('should squash', async () => { const scope = httpMock.scope(githubApiHost); initRepoMock(scope, 'some/repo'); const config = await github.initRepo({ repository: 'some/repo' }); @@ -675,7 +675,7 @@ describe('modules/platform/github/index', () => { expect(config).toMatchSnapshot(); }); - it('should squash', async () => { + it('should merge', async () => { httpMock .scope(githubApiHost) .post(`/graphql`) @@ -687,8 +687,8 @@ describe('modules/platform/github/index', () => { nameWithOwner: 'some/repo', hasIssuesEnabled: true, mergeCommitAllowed: true, - rebaseMergeAllowed: false, - squashMergeAllowed: true, + rebaseMergeAllowed: true, + squashMergeAllowed: false, defaultBranchRef: { name: 'master', target: { @@ -704,7 +704,7 @@ describe('modules/platform/github/index', () => { expect(config).toMatchSnapshot(); }); - it('should merge', async () => { + it('should rebase', async () => { httpMock .scope(githubApiHost) .post(`/graphql`) @@ -715,8 +715,8 @@ describe('modules/platform/github/index', () => { isArchived: false, nameWithOwner: 'some/repo', hasIssuesEnabled: true, - mergeCommitAllowed: true, - rebaseMergeAllowed: false, + mergeCommitAllowed: false, + rebaseMergeAllowed: true, squashMergeAllowed: false, defaultBranchRef: { name: 'master', @@ -2882,7 +2882,7 @@ describe('modules/platform/github/index', () => { }, variables: { pullRequestId: 'abcd', - mergeMethod: 'REBASE', + mergeMethod: 'SQUASH', }, }, }; @@ -3510,7 +3510,7 @@ describe('modules/platform/github/index', () => { }, variables: { pullRequestId: 'abcd', - mergeMethod: 'REBASE', + mergeMethod: 'SQUASH', }, }, }; @@ -3683,7 +3683,7 @@ describe('modules/platform/github/index', () => { }); describe('mergePr(prNo) - autodetection', () => { - it('should try rebase first', async () => { + it('should try squash first', async () => { const scope = httpMock.scope(githubApiHost); initRepoMock(scope, 'some/repo'); scope.put('/repos/some/repo/pulls/1235/merge').reply(200); @@ -3702,12 +3702,12 @@ describe('modules/platform/github/index', () => { ).toBeTrue(); }); - it('should try squash after rebase', async () => { + it('should try merge after squash', async () => { const scope = httpMock.scope(githubApiHost); initRepoMock(scope, 'some/repo'); scope .put('/repos/some/repo/pulls/1236/merge') - .reply(400, 'no rebasing allowed'); + .reply(400, 'no squashing allowed'); await github.initRepo({ repository: 'some/repo' }); const pr = { number: 1236, @@ -3723,15 +3723,15 @@ describe('modules/platform/github/index', () => { ).toBeFalse(); }); - it('should try merge after squash', async () => { + it('should try rebase after merge', async () => { const scope = httpMock.scope(githubApiHost); initRepoMock(scope, 'some/repo'); scope - .put('/repos/some/repo/pulls/1237/merge') - .reply(405, 'no rebasing allowed') .put('/repos/some/repo/pulls/1237/merge') .reply(405, 'no squashing allowed') .put('/repos/some/repo/pulls/1237/merge') + .reply(405, 'no merging allowed') + .put('/repos/some/repo/pulls/1237/merge') .reply(200); await github.initRepo({ repository: 'some/repo' }); const pr = { @@ -3753,12 +3753,12 @@ describe('modules/platform/github/index', () => { initRepoMock(scope, 'some/repo'); scope .put('/repos/some/repo/pulls/1237/merge') - .reply(405, 'no rebasing allowed') - .put('/repos/some/repo/pulls/1237/merge') - .replyWithError('no squashing allowed') + .reply(405, 'no squashing allowed') .put('/repos/some/repo/pulls/1237/merge') .replyWithError('no merging allowed') .put('/repos/some/repo/pulls/1237/merge') + .replyWithError('no rebasing allowed') + .put('/repos/some/repo/pulls/1237/merge') .replyWithError('never gonna give you up'); await github.initRepo({ repository: 'some/repo' }); const pr = { diff --git a/lib/modules/platform/github/index.ts b/lib/modules/platform/github/index.ts index 08678c06d37dac..082932f3475698 100644 --- a/lib/modules/platform/github/index.ts +++ b/lib/modules/platform/github/index.ts @@ -553,12 +553,12 @@ export async function initRepo({ // Base branch may be configured but defaultBranch is always fixed logger.debug(`${repository} default branch = ${config.defaultBranch}`); // GitHub allows administrators to block certain types of merge, so we need to check it - if (repo.rebaseMergeAllowed) { - config.mergeMethod = 'rebase'; - } else if (repo.squashMergeAllowed) { + if (repo.squashMergeAllowed) { config.mergeMethod = 'squash'; } else if (repo.mergeCommitAllowed) { config.mergeMethod = 'merge'; + } else if (repo.rebaseMergeAllowed) { + config.mergeMethod = 'rebase'; } else { // This happens if we don't have Administrator read access, it is not a critical error logger.debug('Could not find allowed merge methods for repo'); @@ -1910,25 +1910,25 @@ export async function mergePr({ } } if (!automerged) { - // We need to guess the merge method and try squash -> rebase -> merge - options.body.merge_method = 'rebase'; + // We need to guess the merge method and try squash -> merge -> rebase + options.body.merge_method = 'squash'; try { logger.debug({ options, url }, `mergePr`); automergeResult = await githubApi.putJson(url, options); } catch (err1) { - logger.debug({ err: err1 }, `Failed to rebase merge PR`); + logger.debug({ err: err1 }, `Failed to squash merge PR`); try { - options.body.merge_method = 'squash'; + options.body.merge_method = 'merge'; logger.debug({ options, url }, `mergePr`); automergeResult = await githubApi.putJson(url, options); } catch (err2) { - logger.debug({ err: err2 }, `Failed to merge squash PR`); + logger.debug({ err: err2 }, `Failed to merge commit PR`); try { - options.body.merge_method = 'merge'; + options.body.merge_method = 'rebase'; logger.debug({ options, url }, `mergePr`); automergeResult = await githubApi.putJson(url, options); } catch (err3) { - logger.debug({ err: err3 }, `Failed to merge commit PR`); + logger.debug({ err: err3 }, `Failed to rebase merge PR`); logger.info({ pr: prNo }, 'All merge attempts failed'); return false; } From e664a0b423f31ad058dc979b5029119fdf1b044f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 1 Nov 2024 12:24:35 +0100 Subject: [PATCH 4/6] feat(deps)!: update ghcr.io/renovatebot/base-image docker tag to v9 (#32240) Update Renovate base-image from v7 to v9. Includes the following potentially breaking changes for -full image: - Update Ubuntu base image to 24.04 - Update dependency python to v3.13.0 - Update dependency node to v22 Additionally, some changes to internal paths were made (only affects users who install things themselves or rely on static locations of binaries). BREAKING CHANGE: The Renovate full image now uses Ubuntu 24.04, Python 3.13 and Node v22 --- tools/docker/Dockerfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile index cba137b8698cf5..4ff58311623703 100644 --- a/tools/docker/Dockerfile +++ b/tools/docker/Dockerfile @@ -5,19 +5,19 @@ ARG BASE_IMAGE_TYPE=slim # -------------------------------------- # slim image # -------------------------------------- -FROM ghcr.io/renovatebot/base-image:7.41.2@sha256:b104d2a8ae0072f205f29b972769e4c1a00d9957073b628b57c734e4f7376027 AS slim-base +FROM ghcr.io/renovatebot/base-image:9.2.0@sha256:52c241a927ca9f2e339e8d74c860f410c2f182a19819fb2050f89c91a905d99f AS slim-base # -------------------------------------- # full image # -------------------------------------- -FROM ghcr.io/renovatebot/base-image:7.41.2-full@sha256:3365becc7d7b50b210f793e58e4e871ead00976280f3451fd97230417c02f423 AS full-base +FROM ghcr.io/renovatebot/base-image:9.2.0-full@sha256:898a5898727ef6ecbe3d57c6dcf9917b13af91abc11f70e6c9926c7ebf1b0311 AS full-base ENV RENOVATE_BINARY_SOURCE=global # -------------------------------------- # build image # -------------------------------------- -FROM --platform=$BUILDPLATFORM ghcr.io/renovatebot/base-image:7.41.2@sha256:b104d2a8ae0072f205f29b972769e4c1a00d9957073b628b57c734e4f7376027 AS build +FROM --platform=$BUILDPLATFORM ghcr.io/renovatebot/base-image:9.2.0@sha256:52c241a927ca9f2e339e8d74c860f410c2f182a19819fb2050f89c91a905d99f AS build # We want a specific node version here # renovate: datasource=node-version From 7f4bb35ab48843f7f6eb504048effc3bf6667da3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 1 Nov 2024 12:25:16 +0100 Subject: [PATCH 5/6] feat(deps)!: update ghcr.io/containerbase/sidecar docker tag to v13 (#32095) Updates default Renovate sidecar container to v13, which is based on Ubuntu 24.04. BREAKING CHANGE: Renovate sidecard images will default to use Ubuntu 24.04 instead of 20.04 --- lib/config/options/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/config/options/index.ts b/lib/config/options/index.ts index 955105f4dce7d7..fd1a19ffe71f40 100644 --- a/lib/config/options/index.ts +++ b/lib/config/options/index.ts @@ -515,7 +515,7 @@ const options: RenovateOptions[] = [ description: 'Change this value to override the default Renovate sidecar image.', type: 'string', - default: 'ghcr.io/containerbase/sidecar:11.11.41', + default: 'ghcr.io/containerbase/sidecar:13.0.4', globalOnly: true, }, { From 3ae9e2f6cd7a13220769a4d8daf59379a0791b2d Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Fri, 1 Nov 2024 16:01:41 +0100 Subject: [PATCH 6/6] feat(branchNameStrict)!: remove forward slashes from non-prefix part of branchName (#32278) Update logic for branchNameStrict=true so that it also removes forward slashes from branch names, with the exception of the `branchPrefix` part. In other words, if you leave the default `branchPrefix="renovate/"` then you'll get branch names like `renovate/foo-bar-42-x` instead of today's `renovate/foo/bar-42-x`. BREAKING CHANGE: Branch names with multiple forward slashes will change if branchNameStrict=true --- docs/usage/configuration-options.md | 7 ++++++- docs/usage/examples/self-hosting.md | 2 +- .../repository/updates/branch-name.spec.ts | 16 ++++++++++++++++ lib/workers/repository/updates/branch-name.ts | 13 +++++++++++-- tools/docker/Dockerfile | 2 +- 5 files changed, 35 insertions(+), 5 deletions(-) diff --git a/docs/usage/configuration-options.md b/docs/usage/configuration-options.md index 99bb5ca13822de..02f2d3394cd350 100644 --- a/docs/usage/configuration-options.md +++ b/docs/usage/configuration-options.md @@ -394,7 +394,12 @@ If `true`, Renovate removes special characters when slugifying the branch name: - only alphabetic characters are allowed - hyphens `-` are used to separate sections -The default `false` behavior will mean that special characters like `.` may end up in the branch name. +The default `false` behavior will mean that special characters like `.` and `/` may end up in the branch name. + + +!!! note + Renovate will not apply any search/replace to the `branchPrefix` part of the branch name. + If you don't want any `/` in your branch name then you will also need to change `branchPrefix` from the default `renovate/` value to something like `renovate-`. ## branchPrefix diff --git a/docs/usage/examples/self-hosting.md b/docs/usage/examples/self-hosting.md index 705ffd176820d3..edc1b91a386940 100644 --- a/docs/usage/examples/self-hosting.md +++ b/docs/usage/examples/self-hosting.md @@ -436,7 +436,7 @@ COPY self-signed-certificate.crt /usr/local/share/ca-certificates/ RUN update-ca-certificates # Change back to the Ubuntu user -USER 1000 +USER 12021 # OpenSSL ENV SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt diff --git a/lib/workers/repository/updates/branch-name.spec.ts b/lib/workers/repository/updates/branch-name.spec.ts index 297d7012bcd4af..a4b4dd5993954e 100644 --- a/lib/workers/repository/updates/branch-name.spec.ts +++ b/lib/workers/repository/updates/branch-name.spec.ts @@ -213,6 +213,22 @@ describe('workers/repository/updates/branch-name', () => { expect(upgrade.branchName).toBe('renovate/jest-42-x'); }); + it('removes slashes from the non-suffix part', () => { + const upgrade: RenovateConfig = { + branchNameStrict: true, + branchName: + '{{{branchPrefix}}}{{{additionalBranchPrefix}}}{{{branchTopic}}}', + branchTopic: + '{{{depNameSanitized}}}-{{{newMajor}}}{{#if isPatch}}.{{{newMinor}}}{{/if}}.x{{#if isLockfileUpdate}}-lockfile{{/if}}', + branchPrefix: 'renovate/', + depNameSanitized: '@foo/jest', + newMajor: '42', + group: {}, + }; + generateBranchName(upgrade); + expect(upgrade.branchName).toBe('renovate/foo-jest-42-x'); + }); + it('hashedBranchLength hashing', () => { const upgrade: RenovateConfig = { branchName: diff --git a/lib/workers/repository/updates/branch-name.ts b/lib/workers/repository/updates/branch-name.ts index bc42966fd0ded7..d151c0772b8c24 100644 --- a/lib/workers/repository/updates/branch-name.ts +++ b/lib/workers/repository/updates/branch-name.ts @@ -11,7 +11,7 @@ const MIN_HASH_LENGTH = 6; const RE_MULTIPLE_DASH = regEx(/--+/g); -const RE_SPECIAL_CHARS_STRICT = regEx(/[`~!@#$%^&*()_=+[\]\\|{};':",.<>?]/g); +const RE_SPECIAL_CHARS_STRICT = regEx(/[`~!@#$%^&*()_=+[\]\\|{};':",.<>?/]/g); /** * Clean git branch name @@ -26,12 +26,20 @@ const RE_SPECIAL_CHARS_STRICT = regEx(/[`~!@#$%^&*()_=+[\]\\|{};':",.<>?]/g); */ function cleanBranchName( branchName: string, + branchPrefix: string, branchNameStrict?: boolean, ): string { let cleanedBranchName = branchName; + let existingBranchPrefix = ''; if (branchNameStrict) { - cleanedBranchName = cleanedBranchName.replace(RE_SPECIAL_CHARS_STRICT, '-'); // massage out all special characters that slip through slugify + if (cleanedBranchName.startsWith(branchPrefix)) { + existingBranchPrefix = branchPrefix; + cleanedBranchName = cleanedBranchName.slice(branchPrefix.length); + } + cleanedBranchName = + existingBranchPrefix + + cleanedBranchName.replace(RE_SPECIAL_CHARS_STRICT, '-'); // massage out all special characters that slip through slugify } return cleanGitRef @@ -125,6 +133,7 @@ export function generateBranchName(update: RenovateConfig): void { } update.branchName = cleanBranchName( update.branchName, + update.branchPrefix!, update.branchNameStrict, ); } diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile index 4ff58311623703..bf755d60107105 100644 --- a/tools/docker/Dockerfile +++ b/tools/docker/Dockerfile @@ -104,4 +104,4 @@ LABEL \ org.label-schema.version="${RENOVATE_VERSION}" # Numeric user ID for the ubuntu user. Used to indicate a non-root user to OpenShift -USER 1000 +USER 12021