diff --git a/lib/workers/repository/onboarding/pr/index.spec.ts b/lib/workers/repository/onboarding/pr/index.spec.ts index 8132506488..5bf525ec72 100644 --- a/lib/workers/repository/onboarding/pr/index.spec.ts +++ b/lib/workers/repository/onboarding/pr/index.spec.ts @@ -155,6 +155,10 @@ describe('workers/repository/onboarding/pr/index', () => { // the summary groups them under a manager heading instead expect(prBody).not.toContain('`package.json` (npm)'); expect(prBody).toContain('#### npm\n\n * `package.json`'); + // in the summary view, "What to Expect" should render before "Detected Package Files" + expect(prBody.indexOf('### What to Expect')).toBeLessThan( + prBody.indexOf('### Detected Package Files'), + ); }); it('does not attempt to replace package files when none were detected', async () => { diff --git a/lib/workers/repository/onboarding/pr/index.ts b/lib/workers/repository/onboarding/pr/index.ts index d38da1ebe4..e8c269f671 100644 --- a/lib/workers/repository/onboarding/pr/index.ts +++ b/lib/workers/repository/onboarding/pr/index.ts @@ -86,10 +86,35 @@ async function ensureOnboardingAutoCloseAge(existingPr: Pr): Promise { return false; } +/** + * Full onboarding PRs list package files before the PR list. + */ +const FULL_SECTION_ORDER = [ + 'PACKAGE FILES', + 'CONFIG', + 'BASEBRANCH', + 'PRLIST', + 'WARNINGS', + 'ERRORS', +] as const; + +/** + * "Summarised" onboarding PRs list PRs before other sections. + */ +const SUMMARY_SECTION_ORDER = [ + 'PRLIST', + 'CONFIG', + 'BASEBRANCH', + 'PACKAGE FILES', + 'WARNINGS', + 'ERRORS', +] as const; + function buildOnboardingPrTemplate( config: RenovateConfig, configFile: string, rebaseCheckBox: string, + sectionOrder: readonly string[], ): string { let prTemplate = `Welcome to [Renovate](${ GlobalConfig.get('productLinks').homepage @@ -121,12 +146,7 @@ function buildOnboardingPrTemplate( ` --- -{{PACKAGE FILES}} -{{CONFIG}} -{{BASEBRANCH}} -{{PRLIST}} -{{WARNINGS}} -{{ERRORS}} +${sectionOrder.map((section) => `{{${section}}}`).join('\n')} --- @@ -249,7 +269,12 @@ export async function ensureOnboardingPr( let prBody = finalizeOnboardingPrBody( fillOnboardingPrBody( - buildOnboardingPrTemplate(config, configFile, rebaseCheckBox), + buildOnboardingPrTemplate( + config, + configFile, + rebaseCheckBox, + FULL_SECTION_ORDER, + ), { packageFiles: packageFilesDesc, config: configDesc, @@ -267,12 +292,33 @@ export async function ensureOnboardingPr( logger.debug( 'Onboarding PR body exceeds platform limit, switching to summary PR list and package files', ); - prBody = prBody.replace(prList, getExpectedPrListSummary(config, branches)); + const prListSummary = getExpectedPrListSummary(config, branches); if (packageFilesDesc) { - prBody = prBody.replace( - packageFilesDesc, - `### Detected Package Files\n\n${getPackageFilesSummary(packageFiles)}`, + const packageFilesSummary = `### Detected Package Files\n\n${getPackageFilesSummary(packageFiles)}`; + // "What to Expect" should render before "Detected Package Files" in the summary view, + // so rebuild from a template with that section order rather than reordering the rendered body. + prBody = finalizeOnboardingPrBody( + fillOnboardingPrBody( + buildOnboardingPrTemplate( + config, + configFile, + rebaseCheckBox, + SUMMARY_SECTION_ORDER, + ), + { + packageFiles: packageFilesSummary, + config: configDesc, + baseBranch: baseBranchDesc, + prList: prListSummary, + warnings, + errors, + }, + ), + config, + onboardingConfigHashComment, ); + } else { + prBody = prBody.replace(prList, prListSummary); } } diff --git a/lib/workers/repository/reconfigure/comment.spec.ts b/lib/workers/repository/reconfigure/comment.spec.ts index 12a62bf3c1..f0fca05275 100644 --- a/lib/workers/repository/reconfigure/comment.spec.ts +++ b/lib/workers/repository/reconfigure/comment.spec.ts @@ -114,6 +114,10 @@ describe('workers/repository/reconfigure/comment', () => { // the summary groups them under a manager heading instead expect(prBody).not.toContain('`package.json` (npm)'); expect(prBody).toContain('#### npm\n\n * `package.json`'); + // in the summary view, "What to Expect" should render before "Detected Package Files" + expect(prBody.indexOf('### What to Expect')).toBeLessThan( + prBody.indexOf('### Detected Package Files'), + ); }); it('does not attempt to replace package files when none were detected', async () => { diff --git a/lib/workers/repository/reconfigure/comment.ts b/lib/workers/repository/reconfigure/comment.ts index 6bb6f3ab47..faefb653bc 100644 --- a/lib/workers/repository/reconfigure/comment.ts +++ b/lib/workers/repository/reconfigure/comment.ts @@ -24,16 +24,37 @@ import { } from '../onboarding/pr/pr-list.ts'; import type { ReconfigurePrCommentSections } from '../onboarding/pr/types.ts'; -// TODO #22198 -const RECONFIGURE_PR_COMMENT_TEMPLATE = `This is a reconfigure PR comment to help you understand and re-configure your renovate bot settings. If this Reconfigure PR were to be merged, we'd expect to see the following outcome:\n\n +// Full reconfigure PR comments list package files before the PR list. +const SECTION_ORDER = [ + 'PACKAGE FILES', + 'CONFIG', + 'BASEBRANCH', + 'PRLIST', + 'WARNINGS', + 'ERRORS', +] as const; +// Once the body is summarised, "What to Expect" should render before "Detected Package Files". +const SUMMARY_SECTION_ORDER = [ + 'PRLIST', + 'CONFIG', + 'BASEBRANCH', + 'PACKAGE FILES', + 'WARNINGS', + 'ERRORS', +] as const; + +function buildReconfigurePrCommentTemplate( + sectionOrder: readonly string[], +): string { + let prCommentTemplate = `This is a reconfigure PR comment to help you understand and re-configure your renovate bot settings. If this Reconfigure PR were to be merged, we'd expect to see the following outcome:\n\n`; + + // TODO #22198 + prCommentTemplate += ` --- -{{PACKAGE FILES}} -{{CONFIG}} -{{BASEBRANCH}} -{{PRLIST}} -{{WARNINGS}} -{{ERRORS}} +${sectionOrder.map((section) => `{{${section}}}`).join('\n')} `; + return prCommentTemplate; +} function fillReconfigurePrCommentBody( prCommentTemplate: string, @@ -76,25 +97,40 @@ export async function ensureReconfigurePrComment( const baseBranchDesc = getBaseBranchDesc(config); const prList = getExpectedPrList(config, branches); - let prBody = fillReconfigurePrCommentBody(RECONFIGURE_PR_COMMENT_TEMPLATE, { - packageFiles: packageFilesDesc, - config: configDesc, - baseBranch: baseBranchDesc, - prList, - warnings, - errors, - }); + let prBody = fillReconfigurePrCommentBody( + buildReconfigurePrCommentTemplate(SECTION_ORDER), + { + packageFiles: packageFilesDesc, + config: configDesc, + baseBranch: baseBranchDesc, + prList, + warnings, + errors, + }, + ); if (prBody.length > platform.maxBodyLength()) { logger.debug( 'Reconfigure PR body exceeds platform limit, switching to summary PR list and package files', ); - prBody = prBody.replace(prList, getExpectedPrListSummary(config, branches)); + const prListSummary = getExpectedPrListSummary(config, branches); if (packageFilesDesc) { - prBody = prBody.replace( - packageFilesDesc, - `### Detected Package Files\n\n${getPackageFilesSummary(packageFiles)}`, + const packageFilesSummary = `### Detected Package Files\n\n${getPackageFilesSummary(packageFiles)}`; + // "What to Expect" should render before "Detected Package Files" in the summary view, + // so rebuild from a template with that section order rather than reordering the rendered body. + prBody = fillReconfigurePrCommentBody( + buildReconfigurePrCommentTemplate(SUMMARY_SECTION_ORDER), + { + packageFiles: packageFilesSummary, + config: configDesc, + baseBranch: baseBranchDesc, + prList: prListSummary, + warnings, + errors, + }, ); + } else { + prBody = prBody.replace(prList, prListSummary); } }