diff --git a/docs/usage/self-hosted-configuration.md b/docs/usage/self-hosted-configuration.md index e0fb0cc5ed8fec8867e2f2a95f789d19cf663462..fcf72c943a86abad86c1e9fae88b0cb0a0b760d0 100644 --- a/docs/usage/self-hosted-configuration.md +++ b/docs/usage/self-hosted-configuration.md @@ -219,6 +219,15 @@ Results which are soft expired are reused in the following manner: - The `etag` from the cached results will be reused, and may result in a 304 response, meaning cached results are revalidated - If an error occurs when querying the `npmjs` registry, then soft expired results will be reused if they are present +## checkedBranches + +This array will allow you to set the names of the branches you want to rebase/create, as if you selected their checkboxes in the Dependency Dashboard issue. + +It has been designed with the intention of being run on one repository, in a one-off manner, e.g. to "force" the rebase of a known existing branch. +It is highly unlikely that you should ever need to add this to your permanent global config. + +Example: `renovate --checked-branches=renovate/chalk-4.x renovate-reproductions/checked` will rebase the `renovate/chalk-4.x` branch in the `renovate-reproductions/checked` repository.` + ## containerbaseDir This directory is used to cache downloads when `binarySource=docker` or `binarySource=install`. diff --git a/lib/config/options/index.ts b/lib/config/options/index.ts index 60153f1ef700ddd49bbcb9db64094deec46f075b..a020d9dae7215766d274d160fd9f309429469c47 100644 --- a/lib/config/options/index.ts +++ b/lib/config/options/index.ts @@ -2624,6 +2624,16 @@ const options: RenovateOptions[] = [ type: 'boolean', default: false, }, + { + name: 'checkedBranches', + description: + 'A list of branch names to mark for creation or rebasing as if it was selected in the Dependency Dashboard issue.', + type: 'array', + subType: 'string', + experimental: true, + globalOnly: true, + default: [], + }, ]; export function getOptions(): RenovateOptions[] { diff --git a/lib/config/types.ts b/lib/config/types.ts index aedf88d6237cdcb25655e48381907385c2008f55..0df00b27a9a6885dd7e5b91c4f8f3917c95fda72 100644 --- a/lib/config/types.ts +++ b/lib/config/types.ts @@ -260,6 +260,8 @@ export interface RenovateConfig skipInstalls?: boolean | null; constraintsFiltering?: ConstraintsFilter; + + checkedBranches?: string[]; } export interface AllConfig diff --git a/lib/workers/repository/dependency-dashboard.spec.ts b/lib/workers/repository/dependency-dashboard.spec.ts index 6170c3dcdc4e68a939bf95aa254d3de6abbeada9..a2d9b97782cf83405044e2b4a54c25f4cbbccda8 100644 --- a/lib/workers/repository/dependency-dashboard.spec.ts +++ b/lib/workers/repository/dependency-dashboard.spec.ts @@ -104,6 +104,31 @@ describe('workers/repository/dependency-dashboard', () => { }); }); + it('reads dashboard body and apply checkedBranches', async () => { + const conf: RenovateConfig = {}; + conf.prCreation = 'approval'; + conf.checkedBranches = ['branch1', 'branch2']; + platform.findIssue.mockResolvedValueOnce({ + title: '', + number: 1, + body: Fixtures.get('dependency-dashboard-with-8-PR.txt'), + }); + await dependencyDashboard.readDashboardBody(conf); + expect(conf).toEqual({ + checkedBranches: ['branch1', 'branch2'], + dependencyDashboardAllPending: false, + dependencyDashboardAllRateLimited: false, + dependencyDashboardChecks: { + branch1: 'global-config', + branch2: 'global-config', + }, + dependencyDashboardIssue: 1, + dependencyDashboardRebaseAllOpen: false, + dependencyDashboardTitle: 'Dependency Dashboard', + prCreation: 'approval', + }); + }); + it('reads dashboard body all pending approval', async () => { const conf: RenovateConfig = {}; conf.prCreation = 'approval'; diff --git a/lib/workers/repository/dependency-dashboard.ts b/lib/workers/repository/dependency-dashboard.ts index ac00cdd0fe527e1b41c4d5b4957dd0700b37c60d..6054f0e58e9573c7823038bac70c7b2a36cde09b 100644 --- a/lib/workers/repository/dependency-dashboard.ts +++ b/lib/workers/repository/dependency-dashboard.ts @@ -113,7 +113,22 @@ export async function readDashboardBody( const issue = await platform.findIssue(config.dependencyDashboardTitle); if (issue) { config.dependencyDashboardIssue = issue.number; - Object.assign(config, parseDashboardIssue(issue.body!)); + const dashboardChecks = parseDashboardIssue(issue.body!); + + if (config.checkedBranches) { + const checkedBranchesRec: Record<string, string> = Object.fromEntries( + config.checkedBranches.map((branchName) => [ + branchName, + 'global-config', + ]) + ); + dashboardChecks.dependencyDashboardChecks = { + ...dashboardChecks.dependencyDashboardChecks, + ...checkedBranchesRec, + }; + } + + Object.assign(config, dashboardChecks); } } } diff --git a/lib/workers/repository/update/branch/index.spec.ts b/lib/workers/repository/update/branch/index.spec.ts index 7609eab2d2b86b43ffdff53bcc2f4b6b63fffe4c..636803ec391f9ddfde124f9bf168cae83d460478 100644 --- a/lib/workers/repository/update/branch/index.spec.ts +++ b/lib/workers/repository/update/branch/index.spec.ts @@ -2015,6 +2015,27 @@ describe('workers/repository/update/branch/index', () => { expect(commit.commitFilesToBranch).toHaveBeenCalled(); }); + it('continues when checked by checkedBranches', async () => { + getUpdated.getUpdatedPackageFiles.mockResolvedValueOnce( + updatedPackageFiles + ); + npmPostExtract.getAdditionalFiles.mockResolvedValueOnce({ + artifactErrors: [], + updatedArtifacts: [], + }); + scm.branchExists.mockResolvedValue(true); + commit.commitFilesToBranch.mockResolvedValueOnce(null); + expect( + await branchWorker.processBranch({ + ...config, + dependencyDashboardChecks: { + 'renovate/some-branch': 'global-config', + }, + }) + ).toMatchObject({ result: 'done' }); + expect(commit.commitFilesToBranch).toHaveBeenCalled(); + }); + it('does nothing when branchPrefixOld/branch and its pr exists', async () => { getUpdated.getUpdatedPackageFiles.mockResolvedValueOnce({ ...updatedPackageFiles, diff --git a/lib/workers/repository/update/branch/index.ts b/lib/workers/repository/update/branch/index.ts index 81c8c7b758752a9d7bd7347e476b3a641c74bbc9..ba93eee78e8414ec19b3c60b00bde6b0d2def482 100644 --- a/lib/workers/repository/update/branch/index.ts +++ b/lib/workers/repository/update/branch/index.ts @@ -367,6 +367,9 @@ export async function processBranch( if (userRebaseRequested) { logger.debug('Manual rebase requested via Dependency Dashboard'); config.reuseExistingBranch = false; + } else if (dependencyDashboardCheck === 'global-config') { + logger.debug(`Manual create/rebase requested via checkedBranches`); + config.reuseExistingBranch = false; } else if (userApproveAllPendingPR) { logger.debug( 'A user manually approved all pending PRs via the Dependency Dashboard.'