diff --git a/docs/usage/configuration-options.md b/docs/usage/configuration-options.md index 8edee0cf2c187c..74dbee9010019d 100644 --- a/docs/usage/configuration-options.md +++ b/docs/usage/configuration-options.md @@ -649,6 +649,14 @@ These datasources can be referred by RegexManagers or can be used to overwrite d For more details see the [`custom` datasource documentation](/modules/datasource/custom/). +## customizeDashboard + +You can use the `customizeDashboard` object to customize dependency dashboard. + +Supported fields: + +- `repoProblemsHeader`: This field will replace the header of the Repository Problems in dependency dashboard issue. + ### defaultRegistryUrlTemplate `registryUrl` which is used, if none is return by extraction. diff --git a/lib/config/options/index.ts b/lib/config/options/index.ts index 3ab6ac482974b4..21e855259cb1e4 100644 --- a/lib/config/options/index.ts +++ b/lib/config/options/index.ts @@ -1977,6 +1977,15 @@ const options: RenovateOptions[] = [ type: 'string', default: `This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).`, }, + { + name: 'customizeDashboard', + description: 'Customize sections in the dependency dashboard issue.', + type: 'object', + default: {}, + additionalProperties: { + type: 'string', + }, + }, { name: 'lockFileMaintenance', description: 'Configuration for lock file maintenance.', diff --git a/lib/config/types.ts b/lib/config/types.ts index 58a36ab50155ca..c66c8941e14322 100644 --- a/lib/config/types.ts +++ b/lib/config/types.ts @@ -273,6 +273,7 @@ export interface RenovateConfig constraintsFiltering?: ConstraintsFilter; checkedBranches?: string[]; + customizeDashboard?: Record; } export interface CustomDatasourceConfig { diff --git a/lib/config/validation.ts b/lib/config/validation.ts index b14ce73fa021f0..4684c6e8777b29 100644 --- a/lib/config/validation.ts +++ b/lib/config/validation.ts @@ -616,6 +616,7 @@ export async function validateConfig( 'migratePresets', 'productLinks', 'secrets', + 'customizeDashboard', ].includes(key) ) { const res = validatePlainObject(val); diff --git a/lib/workers/repository/__snapshots__/dependency-dashboard.spec.ts.snap b/lib/workers/repository/__snapshots__/dependency-dashboard.spec.ts.snap index 9bd3295445f553..ef4acccd71b0a6 100644 --- a/lib/workers/repository/__snapshots__/dependency-dashboard.spec.ts.snap +++ b/lib/workers/repository/__snapshots__/dependency-dashboard.spec.ts.snap @@ -472,6 +472,28 @@ None detected " `; +exports[`workers/repository/dependency-dashboard ensureDependencyDashboard() contains logged problems with custom header 1`] = ` +"This issue lists Renovate updates and detected dependencies. Read the [Dependency Dashboard](https://docs.renovatebot.com/key-concepts/dashboard/) docs to learn more. + +## Repository problems + +platform is github + + - ERROR: i am a non-duplicated problem + +## Pending Status Checks + +These updates await pending status checks. To force their creation now, click the checkbox below. + + - [ ] pr1 + +## Detected dependencies + +None detected + +" +`; + exports[`workers/repository/dependency-dashboard ensureDependencyDashboard() open or update Dependency Dashboard when all branches are closed and dependencyDashboardAutoclose is false 1`] = ` "This is a header diff --git a/lib/workers/repository/dependency-dashboard.spec.ts b/lib/workers/repository/dependency-dashboard.spec.ts index 659ee4daafeca0..0f22e3e558ea86 100644 --- a/lib/workers/repository/dependency-dashboard.spec.ts +++ b/lib/workers/repository/dependency-dashboard.spec.ts @@ -641,6 +641,38 @@ describe('workers/repository/dependency-dashboard', () => { expect(platform.ensureIssue.mock.calls[0][0].body).toMatchSnapshot(); }); + it('contains logged problems with custom header', async () => { + const branches: BranchConfig[] = [ + { + ...mock(), + prTitle: 'pr1', + upgrades: [ + { ...mock(), depName: 'dep1', repository: 'repo1' }, + ], + result: 'pending', + branchName: 'branchName1', + }, + ]; + logger.getProblems.mockReturnValueOnce([ + { + level: ERROR, + msg: 'i am a non-duplicated problem', + }, + ]); + config.dependencyDashboard = true; + config.customizeDashboard = { + repoProblemsHeader: 'platform is {{platform}}', + }; + + await dependencyDashboard.ensureDependencyDashboard(config, branches); + + expect(platform.ensureIssue).toHaveBeenCalledTimes(1); + expect(platform.ensureIssue.mock.calls[0][0].body).toContain( + 'platform is github' + ); + expect(platform.ensureIssue.mock.calls[0][0].body).toMatchSnapshot(); + }); + it('dependency Dashboard All Pending Approval', async () => { const branches: BranchConfig[] = [ { diff --git a/lib/workers/repository/dependency-dashboard.ts b/lib/workers/repository/dependency-dashboard.ts index 5d80ba35ca1cf5..25dc19c08f0385 100644 --- a/lib/workers/repository/dependency-dashboard.ts +++ b/lib/workers/repository/dependency-dashboard.ts @@ -174,8 +174,11 @@ function appendRepoProblems(config: RenovateConfig, issueBody: string): string { 'repository problems' ); newIssueBody += '## Repository problems\n\n'; - newIssueBody += - 'These problems occurred while renovating this repository.\n\n'; + const repoProblemsHeader = + config.customizeDashboard?.['repoProblemsHeader'] ?? + 'These problems occurred while renovating this repository.'; + newIssueBody += template.compile(repoProblemsHeader, config) + '\n\n'; + for (const repoProblem of repoProblems) { newIssueBody += ` - ${repoProblem}\n`; }