From 1d893a1b05bd24262717254312acb0eadea753ad Mon Sep 17 00:00:00 2001 From: RahulGautamSingh Date: Tue, 8 Nov 2022 15:42:01 +0530 Subject: [PATCH 01/48] first implementation --- lib/util/cache/repository/types.ts | 11 +++++++- lib/workers/repository/cache.ts | 4 +++ lib/workers/repository/update/pr/index.ts | 34 +++++++++++++++++++++-- 3 files changed, 46 insertions(+), 3 deletions(-) diff --git a/lib/util/cache/repository/types.ts b/lib/util/cache/repository/types.ts index 7bd11bda8371e1..42bc76f17304e4 100644 --- a/lib/util/cache/repository/types.ts +++ b/lib/util/cache/repository/types.ts @@ -26,6 +26,11 @@ export interface BranchUpgradeCache { sourceUrl?: string; } +interface PrCache { + fingerprint: string; + lastEdited: Date; +} + export interface BranchCache { /** *Whether this branch has automerge enabled @@ -40,7 +45,7 @@ export interface BranchCache { */ baseBranchSha: string | null; /** - * Hash of the manager fingerprints and the update branch config + * Hash of the manager fingerprints and the update branch config(filtered) */ branchFingerprint?: string; /** @@ -75,6 +80,10 @@ export interface BranchCache { * Details on the dependency upgrades that have been applied in this branch */ upgrades: BranchUpgradeCache[]; + /** + * Object that has PR info + */ + prCache?: PrCache; } export interface RepoCacheData { diff --git a/lib/workers/repository/cache.ts b/lib/workers/repository/cache.ts index 6de35aa19d4f80..c45391020ba9cc 100644 --- a/lib/workers/repository/cache.ts +++ b/lib/workers/repository/cache.ts @@ -73,6 +73,9 @@ async function generateBranchCache( ? branch.upgrades.map(generateBranchUpgradeCache) : []; const branchFingerprint = branch.branchFingerprint; + const prCache = getCache().branches?.find( + (branch) => branch.branchName === branchName + )?.prCache; return { automerge, baseBranchSha, @@ -86,6 +89,7 @@ async function generateBranchCache( prNo, sha, upgrades, + prCache, }; } catch (error) { const err = error.err || error; // external host error nests err diff --git a/lib/workers/repository/update/pr/index.ts b/lib/workers/repository/update/pr/index.ts index e2917a731bc72c..3e453cd343b713 100644 --- a/lib/workers/repository/update/pr/index.ts +++ b/lib/workers/repository/update/pr/index.ts @@ -18,7 +18,9 @@ import { ensureComment } from '../../../../modules/platform/comment'; import { hashBody } from '../../../../modules/platform/pr-body'; import { BranchStatus } from '../../../../types'; import { ExternalHostError } from '../../../../types/errors/external-host-error'; +import { getCache } from '../../../../util/cache/repository'; import { stripEmojis } from '../../../../util/emoji'; +import { fingerprint } from '../../../../util/fingerprint'; import { deleteBranch, getBranchLastCommitTime } from '../../../../util/git'; import { memoize } from '../../../../util/memoize'; import { Limit, incLimitedValue, isLimitReached } from '../../../global/limits'; @@ -28,7 +30,6 @@ import type { PrBlockedBy, } from '../../../types'; import { embedChangelogs } from '../../changelog'; -// import { embedChangelogs } from '../../changelog'; import { resolveBranchStatus } from '../branch/status-checks'; import { getPrBody } from './body'; import { ChangeLogError } from './changelog/types'; @@ -85,7 +86,12 @@ export async function ensurePr( ); const config: BranchConfig = { ...prConfig }; - + const prFingerprint = fingerprint(config); + const cache = getCache(); + const branch = cache.branches?.find( + (branch) => branch.branchName === config.branchName + ); + let prCache = branch?.prCache; logger.trace({ config }, 'ensurePr'); // If there is a group, it will use the config of the first upgrade in the array const { branchName, ignoreTests, prTitle = '', upgrades } = config; @@ -95,6 +101,19 @@ export async function ensurePr( const existingPr = await platform.getBranchPr(branchName); if (existingPr) { logger.debug('Found existing PR'); + if (prCache) { + const lastEditTime = prCache?.lastEdited; + const currentTime = new Date(); + const millisecondsPerHour = 1000 * 60 * 60; + const elapsedHours = Math.round( + (currentTime.getTime() - lastEditTime.getTime()) / millisecondsPerHour + ); + // check pr config fingerprint: no need to check for upgrades as it is already inside config + if (prFingerprint === branch?.prCache?.fingerprint && elapsedHours > 24) { + logger.debug(`${existingPr.displayNumber!} does not need updating`); + return { type: 'with-pr', pr: existingPr }; + } + } } config.upgrades = []; @@ -325,6 +344,11 @@ export async function ensurePr( }, 'PR body changed' ); + // update prCache last edit time + prCache = { + fingerprint: prFingerprint, + lastEdited: new Date(), + }; } if (GlobalConfig.get('dryRun')) { logger.info(`DRY-RUN: Would update PR #${existingPr.number}`); @@ -367,6 +391,12 @@ export async function ensurePr( draftPR: config.draftPR, }); + // add pr object to branch cache + prCache = { + fingerprint: prFingerprint, + lastEdited: new Date(), + }; + incLimitedValue(Limit.PullRequests); logger.info({ pr: pr?.number, prTitle }, 'PR created'); } catch (err) { From cd181c40e5a4382c832701c36b8c8656f3d6fdf1 Mon Sep 17 00:00:00 2001 From: RahulGautamSingh Date: Tue, 8 Nov 2022 17:11:51 +0530 Subject: [PATCH 02/48] refactor code --- lib/util/cache/repository/types.ts | 4 +- lib/workers/repository/cache.ts | 5 +- lib/workers/repository/update/pr/index.ts | 46 +++++++++++-------- .../repository/update/pr/set-pr-cache.ts | 35 ++++++++++++++ 4 files changed, 66 insertions(+), 24 deletions(-) create mode 100644 lib/workers/repository/update/pr/set-pr-cache.ts diff --git a/lib/util/cache/repository/types.ts b/lib/util/cache/repository/types.ts index 42bc76f17304e4..6c66e29d86208d 100644 --- a/lib/util/cache/repository/types.ts +++ b/lib/util/cache/repository/types.ts @@ -26,7 +26,7 @@ export interface BranchUpgradeCache { sourceUrl?: string; } -interface PrCache { +export interface PrCache { fingerprint: string; lastEdited: Date; } @@ -83,7 +83,7 @@ export interface BranchCache { /** * Object that has PR info */ - prCache?: PrCache; + prCache?: PrCache | null; } export interface RepoCacheData { diff --git a/lib/workers/repository/cache.ts b/lib/workers/repository/cache.ts index c45391020ba9cc..a2344ca5e51651 100644 --- a/lib/workers/repository/cache.ts +++ b/lib/workers/repository/cache.ts @@ -15,6 +15,7 @@ import { } from '../../util/git'; import { getCachedBranchParentShaResult } from '../../util/git/parent-sha-cache'; import type { BranchConfig, BranchUpgradeConfig } from '../types'; +import { getPrCache } from './update/pr/set-pr-cache'; function generateBranchUpgradeCache( upgrade: BranchUpgradeConfig @@ -73,9 +74,7 @@ async function generateBranchCache( ? branch.upgrades.map(generateBranchUpgradeCache) : []; const branchFingerprint = branch.branchFingerprint; - const prCache = getCache().branches?.find( - (branch) => branch.branchName === branchName - )?.prCache; + const prCache = getPrCache(branchName); return { automerge, baseBranchSha, diff --git a/lib/workers/repository/update/pr/index.ts b/lib/workers/repository/update/pr/index.ts index 3e453cd343b713..856afa320b0311 100644 --- a/lib/workers/repository/update/pr/index.ts +++ b/lib/workers/repository/update/pr/index.ts @@ -18,10 +18,13 @@ import { ensureComment } from '../../../../modules/platform/comment'; import { hashBody } from '../../../../modules/platform/pr-body'; import { BranchStatus } from '../../../../types'; import { ExternalHostError } from '../../../../types/errors/external-host-error'; -import { getCache } from '../../../../util/cache/repository'; import { stripEmojis } from '../../../../util/emoji'; import { fingerprint } from '../../../../util/fingerprint'; -import { deleteBranch, getBranchLastCommitTime } from '../../../../util/git'; +import { + deleteBranch, + getBranchLastCommitTime, + isCloned, +} from '../../../../util/git'; import { memoize } from '../../../../util/memoize'; import { Limit, incLimitedValue, isLimitReached } from '../../../global/limits'; import type { @@ -35,6 +38,7 @@ import { getPrBody } from './body'; import { ChangeLogError } from './changelog/types'; import { prepareLabels } from './labels'; import { addParticipants } from './participants'; +import { getPrCache, setPrCache } from './set-pr-cache'; export function getPlatformPrOptions( config: RenovateConfig & PlatformPrOptions @@ -87,11 +91,6 @@ export async function ensurePr( const config: BranchConfig = { ...prConfig }; const prFingerprint = fingerprint(config); - const cache = getCache(); - const branch = cache.branches?.find( - (branch) => branch.branchName === config.branchName - ); - let prCache = branch?.prCache; logger.trace({ config }, 'ensurePr'); // If there is a group, it will use the config of the first upgrade in the array const { branchName, ignoreTests, prTitle = '', upgrades } = config; @@ -101,18 +100,29 @@ export async function ensurePr( const existingPr = await platform.getBranchPr(branchName); if (existingPr) { logger.debug('Found existing PR'); + const prCache = getPrCache(branchName); if (prCache) { + logger.debug({ prCache }, 'Pr-Cache exists'); const lastEditTime = prCache?.lastEdited; const currentTime = new Date(); - const millisecondsPerHour = 1000 * 60 * 60; + // const millisecondsPerHour = 1000 * 60 * 60; const elapsedHours = Math.round( - (currentTime.getTime() - lastEditTime.getTime()) / millisecondsPerHour + currentTime.getTime() - new Date(lastEditTime).getTime() ); // check pr config fingerprint: no need to check for upgrades as it is already inside config - if (prFingerprint === branch?.prCache?.fingerprint && elapsedHours > 24) { - logger.debug(`${existingPr.displayNumber!} does not need updating`); + if ( + isCloned() === false && + prFingerprint === prCache.fingerprint && + elapsedHours > 24 + ) { + logger.debug( + `${existingPr.displayNumber!} does not need updating --- cache used HURRAY !!!` + ); return { type: 'with-pr', pr: existingPr }; } + } else { + logger.debug('Pr-Cache not found'); + setPrCache(branchName, prFingerprint); } } config.upgrades = []; @@ -216,8 +226,12 @@ export async function ensurePr( } if (config.fetchReleaseNotes) { + // eslint-disable-next-line no-console + console.time('changelog'); // fetch changelogs when not already done; await embedChangelogs(upgrades); + // eslint-disable-next-line no-console + console.timeEnd('changelog'); } // Get changelog and then generate template strings @@ -345,10 +359,7 @@ export async function ensurePr( 'PR body changed' ); // update prCache last edit time - prCache = { - fingerprint: prFingerprint, - lastEdited: new Date(), - }; + setPrCache(branchName, prFingerprint); } if (GlobalConfig.get('dryRun')) { logger.info(`DRY-RUN: Would update PR #${existingPr.number}`); @@ -392,10 +403,7 @@ export async function ensurePr( }); // add pr object to branch cache - prCache = { - fingerprint: prFingerprint, - lastEdited: new Date(), - }; + setPrCache(branchName, prFingerprint); incLimitedValue(Limit.PullRequests); logger.info({ pr: pr?.number, prTitle }, 'PR created'); diff --git a/lib/workers/repository/update/pr/set-pr-cache.ts b/lib/workers/repository/update/pr/set-pr-cache.ts new file mode 100644 index 00000000000000..c8e1156b12dab9 --- /dev/null +++ b/lib/workers/repository/update/pr/set-pr-cache.ts @@ -0,0 +1,35 @@ +import { logger } from '../../../../logger'; +import { getCache } from '../../../../util/cache/repository'; +import type { PrCache } from '../../../../util/cache/repository/types'; + +export function getPrCache(branchName: string): PrCache | null { + logger.debug(`getPrCache()`); + const cache = getCache(); + const branch = cache.branches?.find( + (branch) => branchName === branch.branchName + ); + + if (branch?.prCache) { + return branch.prCache; + } + + return null; +} + +export function setPrCache(branchName: string, fingerprint: string): void { + logger.debug(`setPrCache()`); + const cache = getCache(); + const branch = cache.branches?.find( + (branch) => branchName === branch.branchName + ); + + if (!branch) { + logger.debug(`setPrCache(): Branch cache not present`); + return; + } + + branch.prCache = { + fingerprint, + lastEdited: new Date(), + }; +} From 80b8806e6d4fead9b6a9c740f2e4f40e5dd1a344 Mon Sep 17 00:00:00 2001 From: RahulGautamSingh Date: Wed, 9 Nov 2022 15:24:57 +0530 Subject: [PATCH 03/48] refactor: add fn to compute get elapsed hours --- lib/workers/repository/update/pr/index.ts | 33 +++++++++-------------- 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/lib/workers/repository/update/pr/index.ts b/lib/workers/repository/update/pr/index.ts index 856afa320b0311..94d13ee5ce7449 100644 --- a/lib/workers/repository/update/pr/index.ts +++ b/lib/workers/repository/update/pr/index.ts @@ -40,6 +40,15 @@ import { prepareLabels } from './labels'; import { addParticipants } from './participants'; import { getPrCache, setPrCache } from './set-pr-cache'; +function getElapsedHours(time: Date | string): number { + const pastTime = typeof time === 'string' ? new Date(time) : time; + const currentTime = new Date(); + const millisecondsPerHour = 1000 * 60 * 60; + return ( + Math.round(currentTime.getTime() - pastTime.getTime()) / millisecondsPerHour + ); +} + export function getPlatformPrOptions( config: RenovateConfig & PlatformPrOptions ): PlatformPrOptions { @@ -104,16 +113,11 @@ export async function ensurePr( if (prCache) { logger.debug({ prCache }, 'Pr-Cache exists'); const lastEditTime = prCache?.lastEdited; - const currentTime = new Date(); - // const millisecondsPerHour = 1000 * 60 * 60; - const elapsedHours = Math.round( - currentTime.getTime() - new Date(lastEditTime).getTime() - ); // check pr config fingerprint: no need to check for upgrades as it is already inside config if ( isCloned() === false && prFingerprint === prCache.fingerprint && - elapsedHours > 24 + getElapsedHours(lastEditTime) > 24 ) { logger.debug( `${existingPr.displayNumber!} does not need updating --- cache used HURRAY !!!` @@ -146,12 +150,7 @@ export async function ensurePr( ) { logger.debug('Checking how long this branch has been pending'); const lastCommitTime = await getBranchLastCommitTime(branchName); - const currentTime = new Date(); - const millisecondsPerHour = 1000 * 60 * 60; - const elapsedHours = Math.round( - (currentTime.getTime() - lastCommitTime.getTime()) / millisecondsPerHour - ); - if (elapsedHours >= config.prNotPendingHours) { + if (getElapsedHours(lastCommitTime) >= config.prNotPendingHours) { logger.debug('Branch exceeds prNotPending hours - forcing PR creation'); config.forcePr = true; } @@ -185,11 +184,7 @@ export async function ensurePr( if ((await getBranchStatus()) === BranchStatus.yellow) { logger.debug(`Branch status is yellow - checking timeout`); const lastCommitTime = await getBranchLastCommitTime(branchName); - const currentTime = new Date(); - const millisecondsPerHour = 1000 * 60 * 60; - const elapsedHours = Math.round( - (currentTime.getTime() - lastCommitTime.getTime()) / millisecondsPerHour - ); + const elapsedHours = getElapsedHours(lastCommitTime); if ( !dependencyDashboardCheck && ((config.stabilityStatus && @@ -226,12 +221,8 @@ export async function ensurePr( } if (config.fetchReleaseNotes) { - // eslint-disable-next-line no-console - console.time('changelog'); // fetch changelogs when not already done; await embedChangelogs(upgrades); - // eslint-disable-next-line no-console - console.timeEnd('changelog'); } // Get changelog and then generate template strings From 80df5e3865fa12a08b534f00fdd48b6fa082fdbf Mon Sep 17 00:00:00 2001 From: RahulGautamSingh Date: Thu, 10 Nov 2022 08:35:07 +0530 Subject: [PATCH 04/48] setPrCache when with-pr and pr is updated/created --- lib/workers/repository/update/pr/index.ts | 29 ++++++++++------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/lib/workers/repository/update/pr/index.ts b/lib/workers/repository/update/pr/index.ts index 94d13ee5ce7449..ae1e109197b99e 100644 --- a/lib/workers/repository/update/pr/index.ts +++ b/lib/workers/repository/update/pr/index.ts @@ -44,8 +44,8 @@ function getElapsedHours(time: Date | string): number { const pastTime = typeof time === 'string' ? new Date(time) : time; const currentTime = new Date(); const millisecondsPerHour = 1000 * 60 * 60; - return ( - Math.round(currentTime.getTime() - pastTime.getTime()) / millisecondsPerHour + return Math.round( + currentTime.getTime() - pastTime.getTime() / millisecondsPerHour ); } @@ -105,28 +105,24 @@ export async function ensurePr( const { branchName, ignoreTests, prTitle = '', upgrades } = config; const dependencyDashboardCheck = config.dependencyDashboardChecks?.[config.branchName]; - // Check if existing PR exists + // Check if PR already exists const existingPr = await platform.getBranchPr(branchName); if (existingPr) { logger.debug('Found existing PR'); const prCache = getPrCache(branchName); if (prCache) { - logger.debug({ prCache }, 'Pr-Cache exists'); + logger.debug({ prCache }, 'Found existing Pr cache'); const lastEditTime = prCache?.lastEdited; - // check pr config fingerprint: no need to check for upgrades as it is already inside config + // validate pr cache and if okay skip pr body update and changelog fetching if ( isCloned() === false && prFingerprint === prCache.fingerprint && getElapsedHours(lastEditTime) > 24 ) { - logger.debug( - `${existingPr.displayNumber!} does not need updating --- cache used HURRAY !!!` - ); + logger.debug('Pr fingerprints match, skiping fetching changelogs'); return { type: 'with-pr', pr: existingPr }; } - } else { - logger.debug('Pr-Cache not found'); - setPrCache(branchName, prFingerprint); + logger.debug('Pr fingerprints do not match'); } } config.upgrades = []; @@ -330,6 +326,8 @@ export async function ensurePr( ) { // TODO: types (#7154) logger.debug(`${existingPr.displayNumber!} does not need updating`); + // update prCache last edit time + setPrCache(branchName, prFingerprint); return { type: 'with-pr', pr: existingPr }; } // PR must need updating @@ -349,8 +347,6 @@ export async function ensurePr( }, 'PR body changed' ); - // update prCache last edit time - setPrCache(branchName, prFingerprint); } if (GlobalConfig.get('dryRun')) { logger.info(`DRY-RUN: Would update PR #${existingPr.number}`); @@ -363,6 +359,8 @@ export async function ensurePr( }); logger.info({ pr: existingPr.number, prTitle }, `PR updated`); } + // update prCache last edit time + setPrCache(branchName, prFingerprint); return { type: 'with-pr', pr: existingPr }; } logger.debug({ branch: branchName, prTitle }, `Creating PR`); @@ -393,9 +391,6 @@ export async function ensurePr( draftPR: config.draftPR, }); - // add pr object to branch cache - setPrCache(branchName, prFingerprint); - incLimitedValue(Limit.PullRequests); logger.info({ pr: pr?.number, prTitle }, 'PR created'); } catch (err) { @@ -458,6 +453,8 @@ export async function ensurePr( } // TODO: types (#7154) logger.debug(`Created ${pr.displayNumber!}`); + // update prCache last edit time + setPrCache(branchName, prFingerprint); return { type: 'with-pr', pr }; } } catch (err) { From 8ff8337240417f142d21f1b5ee5fb5469671e82a Mon Sep 17 00:00:00 2001 From: RahulGautamSingh Date: Thu, 10 Nov 2022 11:32:57 +0530 Subject: [PATCH 05/48] refactor code --- .gitignore | 1 + lib/workers/repository/update/pr/index.spec.ts | 1 - lib/workers/repository/update/pr/index.ts | 5 ++--- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 5ef8dd5fd84db6..6a784ec254ca5a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +/herewego /node_modules /config.js* /coverage diff --git a/lib/workers/repository/update/pr/index.spec.ts b/lib/workers/repository/update/pr/index.spec.ts index d018736d59dc43..a1028d62314dff 100644 --- a/lib/workers/repository/update/pr/index.spec.ts +++ b/lib/workers/repository/update/pr/index.spec.ts @@ -421,7 +421,6 @@ describe('workers/repository/update/pr/index', () => { git.getBranchLastCommitTime.mockResolvedValueOnce(then.toJSDate()); checks.resolveBranchStatus.mockResolvedValueOnce(BranchStatus.yellow); - platform.createPr.mockResolvedValueOnce(pr); const res = await ensurePr({ ...config, diff --git a/lib/workers/repository/update/pr/index.ts b/lib/workers/repository/update/pr/index.ts index 8d4a773ac3bd4a..fb5c9dfdca7c63 100644 --- a/lib/workers/repository/update/pr/index.ts +++ b/lib/workers/repository/update/pr/index.ts @@ -44,7 +44,7 @@ function getElapsedHours(time: Date | string): number { const currentTime = new Date(); const millisecondsPerHour = 1000 * 60 * 60; return Math.round( - currentTime.getTime() - pastTime.getTime() / millisecondsPerHour + (currentTime.getTime() - pastTime.getTime()) / millisecondsPerHour ); } @@ -323,10 +323,9 @@ export async function ensurePr( existingPrTitle === newPrTitle && existingPrBodyHash === newPrBodyHash ) { + // no need to update PrCache here else we will never reach elapsedHours > 24 // TODO: types (#7154) logger.debug(`${existingPr.displayNumber!} does not need updating`); - // update prCache last edit time - setPrCache(branchName, prFingerprint); return { type: 'with-pr', pr: existingPr }; } // PR must need updating From 1dc2e65f74fd0e15964a75a54b4fd054f210ac74 Mon Sep 17 00:00:00 2001 From: RahulGautamSingh Date: Thu, 10 Nov 2022 11:34:08 +0530 Subject: [PATCH 06/48] revert changes to .gitignore --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index 6a784ec254ca5a..5ef8dd5fd84db6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ -/herewego /node_modules /config.js* /coverage From 941911f611d1ea9b21ce8a8d74f909de3f0437a9 Mon Sep 17 00:00:00 2001 From: RahulGautamSingh Date: Fri, 11 Nov 2022 01:56:12 +0530 Subject: [PATCH 07/48] apply suggested changes --- lib/workers/repository/update/pr/index.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/workers/repository/update/pr/index.ts b/lib/workers/repository/update/pr/index.ts index fb5c9dfdca7c63..faa4959ac8208c 100644 --- a/lib/workers/repository/update/pr/index.ts +++ b/lib/workers/repository/update/pr/index.ts @@ -122,6 +122,10 @@ export async function ensurePr( return { type: 'with-pr', pr: existingPr }; } logger.debug('Pr fingerprints do not match'); + } else { + logger.debug('Pr cache not found, creating new.'); + // update prCache last edit time + setPrCache(branchName, prFingerprint); } } config.upgrades = []; @@ -356,9 +360,9 @@ export async function ensurePr( platformOptions: getPlatformPrOptions(config), }); logger.info({ pr: existingPr.number, prTitle }, `PR updated`); + // update prCache last edit time + setPrCache(branchName, prFingerprint); } - // update prCache last edit time - setPrCache(branchName, prFingerprint); return { type: 'with-pr', pr: existingPr }; } logger.debug({ branch: branchName, prTitle }, `Creating PR`); From 061f2363c27bbcb5fb6830c3df15e518f0ec4910 Mon Sep 17 00:00:00 2001 From: RahulGautamSingh Date: Fri, 11 Nov 2022 02:07:24 +0530 Subject: [PATCH 08/48] refactor: remove unnecessary optional chaining --- lib/workers/repository/update/pr/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/workers/repository/update/pr/index.ts b/lib/workers/repository/update/pr/index.ts index faa4959ac8208c..e7e4c1b20a4fde 100644 --- a/lib/workers/repository/update/pr/index.ts +++ b/lib/workers/repository/update/pr/index.ts @@ -111,7 +111,7 @@ export async function ensurePr( const prCache = getPrCache(branchName); if (prCache) { logger.debug({ prCache }, 'Found existing Pr cache'); - const lastEditTime = prCache?.lastEdited; + const lastEditTime = prCache.lastEdited; // validate pr cache and if okay skip pr body update and changelog fetching if ( isCloned() === false && From b2075c89f83274e2259635faf6c9cfbae7657186 Mon Sep 17 00:00:00 2001 From: RahulGautamSingh Date: Fri, 11 Nov 2022 02:25:13 +0530 Subject: [PATCH 09/48] move getElapsedHours to util/date --- lib/util/date.ts | 9 +++++++++ lib/workers/repository/update/pr/index.ts | 10 +--------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/lib/util/date.ts b/lib/util/date.ts index 93d4f46f00a4af..809e4663316677 100644 --- a/lib/util/date.ts +++ b/lib/util/date.ts @@ -10,3 +10,12 @@ export function getElapsedDays(timestamp: string): number { export function getElapsedMinutes(date: Date): number { return Math.floor((new Date().getTime() - date.getTime()) / ONE_MINUTE_MS); } + +export function getElapsedHours(time: Date | string): number { + const pastTime = typeof time === 'string' ? new Date(time) : time; + const currentTime = new Date(); + const millisecondsPerHour = 1000 * 60 * 60; + return Math.round( + (currentTime.getTime() - pastTime.getTime()) / millisecondsPerHour + ); +} diff --git a/lib/workers/repository/update/pr/index.ts b/lib/workers/repository/update/pr/index.ts index e7e4c1b20a4fde..2b4ed8c26a97b3 100644 --- a/lib/workers/repository/update/pr/index.ts +++ b/lib/workers/repository/update/pr/index.ts @@ -18,6 +18,7 @@ import { ensureComment } from '../../../../modules/platform/comment'; import { hashBody } from '../../../../modules/platform/pr-body'; import { BranchStatus } from '../../../../types'; import { ExternalHostError } from '../../../../types/errors/external-host-error'; +import { getElapsedHours } from '../../../../util/date'; import { stripEmojis } from '../../../../util/emoji'; import { fingerprint } from '../../../../util/fingerprint'; import { @@ -39,15 +40,6 @@ import { prepareLabels } from './labels'; import { addParticipants } from './participants'; import { getPrCache, setPrCache } from './set-pr-cache'; -function getElapsedHours(time: Date | string): number { - const pastTime = typeof time === 'string' ? new Date(time) : time; - const currentTime = new Date(); - const millisecondsPerHour = 1000 * 60 * 60; - return Math.round( - (currentTime.getTime() - pastTime.getTime()) / millisecondsPerHour - ); -} - export function getPlatformPrOptions( config: RenovateConfig & PlatformPrOptions ): PlatformPrOptions { From 27102408adcfeb11802e7c823a569e2fdf09b971 Mon Sep 17 00:00:00 2001 From: RahulGautamSingh Date: Wed, 16 Nov 2022 22:24:51 +0530 Subject: [PATCH 10/48] update comments --- lib/workers/repository/update/pr/index.ts | 3 --- lib/workers/repository/update/pr/set-pr-cache.ts | 1 + 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/workers/repository/update/pr/index.ts b/lib/workers/repository/update/pr/index.ts index 2b4ed8c26a97b3..68924958834ffb 100644 --- a/lib/workers/repository/update/pr/index.ts +++ b/lib/workers/repository/update/pr/index.ts @@ -116,7 +116,6 @@ export async function ensurePr( logger.debug('Pr fingerprints do not match'); } else { logger.debug('Pr cache not found, creating new.'); - // update prCache last edit time setPrCache(branchName, prFingerprint); } } @@ -352,7 +351,6 @@ export async function ensurePr( platformOptions: getPlatformPrOptions(config), }); logger.info({ pr: existingPr.number, prTitle }, `PR updated`); - // update prCache last edit time setPrCache(branchName, prFingerprint); } return { type: 'with-pr', pr: existingPr }; @@ -447,7 +445,6 @@ export async function ensurePr( } // TODO: types (#7154) logger.debug(`Created ${pr.displayNumber!}`); - // update prCache last edit time setPrCache(branchName, prFingerprint); return { type: 'with-pr', pr }; } diff --git a/lib/workers/repository/update/pr/set-pr-cache.ts b/lib/workers/repository/update/pr/set-pr-cache.ts index c8e1156b12dab9..b04a252b6a0e45 100644 --- a/lib/workers/repository/update/pr/set-pr-cache.ts +++ b/lib/workers/repository/update/pr/set-pr-cache.ts @@ -16,6 +16,7 @@ export function getPrCache(branchName: string): PrCache | null { return null; } +// store the time a PR was last updated export function setPrCache(branchName: string, fingerprint: string): void { logger.debug(`setPrCache()`); const cache = getCache(); From 6486b64483763370a0390f4e52fd0a97953c32eb Mon Sep 17 00:00:00 2001 From: RahulGautamSingh Date: Wed, 23 Nov 2022 06:33:59 +0530 Subject: [PATCH 11/48] add tests' --- .../repository/update/pr/index.spec.ts | 68 ++++++++++++++++ .../repository/update/pr/set-pr-cache.spec.ts | 78 +++++++++++++++++++ 2 files changed, 146 insertions(+) create mode 100644 lib/workers/repository/update/pr/set-pr-cache.spec.ts diff --git a/lib/workers/repository/update/pr/index.spec.ts b/lib/workers/repository/update/pr/index.spec.ts index db355ade891712..97f50cff4703cf 100644 --- a/lib/workers/repository/update/pr/index.spec.ts +++ b/lib/workers/repository/update/pr/index.spec.ts @@ -10,12 +10,16 @@ import * as _comment from '../../../../modules/platform/comment'; import { getPrBodyStruct } from '../../../../modules/platform/pr-body'; import type { Pr } from '../../../../modules/platform/types'; import { ExternalHostError } from '../../../../types/errors/external-host-error'; +import type { PrCache } from '../../../../util/cache/repository/types'; +import { fingerprint } from '../../../../util/fingerprint'; import * as _limits from '../../../global/limits'; import type { BranchConfig, BranchUpgradeConfig } from '../../../types'; +import { embedChangelog } from '../../changelog'; import * as _statusChecks from '../branch/status-checks'; import * as _prBody from './body'; import type { ChangeLogChange, ChangeLogRelease } from './changelog/types'; import * as _participants from './participants'; +import * as _prCache from './set-pr-cache'; import { ensurePr } from '.'; jest.mock('../../../../util/git'); @@ -36,6 +40,9 @@ const participants = mocked(_participants); jest.mock('../../../../modules/platform/comment'); const comment = mocked(_comment); +jest.mock('./set-pr-cache'); +const prCache = mocked(_prCache); + describe('workers/repository/update/pr/index', () => { describe('ensurePr', () => { const number = 123; @@ -64,6 +71,7 @@ describe('workers/repository/update/pr/index', () => { jest.resetAllMocks(); GlobalConfig.reset(); prBody.getPrBody.mockReturnValue(body); + git.isCloned.mockReturnValueOnce(false); }); describe('Create', () => { @@ -79,6 +87,7 @@ describe('workers/repository/update/pr/index', () => { { pr: pr.number, prTitle }, 'PR created' ); + expect(prCache.setPrCache).toHaveBeenCalledTimes(1); }); it('aborts PR creation once limit is exceeded', async () => { @@ -696,5 +705,64 @@ describe('workers/repository/update/pr/index', () => { }); }); }); + + describe('PrCache', () => { + const existingPr: Pr = { + ...pr, + }; + let cachedPr: PrCache | null = null; + + it('no cache found', async () => { + platform.getBranchPr.mockResolvedValue(existingPr); + prCache.getPrCache.mockReturnValueOnce(cachedPr); + await ensurePr(config); + expect(logger.logger.debug).toHaveBeenCalledWith( + 'Pr cache not found, creating new.' + ); + expect(prCache.setPrCache).toHaveBeenCalled(); + }); + + it('invalid cache', async () => { + platform.getBranchPr.mockResolvedValue(existingPr); + cachedPr = { + fingerprint: 'fingerprint', + lastEdited: new Date(), + }; + prCache.getPrCache.mockReturnValueOnce(cachedPr); + await ensurePr(config); + expect(logger.logger.debug).toHaveBeenCalledWith( + 'Pr fingerprints do not match' + ); + }); + + it('cache valid but less than 24 hours', async () => { + platform.getBranchPr.mockResolvedValue(existingPr); + cachedPr = { + fingerprint: fingerprint(config), + lastEdited: new Date(), + }; + prCache.getPrCache.mockReturnValueOnce(cachedPr); + await ensurePr(config); + expect(logger.logger.debug).toHaveBeenCalledWith( + 'Pr fingerprints do not match' + ); + }); + + it('fetches changelogs when cache valid and more than 24 hours', async () => { + platform.getBranchPr.mockResolvedValue(existingPr); + cachedPr = { + fingerprint: fingerprint(config), + lastEdited: new Date( + new Date().getMilliseconds() - 25 * 60 * 60 * 1000 + ), + }; + prCache.getPrCache.mockReturnValueOnce(cachedPr); + await ensurePr(config); + expect(logger.logger.debug).toHaveBeenCalledWith( + 'Pr fingerprints match, skiping fetching changelogs' + ); + expect(embedChangelog).toHaveBeenCalledTimes(0); + }); + }); }); }); diff --git a/lib/workers/repository/update/pr/set-pr-cache.spec.ts b/lib/workers/repository/update/pr/set-pr-cache.spec.ts new file mode 100644 index 00000000000000..80a54c040f2066 --- /dev/null +++ b/lib/workers/repository/update/pr/set-pr-cache.spec.ts @@ -0,0 +1,78 @@ +import { logger, mocked } from '../../../../../test/util'; +import * as _cache from '../../../../util/cache/repository'; +import type { + BranchCache, + RepoCacheData, +} from '../../../../util/cache/repository/types'; +import { getPrCache, setPrCache } from './set-pr-cache'; + +jest.mock('../../../../util/cache/repository'); +const cache = mocked(_cache); + +describe('workers/repository/update/pr/set-pr-cache', () => { + const branchCache: BranchCache = { + automerge: false, + baseBranch: 'base_branch', + baseBranchSha: 'base_sha', + branchName: 'branch_name', + prNo: null, + sha: 'sha', + upgrades: [], + prCache: null, + }; + const dummyCache: RepoCacheData = { + branches: [branchCache], + }; + + describe('getPrCache()', () => { + it('return null for null cache', () => { + cache.getCache.mockReturnValue({}); + expect(getPrCache('branch_name')).toBeNull(); + }); + + it('return null if prCache is absent or null', () => { + cache.getCache.mockReturnValue(dummyCache); + expect(getPrCache('branch_name')).toBeNull(); + }); + + it('returns prCache', () => { + branchCache.prCache = { + fingerprint: 'fp', + lastEdited: new Date('11/11/2011'), + }; + cache.getCache.mockReturnValue(dummyCache); + expect(getPrCache('branch_name')).toStrictEqual({ + fingerprint: 'fp', + lastEdited: new Date('11/11/2011'), + }); + }); + }); + + describe('setPrCache()', () => { + it('logs if branch not found', () => { + cache.getCache.mockReturnValue(dummyCache); + setPrCache('branch_1', 'fingerprint_hash'); + expect(logger.logger.debug).toHaveBeenCalledWith( + 'setPrCache(): Branch cache not present' + ); + }); + + it('set prCache', () => { + cache.getCache.mockReturnValue(dummyCache); + jest.useFakeTimers().setSystemTime(new Date('2020-01-01')); + setPrCache('branch_name', 'fingerprint_hash'); + expect(dummyCache).toStrictEqual({ + branches: [ + { + ...branchCache, + + prCache: { + fingerprint: 'fingerprint_hash', + lastEdited: new Date('2020-01-01'), + }, + }, + ], + }); + }); + }); +}); From 76134e463652e49965208803f19eb49cbef7c388 Mon Sep 17 00:00:00 2001 From: RahulGautamSingh Date: Wed, 23 Nov 2022 08:58:40 +0530 Subject: [PATCH 12/48] Apply suggestions from code review --- lib/workers/repository/update/pr/index.spec.ts | 10 +++++----- lib/workers/repository/update/pr/index.ts | 3 +-- lib/workers/repository/update/pr/set-pr-cache.spec.ts | 5 ++--- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/lib/workers/repository/update/pr/index.spec.ts b/lib/workers/repository/update/pr/index.spec.ts index 97f50cff4703cf..52b0d01124bd85 100644 --- a/lib/workers/repository/update/pr/index.spec.ts +++ b/lib/workers/repository/update/pr/index.spec.ts @@ -706,13 +706,13 @@ describe('workers/repository/update/pr/index', () => { }); }); - describe('PrCache', () => { + describe('prCache', () => { const existingPr: Pr = { ...pr, }; let cachedPr: PrCache | null = null; - it('no cache found', async () => { + it('creates new cache if not found', async () => { platform.getBranchPr.mockResolvedValue(existingPr); prCache.getPrCache.mockReturnValueOnce(cachedPr); await ensurePr(config); @@ -722,7 +722,7 @@ describe('workers/repository/update/pr/index', () => { expect(prCache.setPrCache).toHaveBeenCalled(); }); - it('invalid cache', async () => { + it('logs for invalid cache', async () => { platform.getBranchPr.mockResolvedValue(existingPr); cachedPr = { fingerprint: 'fingerprint', @@ -735,7 +735,7 @@ describe('workers/repository/update/pr/index', () => { ); }); - it('cache valid but less than 24 hours', async () => { + it('logs when pr cache is valid pr was edited within 24 hours', async () => { platform.getBranchPr.mockResolvedValue(existingPr); cachedPr = { fingerprint: fingerprint(config), @@ -748,7 +748,7 @@ describe('workers/repository/update/pr/index', () => { ); }); - it('fetches changelogs when cache valid and more than 24 hours', async () => { + it('skips fetching changelogs when cache is valid and pr was edited more than 24 hours ago', async () => { platform.getBranchPr.mockResolvedValue(existingPr); cachedPr = { fingerprint: fingerprint(config), diff --git a/lib/workers/repository/update/pr/index.ts b/lib/workers/repository/update/pr/index.ts index 443fdc4492a53e..5b1b1d2f490cbc 100644 --- a/lib/workers/repository/update/pr/index.ts +++ b/lib/workers/repository/update/pr/index.ts @@ -103,7 +103,7 @@ export async function ensurePr( if (prCache) { logger.debug({ prCache }, 'Found existing Pr cache'); const lastEditTime = prCache.lastEdited; - // validate pr cache and if okay skip pr body update and changelog fetching + // return if pr cache is valid and pr was last edited before a day if ( isCloned() === false && prFingerprint === prCache.fingerprint && @@ -316,7 +316,6 @@ export async function ensurePr( existingPrTitle === newPrTitle && existingPrBodyHash === newPrBodyHash ) { - // no need to update PrCache here else we will never reach elapsedHours > 24 // TODO: types (#7154) logger.debug(`${existingPr.displayNumber!} does not need updating`); return { type: 'with-pr', pr: existingPr }; diff --git a/lib/workers/repository/update/pr/set-pr-cache.spec.ts b/lib/workers/repository/update/pr/set-pr-cache.spec.ts index 80a54c040f2066..8f9e2016d8fcdb 100644 --- a/lib/workers/repository/update/pr/set-pr-cache.spec.ts +++ b/lib/workers/repository/update/pr/set-pr-cache.spec.ts @@ -25,12 +25,12 @@ describe('workers/repository/update/pr/set-pr-cache', () => { }; describe('getPrCache()', () => { - it('return null for null cache', () => { + it('return null if cache is empty', () => { cache.getCache.mockReturnValue({}); expect(getPrCache('branch_name')).toBeNull(); }); - it('return null if prCache is absent or null', () => { + it('return null if prCache is falsy', () => { cache.getCache.mockReturnValue(dummyCache); expect(getPrCache('branch_name')).toBeNull(); }); @@ -65,7 +65,6 @@ describe('workers/repository/update/pr/set-pr-cache', () => { branches: [ { ...branchCache, - prCache: { fingerprint: 'fingerprint_hash', lastEdited: new Date('2020-01-01'), From ba33c96608fcd459830dc092ad0812c1a9f8ed3b Mon Sep 17 00:00:00 2001 From: RahulGautamSingh Date: Thu, 24 Nov 2022 00:36:42 +0530 Subject: [PATCH 13/48] Update lib/util/cache/repository/types.ts Co-authored-by: Rhys Arkins --- lib/util/cache/repository/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/util/cache/repository/types.ts b/lib/util/cache/repository/types.ts index 60af7ff9afafa2..e839f9f6fe6e4d 100644 --- a/lib/util/cache/repository/types.ts +++ b/lib/util/cache/repository/types.ts @@ -44,7 +44,7 @@ export interface BranchCache { */ baseBranchSha: string | null; /** - * Hash of the manager fingerprints and the update branch config(filtered) + * Hash of the manager fingerprints and the filtered update branch config */ branchFingerprint?: string; /** From 32e74d76d940306047cc391fbc72733f378e8127 Mon Sep 17 00:00:00 2001 From: RahulGautamSingh Date: Thu, 24 Nov 2022 15:21:36 +0530 Subject: [PATCH 14/48] convert type Date->string + update debug logs --- lib/util/cache/repository/types.ts | 2 +- lib/workers/repository/update/pr/index.spec.ts | 16 ++++++++-------- lib/workers/repository/update/pr/index.ts | 8 ++++---- .../repository/update/pr/set-pr-cache.spec.ts | 6 +++--- lib/workers/repository/update/pr/set-pr-cache.ts | 2 +- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/lib/util/cache/repository/types.ts b/lib/util/cache/repository/types.ts index 60af7ff9afafa2..284ebbb5448837 100644 --- a/lib/util/cache/repository/types.ts +++ b/lib/util/cache/repository/types.ts @@ -27,7 +27,7 @@ export interface BranchUpgradeCache { export interface PrCache { fingerprint: string; - lastEdited: Date; + lastEdited: string; } export interface BranchCache { diff --git a/lib/workers/repository/update/pr/index.spec.ts b/lib/workers/repository/update/pr/index.spec.ts index 52b0d01124bd85..beb7f97e03b7cd 100644 --- a/lib/workers/repository/update/pr/index.spec.ts +++ b/lib/workers/repository/update/pr/index.spec.ts @@ -717,7 +717,7 @@ describe('workers/repository/update/pr/index', () => { prCache.getPrCache.mockReturnValueOnce(cachedPr); await ensurePr(config); expect(logger.logger.debug).toHaveBeenCalledWith( - 'Pr cache not found, creating new.' + 'Pr cache not found, creating new' ); expect(prCache.setPrCache).toHaveBeenCalled(); }); @@ -726,12 +726,12 @@ describe('workers/repository/update/pr/index', () => { platform.getBranchPr.mockResolvedValue(existingPr); cachedPr = { fingerprint: 'fingerprint', - lastEdited: new Date(), + lastEdited: new Date().toISOString(), }; prCache.getPrCache.mockReturnValueOnce(cachedPr); await ensurePr(config); expect(logger.logger.debug).toHaveBeenCalledWith( - 'Pr fingerprints do not match' + 'Invaild cache, processing PR' ); }); @@ -739,27 +739,27 @@ describe('workers/repository/update/pr/index', () => { platform.getBranchPr.mockResolvedValue(existingPr); cachedPr = { fingerprint: fingerprint(config), - lastEdited: new Date(), + lastEdited: new Date().toISOString(), }; prCache.getPrCache.mockReturnValueOnce(cachedPr); await ensurePr(config); expect(logger.logger.debug).toHaveBeenCalledWith( - 'Pr fingerprints do not match' + 'Invaild cache, processing PR' ); }); - it('skips fetching changelogs when cache is valid and pr was edited more than 24 hours ago', async () => { + it('skips fetching changelogs', async () => { platform.getBranchPr.mockResolvedValue(existingPr); cachedPr = { fingerprint: fingerprint(config), lastEdited: new Date( new Date().getMilliseconds() - 25 * 60 * 60 * 1000 - ), + ).toISOString(), }; prCache.getPrCache.mockReturnValueOnce(cachedPr); await ensurePr(config); expect(logger.logger.debug).toHaveBeenCalledWith( - 'Pr fingerprints match, skiping fetching changelogs' + 'Cache is valid, skipping PR update' ); expect(embedChangelog).toHaveBeenCalledTimes(0); }); diff --git a/lib/workers/repository/update/pr/index.ts b/lib/workers/repository/update/pr/index.ts index 5b1b1d2f490cbc..ba508e4208ee22 100644 --- a/lib/workers/repository/update/pr/index.ts +++ b/lib/workers/repository/update/pr/index.ts @@ -103,18 +103,18 @@ export async function ensurePr( if (prCache) { logger.debug({ prCache }, 'Found existing Pr cache'); const lastEditTime = prCache.lastEdited; - // return if pr cache is valid and pr was last edited before a day + // return if pr cache is valid and pr was last edited before a day if ( isCloned() === false && prFingerprint === prCache.fingerprint && getElapsedHours(lastEditTime) > 24 ) { - logger.debug('Pr fingerprints match, skiping fetching changelogs'); + logger.debug('Cache is valid, skipping PR update'); return { type: 'with-pr', pr: existingPr }; } - logger.debug('Pr fingerprints do not match'); + logger.debug('Invaild cache, processing PR'); } else { - logger.debug('Pr cache not found, creating new.'); + logger.debug('Pr cache not found, creating new'); setPrCache(branchName, prFingerprint); } } diff --git a/lib/workers/repository/update/pr/set-pr-cache.spec.ts b/lib/workers/repository/update/pr/set-pr-cache.spec.ts index 8f9e2016d8fcdb..e86594d2d71841 100644 --- a/lib/workers/repository/update/pr/set-pr-cache.spec.ts +++ b/lib/workers/repository/update/pr/set-pr-cache.spec.ts @@ -38,12 +38,12 @@ describe('workers/repository/update/pr/set-pr-cache', () => { it('returns prCache', () => { branchCache.prCache = { fingerprint: 'fp', - lastEdited: new Date('11/11/2011'), + lastEdited: new Date('11/11/2011').toISOString(), }; cache.getCache.mockReturnValue(dummyCache); expect(getPrCache('branch_name')).toStrictEqual({ fingerprint: 'fp', - lastEdited: new Date('11/11/2011'), + lastEdited: new Date('11/11/2011').toISOString(), }); }); }); @@ -67,7 +67,7 @@ describe('workers/repository/update/pr/set-pr-cache', () => { ...branchCache, prCache: { fingerprint: 'fingerprint_hash', - lastEdited: new Date('2020-01-01'), + lastEdited: new Date('2020-01-01').toISOString(), }, }, ], diff --git a/lib/workers/repository/update/pr/set-pr-cache.ts b/lib/workers/repository/update/pr/set-pr-cache.ts index b04a252b6a0e45..989a2cd46fc3f8 100644 --- a/lib/workers/repository/update/pr/set-pr-cache.ts +++ b/lib/workers/repository/update/pr/set-pr-cache.ts @@ -31,6 +31,6 @@ export function setPrCache(branchName: string, fingerprint: string): void { branch.prCache = { fingerprint, - lastEdited: new Date(), + lastEdited: new Date().toISOString(), }; } From cb86f69d1435368965be85b6d94d0e8ce6f9b0df Mon Sep 17 00:00:00 2001 From: RahulGautamSingh Date: Mon, 12 Dec 2022 07:36:17 +0530 Subject: [PATCH 15/48] remove isCloned check --- lib/workers/repository/update/pr/index.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/lib/workers/repository/update/pr/index.ts b/lib/workers/repository/update/pr/index.ts index ba508e4208ee22..7e9ded3ed1f4fb 100644 --- a/lib/workers/repository/update/pr/index.ts +++ b/lib/workers/repository/update/pr/index.ts @@ -20,11 +20,7 @@ import { ExternalHostError } from '../../../../types/errors/external-host-error' import { getElapsedHours } from '../../../../util/date'; import { stripEmojis } from '../../../../util/emoji'; import { fingerprint } from '../../../../util/fingerprint'; -import { - deleteBranch, - getBranchLastCommitTime, - isCloned, -} from '../../../../util/git'; +import { deleteBranch, getBranchLastCommitTime } from '../../../../util/git'; import { memoize } from '../../../../util/memoize'; import { incLimitedValue, isLimitReached } from '../../../global/limits'; import type { @@ -105,7 +101,6 @@ export async function ensurePr( const lastEditTime = prCache.lastEdited; // return if pr cache is valid and pr was last edited before a day if ( - isCloned() === false && prFingerprint === prCache.fingerprint && getElapsedHours(lastEditTime) > 24 ) { From d2019662d56faf18a022b745e85b348c446fe1e4 Mon Sep 17 00:00:00 2001 From: RahulGautamSingh Date: Sun, 8 Jan 2023 19:42:24 +0530 Subject: [PATCH 16/48] - refactor logs - update pr cache logic --- lib/workers/repository/update/pr/index.ts | 25 ++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/lib/workers/repository/update/pr/index.ts b/lib/workers/repository/update/pr/index.ts index 7e9ded3ed1f4fb..dd8d1aec9d9dd8 100644 --- a/lib/workers/repository/update/pr/index.ts +++ b/lib/workers/repository/update/pr/index.ts @@ -17,6 +17,7 @@ import { import { ensureComment } from '../../../../modules/platform/comment'; import { hashBody } from '../../../../modules/platform/pr-body'; import { ExternalHostError } from '../../../../types/errors/external-host-error'; +import type { PrCache } from '../../../../util/cache/repository/types'; import { getElapsedHours } from '../../../../util/date'; import { stripEmojis } from '../../../../util/emoji'; import { fingerprint } from '../../../../util/fingerprint'; @@ -76,6 +77,21 @@ export function updatePrDebugData( }; } +function validatePrCache(prCache: PrCache, prFingerprint: string): boolean { + if (prCache.fingerprint !== prFingerprint) { + logger.debug('PR fingerprints mismatch, processing PR'); + logger.debug({ prFingerprint }, 'prFingerprint'); + return false; + } + + if (getElapsedHours(prCache.lastEdited) < 24) { + logger.debug('Processing PR as it has been recently edited'); // edited within 24 hours + return false; + } + + return true; +} + // Ensures that PR exists with matching title/body export async function ensurePr( prConfig: BranchConfig @@ -98,16 +114,12 @@ export async function ensurePr( const prCache = getPrCache(branchName); if (prCache) { logger.debug({ prCache }, 'Found existing Pr cache'); - const lastEditTime = prCache.lastEdited; // return if pr cache is valid and pr was last edited before a day - if ( - prFingerprint === prCache.fingerprint && - getElapsedHours(lastEditTime) > 24 - ) { + if (validatePrCache(prCache, prFingerprint)) { logger.debug('Cache is valid, skipping PR update'); return { type: 'with-pr', pr: existingPr }; } - logger.debug('Invaild cache, processing PR'); + setPrCache(branchName, prFingerprint); } else { logger.debug('Pr cache not found, creating new'); setPrCache(branchName, prFingerprint); @@ -343,7 +355,6 @@ export async function ensurePr( platformOptions: getPlatformPrOptions(config), }); logger.info({ pr: existingPr.number, prTitle }, `PR updated`); - setPrCache(branchName, prFingerprint); } return { type: 'with-pr', pr: existingPr }; } From cc0e82f13da756f603bcda493c42e76874fab297 Mon Sep 17 00:00:00 2001 From: RahulGautamSingh Date: Mon, 9 Jan 2023 09:55:24 +0530 Subject: [PATCH 17/48] refactor: update log messages --- lib/workers/repository/update/pr/index.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/workers/repository/update/pr/index.ts b/lib/workers/repository/update/pr/index.ts index dd8d1aec9d9dd8..640dd8e2f5103e 100644 --- a/lib/workers/repository/update/pr/index.ts +++ b/lib/workers/repository/update/pr/index.ts @@ -113,15 +113,17 @@ export async function ensurePr( logger.debug('Found existing PR'); const prCache = getPrCache(branchName); if (prCache) { - logger.debug({ prCache }, 'Found existing Pr cache'); + logger.debug({ prCache }, 'Found existing PR cache'); // return if pr cache is valid and pr was last edited before a day if (validatePrCache(prCache, prFingerprint)) { - logger.debug('Cache is valid, skipping PR update'); + logger.debug( + 'PR cache matches, and no PR changes in last 24h, so skipping PR body check' + ); return { type: 'with-pr', pr: existingPr }; } setPrCache(branchName, prFingerprint); } else { - logger.debug('Pr cache not found, creating new'); + logger.debug('PR cache not found, creating new'); setPrCache(branchName, prFingerprint); } } From 4e72018d963ca5aa3b2d39c0a85c6681284dfc4b Mon Sep 17 00:00:00 2001 From: RahulGautamSingh Date: Mon, 9 Jan 2023 10:00:46 +0530 Subject: [PATCH 18/48] ensure repoCache:enabled before using prCache --- lib/workers/repository/update/pr/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/workers/repository/update/pr/index.ts b/lib/workers/repository/update/pr/index.ts index 640dd8e2f5103e..ea25996b7c2c9b 100644 --- a/lib/workers/repository/update/pr/index.ts +++ b/lib/workers/repository/update/pr/index.ts @@ -109,7 +109,7 @@ export async function ensurePr( config.dependencyDashboardChecks?.[config.branchName]; // Check if PR already exists const existingPr = await platform.getBranchPr(branchName); - if (existingPr) { + if (existingPr && config.repositoryCache === 'enabled') { logger.debug('Found existing PR'); const prCache = getPrCache(branchName); if (prCache) { From 0dd63433c661e09faa53f6bb33be1b394ba72baf Mon Sep 17 00:00:00 2001 From: RahulGautamSingh Date: Tue, 10 Jan 2023 15:17:45 +0530 Subject: [PATCH 19/48] use luxon --- lib/util/date.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/lib/util/date.ts b/lib/util/date.ts index 809e4663316677..591e6967fc049b 100644 --- a/lib/util/date.ts +++ b/lib/util/date.ts @@ -1,3 +1,5 @@ +import { DateTime } from 'luxon'; + const ONE_MINUTE_MS = 60 * 1000; const ONE_DAY_MS = 24 * 60 * ONE_MINUTE_MS; @@ -12,10 +14,10 @@ export function getElapsedMinutes(date: Date): number { } export function getElapsedHours(time: Date | string): number { - const pastTime = typeof time === 'string' ? new Date(time) : time; - const currentTime = new Date(); - const millisecondsPerHour = 1000 * 60 * 60; - return Math.round( - (currentTime.getTime() - pastTime.getTime()) / millisecondsPerHour - ); + const pastTime = + typeof time === 'string' + ? DateTime.fromISO(time) + : DateTime.fromJSDate(time); + const diff = DateTime.now().diff(pastTime, 'hours'); + return diff.hours; } From b4baced08970a4a5a4fd5715ffc209396ccc3d98 Mon Sep 17 00:00:00 2001 From: RahulGautamSingh Date: Wed, 11 Jan 2023 19:48:30 +0530 Subject: [PATCH 20/48] update test --- .../repository/update/pr/index.spec.ts | 20 ++++++++++--------- lib/workers/repository/update/pr/index.ts | 7 ++++--- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/lib/workers/repository/update/pr/index.spec.ts b/lib/workers/repository/update/pr/index.spec.ts index beb7f97e03b7cd..3ef1cb4d371d5e 100644 --- a/lib/workers/repository/update/pr/index.spec.ts +++ b/lib/workers/repository/update/pr/index.spec.ts @@ -713,16 +713,18 @@ describe('workers/repository/update/pr/index', () => { let cachedPr: PrCache | null = null; it('creates new cache if not found', async () => { + config.repositoryCache = 'enabled'; platform.getBranchPr.mockResolvedValue(existingPr); prCache.getPrCache.mockReturnValueOnce(cachedPr); await ensurePr(config); expect(logger.logger.debug).toHaveBeenCalledWith( - 'Pr cache not found, creating new' + 'PR cache not found, creating new' ); expect(prCache.setPrCache).toHaveBeenCalled(); }); - it('logs for invalid cache', async () => { + it('fetches changelogs when pr cache does not match ', async () => { + config.repositoryCache = 'enabled'; platform.getBranchPr.mockResolvedValue(existingPr); cachedPr = { fingerprint: 'fingerprint', @@ -731,11 +733,12 @@ describe('workers/repository/update/pr/index', () => { prCache.getPrCache.mockReturnValueOnce(cachedPr); await ensurePr(config); expect(logger.logger.debug).toHaveBeenCalledWith( - 'Invaild cache, processing PR' + 'PR fingerprints mismatch, processing PR' ); }); - it('logs when pr cache is valid pr was edited within 24 hours', async () => { + it('fetches changelogs when pr cache matches but pr was edited within 24 hours', async () => { + config.repositoryCache = 'enabled'; platform.getBranchPr.mockResolvedValue(existingPr); cachedPr = { fingerprint: fingerprint(config), @@ -744,22 +747,21 @@ describe('workers/repository/update/pr/index', () => { prCache.getPrCache.mockReturnValueOnce(cachedPr); await ensurePr(config); expect(logger.logger.debug).toHaveBeenCalledWith( - 'Invaild cache, processing PR' + 'PR cache matches but it has been edited in the past 24hrs, so processing PR' ); }); it('skips fetching changelogs', async () => { + config.repositoryCache = 'enabled'; platform.getBranchPr.mockResolvedValue(existingPr); cachedPr = { fingerprint: fingerprint(config), - lastEdited: new Date( - new Date().getMilliseconds() - 25 * 60 * 60 * 1000 - ).toISOString(), + lastEdited: new Date('2020-01-20T00:00:00Z').toISOString(), }; prCache.getPrCache.mockReturnValueOnce(cachedPr); await ensurePr(config); expect(logger.logger.debug).toHaveBeenCalledWith( - 'Cache is valid, skipping PR update' + 'PR cache matches and no PR changes in last 24hrs, so skipping PR body check' ); expect(embedChangelog).toHaveBeenCalledTimes(0); }); diff --git a/lib/workers/repository/update/pr/index.ts b/lib/workers/repository/update/pr/index.ts index ea25996b7c2c9b..b86596bf5c0159 100644 --- a/lib/workers/repository/update/pr/index.ts +++ b/lib/workers/repository/update/pr/index.ts @@ -80,12 +80,13 @@ export function updatePrDebugData( function validatePrCache(prCache: PrCache, prFingerprint: string): boolean { if (prCache.fingerprint !== prFingerprint) { logger.debug('PR fingerprints mismatch, processing PR'); - logger.debug({ prFingerprint }, 'prFingerprint'); return false; } if (getElapsedHours(prCache.lastEdited) < 24) { - logger.debug('Processing PR as it has been recently edited'); // edited within 24 hours + logger.debug( + 'PR cache matches but it has been edited in the past 24hrs, so processing PR' + ); return false; } @@ -117,7 +118,7 @@ export async function ensurePr( // return if pr cache is valid and pr was last edited before a day if (validatePrCache(prCache, prFingerprint)) { logger.debug( - 'PR cache matches, and no PR changes in last 24h, so skipping PR body check' + 'PR cache matches and no PR changes in last 24hrs, so skipping PR body check' ); return { type: 'with-pr', pr: existingPr }; } From 0de8553638b6612d483718ac540e883d9b8940f0 Mon Sep 17 00:00:00 2001 From: RahulGautamSingh Date: Thu, 12 Jan 2023 16:52:57 +0530 Subject: [PATCH 21/48] update logic - set prCache when fingerprints mismatch - log prCache not found only if cache is enabled --- lib/workers/repository/update/pr/index.ts | 16 +++++++++------ .../repository/update/pr/pr-fingerprint.ts | 20 +++++++++++++++++++ 2 files changed, 30 insertions(+), 6 deletions(-) create mode 100644 lib/workers/repository/update/pr/pr-fingerprint.ts diff --git a/lib/workers/repository/update/pr/index.ts b/lib/workers/repository/update/pr/index.ts index b86596bf5c0159..46f12c1fde97e2 100644 --- a/lib/workers/repository/update/pr/index.ts +++ b/lib/workers/repository/update/pr/index.ts @@ -77,9 +77,14 @@ export function updatePrDebugData( }; } -function validatePrCache(prCache: PrCache, prFingerprint: string): boolean { +function validatePrCache( + branchName: string, + prCache: PrCache, + prFingerprint: string +): boolean { if (prCache.fingerprint !== prFingerprint) { logger.debug('PR fingerprints mismatch, processing PR'); + setPrCache(branchName, prFingerprint); return false; } @@ -110,20 +115,19 @@ export async function ensurePr( config.dependencyDashboardChecks?.[config.branchName]; // Check if PR already exists const existingPr = await platform.getBranchPr(branchName); - if (existingPr && config.repositoryCache === 'enabled') { + if (existingPr) { logger.debug('Found existing PR'); const prCache = getPrCache(branchName); if (prCache) { logger.debug({ prCache }, 'Found existing PR cache'); - // return if pr cache is valid and pr was last edited before a day - if (validatePrCache(prCache, prFingerprint)) { + // return if pr cache is valid and pr was not changed in the past 24hrs + if (validatePrCache(branchName, prCache, prFingerprint)) { logger.debug( 'PR cache matches and no PR changes in last 24hrs, so skipping PR body check' ); return { type: 'with-pr', pr: existingPr }; } - setPrCache(branchName, prFingerprint); - } else { + } else if (config.repositoryCache === 'enabled') { logger.debug('PR cache not found, creating new'); setPrCache(branchName, prFingerprint); } diff --git a/lib/workers/repository/update/pr/pr-fingerprint.ts b/lib/workers/repository/update/pr/pr-fingerprint.ts new file mode 100644 index 00000000000000..5032fca2b38240 --- /dev/null +++ b/lib/workers/repository/update/pr/pr-fingerprint.ts @@ -0,0 +1,20 @@ +// import type { UpgradeFingerprintConfig } from '../../types'; + +// type PrFingerprintFields; + +export const upgradeFingerprintFields = [ + 'schedule', + 'automergeSchedule', + 'automerge', + 'rebaseWhen', + 'stopUpdating', + 'recreateClosed', + 'productLinks', // not too important + 'upgrades', // needs too filter this as well + 'timezone', + 'hasReleaseNotes', + 'updateType', + 'isPin', + 'prHeader', + 'prFooter', +]; From e275c6bef76bff90068d272ab3cf7297fcacdbb5 Mon Sep 17 00:00:00 2001 From: RahulGautamSingh Date: Thu, 12 Jan 2023 17:55:47 +0530 Subject: [PATCH 22/48] refactor: remove extra file --- .../repository/update/pr/pr-fingerprint.ts | 20 ------------------- 1 file changed, 20 deletions(-) delete mode 100644 lib/workers/repository/update/pr/pr-fingerprint.ts diff --git a/lib/workers/repository/update/pr/pr-fingerprint.ts b/lib/workers/repository/update/pr/pr-fingerprint.ts deleted file mode 100644 index 5032fca2b38240..00000000000000 --- a/lib/workers/repository/update/pr/pr-fingerprint.ts +++ /dev/null @@ -1,20 +0,0 @@ -// import type { UpgradeFingerprintConfig } from '../../types'; - -// type PrFingerprintFields; - -export const upgradeFingerprintFields = [ - 'schedule', - 'automergeSchedule', - 'automerge', - 'rebaseWhen', - 'stopUpdating', - 'recreateClosed', - 'productLinks', // not too important - 'upgrades', // needs too filter this as well - 'timezone', - 'hasReleaseNotes', - 'updateType', - 'isPin', - 'prHeader', - 'prFooter', -]; From 10bf02c5d6d24b6eeb0a2faaea0bebdb690239c6 Mon Sep 17 00:00:00 2001 From: RahulGautamSingh Date: Fri, 13 Jan 2023 19:56:55 +0530 Subject: [PATCH 23/48] apply suggestions --- lib/util/date.ts | 5 +++++ lib/workers/repository/update/pr/index.ts | 12 ++++-------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/lib/util/date.ts b/lib/util/date.ts index 591e6967fc049b..e18c7614befea4 100644 --- a/lib/util/date.ts +++ b/lib/util/date.ts @@ -18,6 +18,11 @@ export function getElapsedHours(time: Date | string): number { typeof time === 'string' ? DateTime.fromISO(time) : DateTime.fromJSDate(time); + + if (!pastTime.isValid) { + return 0; + } + const diff = DateTime.now().diff(pastTime, 'hours'); return diff.hours; } diff --git a/lib/workers/repository/update/pr/index.ts b/lib/workers/repository/update/pr/index.ts index 46f12c1fde97e2..2bc63d28503842 100644 --- a/lib/workers/repository/update/pr/index.ts +++ b/lib/workers/repository/update/pr/index.ts @@ -77,14 +77,9 @@ export function updatePrDebugData( }; } -function validatePrCache( - branchName: string, - prCache: PrCache, - prFingerprint: string -): boolean { +function validatePrCache(prCache: PrCache, prFingerprint: string): boolean { if (prCache.fingerprint !== prFingerprint) { logger.debug('PR fingerprints mismatch, processing PR'); - setPrCache(branchName, prFingerprint); return false; } @@ -119,9 +114,9 @@ export async function ensurePr( logger.debug('Found existing PR'); const prCache = getPrCache(branchName); if (prCache) { - logger.debug({ prCache }, 'Found existing PR cache'); + logger.trace({ prCache }, 'Found existing PR cache'); // return if pr cache is valid and pr was not changed in the past 24hrs - if (validatePrCache(branchName, prCache, prFingerprint)) { + if (validatePrCache(prCache, prFingerprint)) { logger.debug( 'PR cache matches and no PR changes in last 24hrs, so skipping PR body check' ); @@ -363,6 +358,7 @@ export async function ensurePr( }); logger.info({ pr: existingPr.number, prTitle }, `PR updated`); } + setPrCache(branchName, prFingerprint); return { type: 'with-pr', pr: existingPr }; } logger.debug({ branch: branchName, prTitle }, `Creating PR`); From 4ee9e564ed7c756a844e4ec2001f23f2cafa562a Mon Sep 17 00:00:00 2001 From: RahulGautamSingh Date: Sat, 14 Jan 2023 06:27:30 +0530 Subject: [PATCH 24/48] filter config --- lib/workers/repository/update/pr/index.ts | 38 +++++++++++++++++- .../repository/update/pr/pr-fingerprint.ts | 40 +++++++++++++++++++ 2 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 lib/workers/repository/update/pr/pr-fingerprint.ts diff --git a/lib/workers/repository/update/pr/index.ts b/lib/workers/repository/update/pr/index.ts index 2bc63d28503842..86605a30f1146a 100644 --- a/lib/workers/repository/update/pr/index.ts +++ b/lib/workers/repository/update/pr/index.ts @@ -34,6 +34,7 @@ import { resolveBranchStatus } from '../branch/status-checks'; import { getPrBody } from './body'; import { prepareLabels } from './labels'; import { addParticipants } from './participants'; +import type { prFingerprintConfig } from './pr-fingerprint'; import { getPrCache, setPrCache } from './set-pr-cache'; export function getPlatformPrOptions( @@ -93,6 +94,41 @@ function validatePrCache(prCache: PrCache, prFingerprint: string): boolean { return true; } +function generatePrFingerprintConfig( + config: BranchConfig +): prFingerprintConfig { + const filteredUpgrades = config.upgrades.map((upgrade) => { + return { + prBodyDefinitions: upgrade.prBodyDefinitions, + prBodyNotes: upgrade.prBodyNotes, + gitRef: upgrade.gitRef, + repoName: upgrade.repoName, + depName: upgrade.depName, + hasReleaseNotes: upgrade.hasReleaseNotes, + }; + }); + + return { + pkgVersion: pkg.version, + prTitle: config.prTitle, + prHeader: config.prHeader, + prFooter: config.prFooter, + warnings: config.warnings, + updateType: config.updateType, + isPin: config.isPin, + hasReleaseNotes: config.hasReleaseNotes, + schedule: config.schedule, + automergeSchedule: config.automergeSchedule, + automerge: config.automerge, + timezone: config.timezone, + recreateClosed: config.recreateClosed, + rebaseWhen: config.rebaseWhen, + stopUpdating: config.stopUpdating, + prBodyTemplate: config.prBodyTemplate, + filteredUpgrades, + }; +} + // Ensures that PR exists with matching title/body export async function ensurePr( prConfig: BranchConfig @@ -102,7 +138,7 @@ export async function ensurePr( ); const config: BranchConfig = { ...prConfig }; - const prFingerprint = fingerprint(config); + const prFingerprint = fingerprint(generatePrFingerprintConfig(config)); logger.trace({ config }, 'ensurePr'); // If there is a group, it will use the config of the first upgrade in the array const { branchName, ignoreTests, prTitle = '', upgrades } = config; diff --git a/lib/workers/repository/update/pr/pr-fingerprint.ts b/lib/workers/repository/update/pr/pr-fingerprint.ts new file mode 100644 index 00000000000000..42945183eb701a --- /dev/null +++ b/lib/workers/repository/update/pr/pr-fingerprint.ts @@ -0,0 +1,40 @@ +// fingerprint config is based on the this logic here +// https://github.com/renovatebot/renovate/blob/3d85b6048d6a8c57887b64ed4929e2e02ea41aa0/lib/workers/repository/update/pr/index.ts#L294-L306 + +import type { UpdateType, ValidationMessage } from '../../../../config/types'; + +// it has 3 parts the RenovateVersion, config fields and fields from config.upgrades + +// BranchUpgradeConfig - filtered +interface FilteredBranchUpgradeConfig { + prBodyDefinitions?: Record; + prBodyNotes?: string[]; + gitRef?: boolean; + repoName?: string; + depName?: string; + hasReleaseNotes?: boolean; +} + +export interface prFingerprintConfig { + // Renovate Version + pkgVersion: string; + + // BranchConfig - filtered + prTitle?: string; + prHeader?: string; + prFooter?: string; + warnings?: ValidationMessage[]; + updateType?: UpdateType; + isPin?: boolean; + hasReleaseNotes?: boolean; + schedule?: string[]; + automergeSchedule?: string[]; + automerge?: boolean; + timezone?: string; + recreateClosed?: boolean; + rebaseWhen?: string; + stopUpdating?: boolean; + prBodyTemplate?: string; + + filteredUpgrades?: FilteredBranchUpgradeConfig[]; +} From d507a5fd36f1d378d4023ae740548523882cee5e Mon Sep 17 00:00:00 2001 From: RahulGautamSingh Date: Sat, 14 Jan 2023 19:20:44 +0530 Subject: [PATCH 25/48] update tests --- .../repository/update/pr/index.spec.ts | 20 ++++++++++++++++--- lib/workers/repository/update/pr/index.ts | 2 +- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/lib/workers/repository/update/pr/index.spec.ts b/lib/workers/repository/update/pr/index.spec.ts index 3ef1cb4d371d5e..6707149f3d3a9a 100644 --- a/lib/workers/repository/update/pr/index.spec.ts +++ b/lib/workers/repository/update/pr/index.spec.ts @@ -20,7 +20,7 @@ import * as _prBody from './body'; import type { ChangeLogChange, ChangeLogRelease } from './changelog/types'; import * as _participants from './participants'; import * as _prCache from './set-pr-cache'; -import { ensurePr } from '.'; +import { ensurePr, generatePrFingerprintConfig } from '.'; jest.mock('../../../../util/git'); jest.mock('../../changelog'); @@ -741,7 +741,7 @@ describe('workers/repository/update/pr/index', () => { config.repositoryCache = 'enabled'; platform.getBranchPr.mockResolvedValue(existingPr); cachedPr = { - fingerprint: fingerprint(config), + fingerprint: fingerprint(generatePrFingerprintConfig(config)), lastEdited: new Date().toISOString(), }; prCache.getPrCache.mockReturnValueOnce(cachedPr); @@ -751,11 +751,25 @@ describe('workers/repository/update/pr/index', () => { ); }); + it('fetches changelogs when pr cache matches but lastEdited date string is invalid', async () => { + config.repositoryCache = 'enabled'; + platform.getBranchPr.mockResolvedValue(existingPr); + cachedPr = { + fingerprint: fingerprint(generatePrFingerprintConfig(config)), + lastEdited: 'invalid string', + }; + prCache.getPrCache.mockReturnValueOnce(cachedPr); + await ensurePr(config); + expect(logger.logger.debug).toHaveBeenCalledWith( + 'PR cache matches but it has been edited in the past 24hrs, so processing PR' + ); + }); + it('skips fetching changelogs', async () => { config.repositoryCache = 'enabled'; platform.getBranchPr.mockResolvedValue(existingPr); cachedPr = { - fingerprint: fingerprint(config), + fingerprint: fingerprint(generatePrFingerprintConfig(config)), lastEdited: new Date('2020-01-20T00:00:00Z').toISOString(), }; prCache.getPrCache.mockReturnValueOnce(cachedPr); diff --git a/lib/workers/repository/update/pr/index.ts b/lib/workers/repository/update/pr/index.ts index 86605a30f1146a..1c0ee3f22ee0f0 100644 --- a/lib/workers/repository/update/pr/index.ts +++ b/lib/workers/repository/update/pr/index.ts @@ -94,7 +94,7 @@ function validatePrCache(prCache: PrCache, prFingerprint: string): boolean { return true; } -function generatePrFingerprintConfig( +export function generatePrFingerprintConfig( config: BranchConfig ): prFingerprintConfig { const filteredUpgrades = config.upgrades.map((upgrade) => { From 37de2d95250de5de37f46e7ce7d53cda1e554b63 Mon Sep 17 00:00:00 2001 From: RahulGautamSingh Date: Sat, 14 Jan 2023 20:20:58 +0530 Subject: [PATCH 26/48] refactor --- lib/workers/repository/cache.ts | 2 +- .../repository/update/pr/index.spec.ts | 1 - lib/workers/repository/update/pr/index.ts | 45 ++++++++++--------- .../repository/update/pr/pr-fingerprint.ts | 36 +++++++-------- 4 files changed, 42 insertions(+), 42 deletions(-) diff --git a/lib/workers/repository/cache.ts b/lib/workers/repository/cache.ts index ef5212d79f4b2a..7654f2d6408852 100644 --- a/lib/workers/repository/cache.ts +++ b/lib/workers/repository/cache.ts @@ -84,10 +84,10 @@ async function generateBranchCache( isConflicted, isModified, pristine, + prCache, prNo, sha, upgrades, - prCache, }; } catch (error) { const err = error.err || error; // external host error nests err diff --git a/lib/workers/repository/update/pr/index.spec.ts b/lib/workers/repository/update/pr/index.spec.ts index 6707149f3d3a9a..5ffdc82f5fd870 100644 --- a/lib/workers/repository/update/pr/index.spec.ts +++ b/lib/workers/repository/update/pr/index.spec.ts @@ -71,7 +71,6 @@ describe('workers/repository/update/pr/index', () => { jest.resetAllMocks(); GlobalConfig.reset(); prBody.getPrBody.mockReturnValue(body); - git.isCloned.mockReturnValueOnce(false); }); describe('Create', () => { diff --git a/lib/workers/repository/update/pr/index.ts b/lib/workers/repository/update/pr/index.ts index 1c0ee3f22ee0f0..d40d5e124c0f4c 100644 --- a/lib/workers/repository/update/pr/index.ts +++ b/lib/workers/repository/update/pr/index.ts @@ -34,7 +34,7 @@ import { resolveBranchStatus } from '../branch/status-checks'; import { getPrBody } from './body'; import { prepareLabels } from './labels'; import { addParticipants } from './participants'; -import type { prFingerprintConfig } from './pr-fingerprint'; +import type { PrFingerprintConfig } from './pr-fingerprint'; import { getPrCache, setPrCache } from './set-pr-cache'; export function getPlatformPrOptions( @@ -96,36 +96,36 @@ function validatePrCache(prCache: PrCache, prFingerprint: string): boolean { export function generatePrFingerprintConfig( config: BranchConfig -): prFingerprintConfig { +): PrFingerprintConfig { const filteredUpgrades = config.upgrades.map((upgrade) => { return { + depName: upgrade.depName, + gitRef: upgrade.gitRef, + hasReleaseNotes: upgrade.hasReleaseNotes, prBodyDefinitions: upgrade.prBodyDefinitions, prBodyNotes: upgrade.prBodyNotes, - gitRef: upgrade.gitRef, repoName: upgrade.repoName, - depName: upgrade.depName, - hasReleaseNotes: upgrade.hasReleaseNotes, }; }); return { + automerge: config.automerge, + automergeSchedule: config.automergeSchedule, + filteredUpgrades, + hasReleaseNotes: config.hasReleaseNotes, + isPin: config.isPin, pkgVersion: pkg.version, - prTitle: config.prTitle, - prHeader: config.prHeader, + prBodyTemplate: config.prBodyTemplate, prFooter: config.prFooter, - warnings: config.warnings, - updateType: config.updateType, - isPin: config.isPin, - hasReleaseNotes: config.hasReleaseNotes, - schedule: config.schedule, - automergeSchedule: config.automergeSchedule, - automerge: config.automerge, - timezone: config.timezone, - recreateClosed: config.recreateClosed, + prHeader: config.prHeader, + prTitle: config.prTitle, rebaseWhen: config.rebaseWhen, + recreateClosed: config.recreateClosed, + schedule: config.schedule, stopUpdating: config.stopUpdating, - prBodyTemplate: config.prBodyTemplate, - filteredUpgrades, + timezone: config.timezone, + updateType: config.updateType, + warnings: config.warnings, }; } @@ -138,7 +138,8 @@ export async function ensurePr( ); const config: BranchConfig = { ...prConfig }; - const prFingerprint = fingerprint(generatePrFingerprintConfig(config)); + const filteredPrConfig = generatePrFingerprintConfig(config); + const prFingerprint = fingerprint(filteredPrConfig); logger.trace({ config }, 'ensurePr'); // If there is a group, it will use the config of the first upgrade in the array const { branchName, ignoreTests, prTitle = '', upgrades } = config; @@ -158,8 +159,10 @@ export async function ensurePr( ); return { type: 'with-pr', pr: existingPr }; } - } else if (config.repositoryCache === 'enabled') { - logger.debug('PR cache not found, creating new'); + } else { + if (config.repositoryCache === 'enabled') { + logger.debug('PR cache not found, creating new'); + } setPrCache(branchName, prFingerprint); } } diff --git a/lib/workers/repository/update/pr/pr-fingerprint.ts b/lib/workers/repository/update/pr/pr-fingerprint.ts index 42945183eb701a..dbf3f12578ac2d 100644 --- a/lib/workers/repository/update/pr/pr-fingerprint.ts +++ b/lib/workers/repository/update/pr/pr-fingerprint.ts @@ -1,40 +1,38 @@ -// fingerprint config is based on the this logic here +// fingerprint config is based on the old skip pr update logic // https://github.com/renovatebot/renovate/blob/3d85b6048d6a8c57887b64ed4929e2e02ea41aa0/lib/workers/repository/update/pr/index.ts#L294-L306 import type { UpdateType, ValidationMessage } from '../../../../config/types'; -// it has 3 parts the RenovateVersion, config fields and fields from config.upgrades - // BranchUpgradeConfig - filtered interface FilteredBranchUpgradeConfig { + depName?: string; + gitRef?: boolean; + hasReleaseNotes?: boolean; prBodyDefinitions?: Record; prBodyNotes?: string[]; - gitRef?: boolean; repoName?: string; - depName?: string; - hasReleaseNotes?: boolean; } -export interface prFingerprintConfig { +export interface PrFingerprintConfig { // Renovate Version pkgVersion: string; // BranchConfig - filtered - prTitle?: string; - prHeader?: string; - prFooter?: string; - warnings?: ValidationMessage[]; - updateType?: UpdateType; - isPin?: boolean; - hasReleaseNotes?: boolean; - schedule?: string[]; - automergeSchedule?: string[]; automerge?: boolean; - timezone?: string; - recreateClosed?: boolean; + automergeSchedule?: string[]; + hasReleaseNotes?: boolean; + isPin?: boolean; + prBodyTemplate?: string; + prFooter?: string; + prHeader?: string; + prTitle?: string; rebaseWhen?: string; + recreateClosed?: boolean; + schedule?: string[]; stopUpdating?: boolean; - prBodyTemplate?: string; + timezone?: string; + updateType?: UpdateType; + warnings?: ValidationMessage[]; filteredUpgrades?: FilteredBranchUpgradeConfig[]; } From 58c8b3819c018d0f8a032e02ac72cfa390881b55 Mon Sep 17 00:00:00 2001 From: RahulGautamSingh Date: Wed, 18 Jan 2023 08:55:40 +0530 Subject: [PATCH 27/48] rename files --- .../repository/update/pr/set-pr-cache.spec.ts | 77 ------------------- .../repository/update/pr/set-pr-cache.ts | 36 --------- 2 files changed, 113 deletions(-) delete mode 100644 lib/workers/repository/update/pr/set-pr-cache.spec.ts delete mode 100644 lib/workers/repository/update/pr/set-pr-cache.ts diff --git a/lib/workers/repository/update/pr/set-pr-cache.spec.ts b/lib/workers/repository/update/pr/set-pr-cache.spec.ts deleted file mode 100644 index e86594d2d71841..00000000000000 --- a/lib/workers/repository/update/pr/set-pr-cache.spec.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { logger, mocked } from '../../../../../test/util'; -import * as _cache from '../../../../util/cache/repository'; -import type { - BranchCache, - RepoCacheData, -} from '../../../../util/cache/repository/types'; -import { getPrCache, setPrCache } from './set-pr-cache'; - -jest.mock('../../../../util/cache/repository'); -const cache = mocked(_cache); - -describe('workers/repository/update/pr/set-pr-cache', () => { - const branchCache: BranchCache = { - automerge: false, - baseBranch: 'base_branch', - baseBranchSha: 'base_sha', - branchName: 'branch_name', - prNo: null, - sha: 'sha', - upgrades: [], - prCache: null, - }; - const dummyCache: RepoCacheData = { - branches: [branchCache], - }; - - describe('getPrCache()', () => { - it('return null if cache is empty', () => { - cache.getCache.mockReturnValue({}); - expect(getPrCache('branch_name')).toBeNull(); - }); - - it('return null if prCache is falsy', () => { - cache.getCache.mockReturnValue(dummyCache); - expect(getPrCache('branch_name')).toBeNull(); - }); - - it('returns prCache', () => { - branchCache.prCache = { - fingerprint: 'fp', - lastEdited: new Date('11/11/2011').toISOString(), - }; - cache.getCache.mockReturnValue(dummyCache); - expect(getPrCache('branch_name')).toStrictEqual({ - fingerprint: 'fp', - lastEdited: new Date('11/11/2011').toISOString(), - }); - }); - }); - - describe('setPrCache()', () => { - it('logs if branch not found', () => { - cache.getCache.mockReturnValue(dummyCache); - setPrCache('branch_1', 'fingerprint_hash'); - expect(logger.logger.debug).toHaveBeenCalledWith( - 'setPrCache(): Branch cache not present' - ); - }); - - it('set prCache', () => { - cache.getCache.mockReturnValue(dummyCache); - jest.useFakeTimers().setSystemTime(new Date('2020-01-01')); - setPrCache('branch_name', 'fingerprint_hash'); - expect(dummyCache).toStrictEqual({ - branches: [ - { - ...branchCache, - prCache: { - fingerprint: 'fingerprint_hash', - lastEdited: new Date('2020-01-01').toISOString(), - }, - }, - ], - }); - }); - }); -}); diff --git a/lib/workers/repository/update/pr/set-pr-cache.ts b/lib/workers/repository/update/pr/set-pr-cache.ts deleted file mode 100644 index 989a2cd46fc3f8..00000000000000 --- a/lib/workers/repository/update/pr/set-pr-cache.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { logger } from '../../../../logger'; -import { getCache } from '../../../../util/cache/repository'; -import type { PrCache } from '../../../../util/cache/repository/types'; - -export function getPrCache(branchName: string): PrCache | null { - logger.debug(`getPrCache()`); - const cache = getCache(); - const branch = cache.branches?.find( - (branch) => branchName === branch.branchName - ); - - if (branch?.prCache) { - return branch.prCache; - } - - return null; -} - -// store the time a PR was last updated -export function setPrCache(branchName: string, fingerprint: string): void { - logger.debug(`setPrCache()`); - const cache = getCache(); - const branch = cache.branches?.find( - (branch) => branchName === branch.branchName - ); - - if (!branch) { - logger.debug(`setPrCache(): Branch cache not present`); - return; - } - - branch.prCache = { - fingerprint, - lastEdited: new Date().toISOString(), - }; -} From 923d9a2fe7be1177a76b47f5f6c4c33af01a1f93 Mon Sep 17 00:00:00 2001 From: RahulGautamSingh Date: Wed, 18 Jan 2023 08:56:27 +0530 Subject: [PATCH 28/48] move fingerprint logic to pr-fingerprint.ts --- lib/workers/repository/cache.ts | 2 +- .../repository/update/pr/pr-cache.spec.ts | 77 +++++++++++++++++++ lib/workers/repository/update/pr/pr-cache.ts | 36 +++++++++ .../repository/update/pr/pr-fingerprint.ts | 59 ++++++++++++++ 4 files changed, 173 insertions(+), 1 deletion(-) create mode 100644 lib/workers/repository/update/pr/pr-cache.spec.ts create mode 100644 lib/workers/repository/update/pr/pr-cache.ts diff --git a/lib/workers/repository/cache.ts b/lib/workers/repository/cache.ts index 7654f2d6408852..7d951f9f76e56b 100644 --- a/lib/workers/repository/cache.ts +++ b/lib/workers/repository/cache.ts @@ -15,7 +15,7 @@ import { } from '../../util/git'; import { getCachedPristineResult } from '../../util/git/pristine'; import type { BranchConfig, BranchUpgradeConfig } from '../types'; -import { getPrCache } from './update/pr/set-pr-cache'; +import { getPrCache } from './update/pr/pr-cache'; function generateBranchUpgradeCache( upgrade: BranchUpgradeConfig diff --git a/lib/workers/repository/update/pr/pr-cache.spec.ts b/lib/workers/repository/update/pr/pr-cache.spec.ts new file mode 100644 index 00000000000000..d55fa886cd01c3 --- /dev/null +++ b/lib/workers/repository/update/pr/pr-cache.spec.ts @@ -0,0 +1,77 @@ +import { logger, mocked } from '../../../../../test/util'; +import * as _cache from '../../../../util/cache/repository'; +import type { + BranchCache, + RepoCacheData, +} from '../../../../util/cache/repository/types'; +import { getPrCache, setPrCache } from './pr-cache'; + +jest.mock('../../../../util/cache/repository'); +const cache = mocked(_cache); + +describe('workers/repository/update/pr/pr-cache', () => { + const branchCache: BranchCache = { + automerge: false, + baseBranch: 'base_branch', + baseBranchSha: 'base_sha', + branchName: 'branch_name', + prNo: null, + sha: 'sha', + upgrades: [], + prCache: null, + }; + const dummyCache: RepoCacheData = { + branches: [branchCache], + }; + + describe('getPrCache()', () => { + it('return null if cache is empty', () => { + cache.getCache.mockReturnValue({}); + expect(getPrCache('branch_name')).toBeNull(); + }); + + it('return null if prCache is falsy', () => { + cache.getCache.mockReturnValue(dummyCache); + expect(getPrCache('branch_name')).toBeNull(); + }); + + it('returns prCache', () => { + branchCache.prCache = { + fingerprint: 'fp', + lastEdited: new Date('11/11/2011').toISOString(), + }; + cache.getCache.mockReturnValue(dummyCache); + expect(getPrCache('branch_name')).toStrictEqual({ + fingerprint: 'fp', + lastEdited: new Date('11/11/2011').toISOString(), + }); + }); + }); + + describe('setPrCache()', () => { + it('logs if branch not found', () => { + cache.getCache.mockReturnValue(dummyCache); + setPrCache('branch_1', 'fingerprint_hash'); + expect(logger.logger.debug).toHaveBeenCalledWith( + 'setPrCache(): Branch cache not present' + ); + }); + + it('set prCache', () => { + cache.getCache.mockReturnValue(dummyCache); + jest.useFakeTimers().setSystemTime(new Date('2020-01-01')); + setPrCache('branch_name', 'fingerprint_hash'); + expect(dummyCache).toStrictEqual({ + branches: [ + { + ...branchCache, + prCache: { + fingerprint: 'fingerprint_hash', + lastEdited: new Date('2020-01-01').toISOString(), + }, + }, + ], + }); + }); + }); +}); diff --git a/lib/workers/repository/update/pr/pr-cache.ts b/lib/workers/repository/update/pr/pr-cache.ts new file mode 100644 index 00000000000000..989a2cd46fc3f8 --- /dev/null +++ b/lib/workers/repository/update/pr/pr-cache.ts @@ -0,0 +1,36 @@ +import { logger } from '../../../../logger'; +import { getCache } from '../../../../util/cache/repository'; +import type { PrCache } from '../../../../util/cache/repository/types'; + +export function getPrCache(branchName: string): PrCache | null { + logger.debug(`getPrCache()`); + const cache = getCache(); + const branch = cache.branches?.find( + (branch) => branchName === branch.branchName + ); + + if (branch?.prCache) { + return branch.prCache; + } + + return null; +} + +// store the time a PR was last updated +export function setPrCache(branchName: string, fingerprint: string): void { + logger.debug(`setPrCache()`); + const cache = getCache(); + const branch = cache.branches?.find( + (branch) => branchName === branch.branchName + ); + + if (!branch) { + logger.debug(`setPrCache(): Branch cache not present`); + return; + } + + branch.prCache = { + fingerprint, + lastEdited: new Date().toISOString(), + }; +} diff --git a/lib/workers/repository/update/pr/pr-fingerprint.ts b/lib/workers/repository/update/pr/pr-fingerprint.ts index dbf3f12578ac2d..60d4b1264d88b4 100644 --- a/lib/workers/repository/update/pr/pr-fingerprint.ts +++ b/lib/workers/repository/update/pr/pr-fingerprint.ts @@ -2,6 +2,11 @@ // https://github.com/renovatebot/renovate/blob/3d85b6048d6a8c57887b64ed4929e2e02ea41aa0/lib/workers/repository/update/pr/index.ts#L294-L306 import type { UpdateType, ValidationMessage } from '../../../../config/types'; +import { pkg } from '../../../../expose.cjs'; +import { logger } from '../../../../logger'; +import type { PrCache } from '../../../../util/cache/repository/types'; +import { getElapsedHours } from '../../../../util/date'; +import type { BranchConfig } from '../../../types'; // BranchUpgradeConfig - filtered interface FilteredBranchUpgradeConfig { @@ -36,3 +41,57 @@ export interface PrFingerprintConfig { filteredUpgrades?: FilteredBranchUpgradeConfig[]; } + +export function generatePrFingerprintConfig( + config: BranchConfig +): PrFingerprintConfig { + const filteredUpgrades = config.upgrades.map((upgrade) => { + return { + depName: upgrade.depName, + gitRef: upgrade.gitRef, + hasReleaseNotes: upgrade.hasReleaseNotes, + prBodyDefinitions: upgrade.prBodyDefinitions, + prBodyNotes: upgrade.prBodyNotes, + repoName: upgrade.repoName, + }; + }); + + return { + automerge: config.automerge, + automergeSchedule: config.automergeSchedule, + filteredUpgrades, + hasReleaseNotes: config.hasReleaseNotes, + isPin: config.isPin, + pkgVersion: pkg.version, + prBodyTemplate: config.prBodyTemplate, + prFooter: config.prFooter, + prHeader: config.prHeader, + prTitle: config.prTitle, + rebaseWhen: config.rebaseWhen, + recreateClosed: config.recreateClosed, + schedule: config.schedule, + stopUpdating: config.stopUpdating, + timezone: config.timezone, + updateType: config.updateType, + warnings: config.warnings, + }; +} + +export function validatePrCache( + prCache: PrCache, + prFingerprint: string +): boolean { + if (prCache.fingerprint !== prFingerprint) { + logger.debug('PR fingerprints mismatch, processing PR'); + return false; + } + + if (getElapsedHours(prCache.lastEdited) < 24) { + logger.debug( + 'PR cache matches but it has been edited in the past 24hrs, so processing PR' + ); + return false; + } + + return true; +} From f0e45718313b8578952f347d3bcad61307c5b4ea Mon Sep 17 00:00:00 2001 From: RahulGautamSingh Date: Wed, 18 Jan 2023 08:59:10 +0530 Subject: [PATCH 29/48] update set pr-cache logic --- .../repository/update/pr/index.spec.ts | 18 ++--- lib/workers/repository/update/pr/index.ts | 65 ++----------------- 2 files changed, 10 insertions(+), 73 deletions(-) diff --git a/lib/workers/repository/update/pr/index.spec.ts b/lib/workers/repository/update/pr/index.spec.ts index 5ffdc82f5fd870..27dea4afc9d8cd 100644 --- a/lib/workers/repository/update/pr/index.spec.ts +++ b/lib/workers/repository/update/pr/index.spec.ts @@ -19,8 +19,9 @@ import * as _statusChecks from '../branch/status-checks'; import * as _prBody from './body'; import type { ChangeLogChange, ChangeLogRelease } from './changelog/types'; import * as _participants from './participants'; -import * as _prCache from './set-pr-cache'; -import { ensurePr, generatePrFingerprintConfig } from '.'; +import * as _prCache from './pr-cache'; +import { generatePrFingerprintConfig } from './pr-fingerprint'; +import { ensurePr } from '.'; jest.mock('../../../../util/git'); jest.mock('../../changelog'); @@ -40,7 +41,7 @@ const participants = mocked(_participants); jest.mock('../../../../modules/platform/comment'); const comment = mocked(_comment); -jest.mock('./set-pr-cache'); +jest.mock('./pr-cache'); const prCache = mocked(_prCache); describe('workers/repository/update/pr/index', () => { @@ -711,17 +712,6 @@ describe('workers/repository/update/pr/index', () => { }; let cachedPr: PrCache | null = null; - it('creates new cache if not found', async () => { - config.repositoryCache = 'enabled'; - platform.getBranchPr.mockResolvedValue(existingPr); - prCache.getPrCache.mockReturnValueOnce(cachedPr); - await ensurePr(config); - expect(logger.logger.debug).toHaveBeenCalledWith( - 'PR cache not found, creating new' - ); - expect(prCache.setPrCache).toHaveBeenCalled(); - }); - it('fetches changelogs when pr cache does not match ', async () => { config.repositoryCache = 'enabled'; platform.getBranchPr.mockResolvedValue(existingPr); diff --git a/lib/workers/repository/update/pr/index.ts b/lib/workers/repository/update/pr/index.ts index d40d5e124c0f4c..d7fae25c861649 100644 --- a/lib/workers/repository/update/pr/index.ts +++ b/lib/workers/repository/update/pr/index.ts @@ -17,7 +17,6 @@ import { import { ensureComment } from '../../../../modules/platform/comment'; import { hashBody } from '../../../../modules/platform/pr-body'; import { ExternalHostError } from '../../../../types/errors/external-host-error'; -import type { PrCache } from '../../../../util/cache/repository/types'; import { getElapsedHours } from '../../../../util/date'; import { stripEmojis } from '../../../../util/emoji'; import { fingerprint } from '../../../../util/fingerprint'; @@ -34,8 +33,8 @@ import { resolveBranchStatus } from '../branch/status-checks'; import { getPrBody } from './body'; import { prepareLabels } from './labels'; import { addParticipants } from './participants'; -import type { PrFingerprintConfig } from './pr-fingerprint'; -import { getPrCache, setPrCache } from './set-pr-cache'; +import { getPrCache, setPrCache } from './pr-cache'; +import { generatePrFingerprintConfig, validatePrCache } from './pr-fingerprint'; export function getPlatformPrOptions( config: RenovateConfig & PlatformPrOptions @@ -78,57 +77,6 @@ export function updatePrDebugData( }; } -function validatePrCache(prCache: PrCache, prFingerprint: string): boolean { - if (prCache.fingerprint !== prFingerprint) { - logger.debug('PR fingerprints mismatch, processing PR'); - return false; - } - - if (getElapsedHours(prCache.lastEdited) < 24) { - logger.debug( - 'PR cache matches but it has been edited in the past 24hrs, so processing PR' - ); - return false; - } - - return true; -} - -export function generatePrFingerprintConfig( - config: BranchConfig -): PrFingerprintConfig { - const filteredUpgrades = config.upgrades.map((upgrade) => { - return { - depName: upgrade.depName, - gitRef: upgrade.gitRef, - hasReleaseNotes: upgrade.hasReleaseNotes, - prBodyDefinitions: upgrade.prBodyDefinitions, - prBodyNotes: upgrade.prBodyNotes, - repoName: upgrade.repoName, - }; - }); - - return { - automerge: config.automerge, - automergeSchedule: config.automergeSchedule, - filteredUpgrades, - hasReleaseNotes: config.hasReleaseNotes, - isPin: config.isPin, - pkgVersion: pkg.version, - prBodyTemplate: config.prBodyTemplate, - prFooter: config.prFooter, - prHeader: config.prHeader, - prTitle: config.prTitle, - rebaseWhen: config.rebaseWhen, - recreateClosed: config.recreateClosed, - schedule: config.schedule, - stopUpdating: config.stopUpdating, - timezone: config.timezone, - updateType: config.updateType, - warnings: config.warnings, - }; -} - // Ensures that PR exists with matching title/body export async function ensurePr( prConfig: BranchConfig @@ -159,11 +107,8 @@ export async function ensurePr( ); return { type: 'with-pr', pr: existingPr }; } - } else { - if (config.repositoryCache === 'enabled') { - logger.debug('PR cache not found, creating new'); - } - setPrCache(branchName, prFingerprint); + } else if (config.repositoryCache === 'enabled') { + logger.debug('PR cache not found, creating new'); } } config.upgrades = []; @@ -510,3 +455,5 @@ export async function ensurePr( } return { type: 'without-pr', prBlockedBy: 'Error' }; } + +export { generatePrFingerprintConfig }; From a3edb546067324af184c7de1775c92aec7d62222 Mon Sep 17 00:00:00 2001 From: RahulGautamSingh Date: Wed, 18 Jan 2023 13:45:12 +0530 Subject: [PATCH 30/48] fix coverage --- lib/workers/repository/update/pr/index.spec.ts | 8 ++++++++ lib/workers/repository/update/pr/index.ts | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/workers/repository/update/pr/index.spec.ts b/lib/workers/repository/update/pr/index.spec.ts index 27dea4afc9d8cd..07515a566a3ccc 100644 --- a/lib/workers/repository/update/pr/index.spec.ts +++ b/lib/workers/repository/update/pr/index.spec.ts @@ -712,6 +712,14 @@ describe('workers/repository/update/pr/index', () => { }; let cachedPr: PrCache | null = null; + it('logs when cache is enabled but pr-cache is absent', async () => { + config.repositoryCache = 'enabled'; + platform.getBranchPr.mockResolvedValue(existingPr); + prCache.getPrCache.mockReturnValueOnce(null); + await ensurePr(config); + expect(logger.logger.debug).toHaveBeenCalledWith('PR cache not found'); + }); + it('fetches changelogs when pr cache does not match ', async () => { config.repositoryCache = 'enabled'; platform.getBranchPr.mockResolvedValue(existingPr); diff --git a/lib/workers/repository/update/pr/index.ts b/lib/workers/repository/update/pr/index.ts index d7fae25c861649..4371c9a5b78ca5 100644 --- a/lib/workers/repository/update/pr/index.ts +++ b/lib/workers/repository/update/pr/index.ts @@ -108,7 +108,7 @@ export async function ensurePr( return { type: 'with-pr', pr: existingPr }; } } else if (config.repositoryCache === 'enabled') { - logger.debug('PR cache not found, creating new'); + logger.debug('PR cache not found'); } } config.upgrades = []; From 5a37612a70dfe565b0dc8ecfda68839af9b5f739 Mon Sep 17 00:00:00 2001 From: RahulGautamSingh Date: Fri, 20 Jan 2023 14:54:49 +0530 Subject: [PATCH 31/48] fix: update pr cache if pr not updated --- lib/workers/repository/update/pr/index.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/workers/repository/update/pr/index.ts b/lib/workers/repository/update/pr/index.ts index 4371c9a5b78ca5..3ba745e8af49a9 100644 --- a/lib/workers/repository/update/pr/index.ts +++ b/lib/workers/repository/update/pr/index.ts @@ -311,6 +311,7 @@ export async function ensurePr( ) { // TODO: types (#7154) logger.debug(`${existingPr.displayNumber!} does not need updating`); + setPrCache(branchName, prFingerprint); return { type: 'with-pr', pr: existingPr }; } // PR must need updating @@ -455,5 +456,3 @@ export async function ensurePr( } return { type: 'without-pr', prBlockedBy: 'Error' }; } - -export { generatePrFingerprintConfig }; From c9a02caa1bfad25a4a367cddb3bf9a49f9ff38e1 Mon Sep 17 00:00:00 2001 From: RahulGautamSingh Date: Fri, 20 Jan 2023 14:59:29 +0530 Subject: [PATCH 32/48] fix(test): add/modify tests --- .../repository/update/pr/index.spec.ts | 57 +++++++++++++++++-- 1 file changed, 51 insertions(+), 6 deletions(-) diff --git a/lib/workers/repository/update/pr/index.spec.ts b/lib/workers/repository/update/pr/index.spec.ts index 07515a566a3ccc..2708e87daddd7b 100644 --- a/lib/workers/repository/update/pr/index.spec.ts +++ b/lib/workers/repository/update/pr/index.spec.ts @@ -87,7 +87,7 @@ describe('workers/repository/update/pr/index', () => { { pr: pr.number, prTitle }, 'PR created' ); - expect(prCache.setPrCache).toHaveBeenCalledTimes(1); + expect(prCache.setPrCache).toHaveBeenCalled(); }); it('aborts PR creation once limit is exceeded', async () => { @@ -100,6 +100,7 @@ describe('workers/repository/update/pr/index', () => { expect(res).toEqual({ type: 'without-pr', prBlockedBy: 'RateLimited' }); expect(platform.createPr).not.toHaveBeenCalled(); + expect(prCache.setPrCache).not.toHaveBeenCalled(); }); it('ignores PR limits on vulnerability alert', async () => { @@ -110,6 +111,7 @@ describe('workers/repository/update/pr/index', () => { expect(res).toEqual({ type: 'with-pr', pr }); expect(platform.createPr).toHaveBeenCalled(); + expect(prCache.setPrCache).toHaveBeenCalled(); }); it('creates rollback PR', async () => { @@ -119,6 +121,7 @@ describe('workers/repository/update/pr/index', () => { expect(res).toEqual({ type: 'with-pr', pr }); expect(logger.logger.info).toHaveBeenCalledWith('Creating Rollback PR'); + expect(prCache.setPrCache).toHaveBeenCalled(); }); it('skips PR creation due to non-green branch check', async () => { @@ -130,6 +133,7 @@ describe('workers/repository/update/pr/index', () => { type: 'without-pr', prBlockedBy: 'AwaitingTests', }); + expect(prCache.setPrCache).not.toHaveBeenCalled(); }); it('creates PR for green branch checks', async () => { @@ -140,6 +144,7 @@ describe('workers/repository/update/pr/index', () => { expect(res).toEqual({ type: 'with-pr', pr }); expect(platform.createPr).toHaveBeenCalled(); + expect(prCache.setPrCache).toHaveBeenCalled(); }); it('skips PR creation for unapproved dependencies', async () => { @@ -151,6 +156,7 @@ describe('workers/repository/update/pr/index', () => { type: 'without-pr', prBlockedBy: 'NeedsApproval', }); + expect(prCache.setPrCache).not.toHaveBeenCalled(); }); it('skips PR creation before prNotPendingHours is hit', async () => { @@ -170,6 +176,7 @@ describe('workers/repository/update/pr/index', () => { type: 'without-pr', prBlockedBy: 'AwaitingTests', }); + expect(prCache.setPrCache).not.toHaveBeenCalled(); }); it('skips PR creation due to stabilityStatus', async () => { @@ -189,6 +196,7 @@ describe('workers/repository/update/pr/index', () => { type: 'without-pr', prBlockedBy: 'AwaitingTests', }); + expect(prCache.setPrCache).not.toHaveBeenCalled(); }); it('creates PR after prNotPendingHours is hit', async () => { @@ -206,6 +214,7 @@ describe('workers/repository/update/pr/index', () => { }); expect(res).toEqual({ type: 'with-pr', pr }); + expect(prCache.setPrCache).toHaveBeenCalled(); }); describe('Error handling', () => { @@ -216,6 +225,7 @@ describe('workers/repository/update/pr/index', () => { const res = await ensurePr(config); expect(res).toEqual({ type: 'without-pr', prBlockedBy: 'Error' }); + expect(prCache.setPrCache).not.toHaveBeenCalled(); }); it('handles error for PR that already exists', async () => { @@ -232,6 +242,7 @@ describe('workers/repository/update/pr/index', () => { expect(logger.logger.warn).toHaveBeenCalledWith( 'A pull requests already exists' ); + expect(prCache.setPrCache).not.toHaveBeenCalled(); }); it('deletes branch on 502 error', async () => { @@ -242,6 +253,7 @@ describe('workers/repository/update/pr/index', () => { const res = await ensurePr(config); expect(res).toEqual({ type: 'without-pr', prBlockedBy: 'Error' }); + expect(prCache.setPrCache).not.toHaveBeenCalled(); expect(git.deleteBranch).toHaveBeenCalledWith('renovate-branch'); }); }); @@ -261,6 +273,7 @@ describe('workers/repository/update/pr/index', () => { { pr: changedPr.number, prTitle }, `PR updated` ); + expect(prCache.setPrCache).toHaveBeenCalled(); }); it('updates PR due to body change', async () => { @@ -275,6 +288,11 @@ describe('workers/repository/update/pr/index', () => { expect(res).toEqual({ type: 'with-pr', pr: changedPr }); expect(platform.updatePr).toHaveBeenCalled(); expect(platform.createPr).not.toHaveBeenCalled(); + expect(prCache.setPrCache).toHaveBeenCalled(); + expect(logger.logger.info).toHaveBeenCalledWith( + { pr: changedPr.number, prTitle }, + `PR updated` + ); }); it('ignores reviewable content ', async () => { @@ -284,6 +302,7 @@ describe('workers/repository/update/pr/index', () => { 'something'; const changedPr: Pr = { ...pr, + displayNumber: 'PR1', bodyStruct: getPrBodyStruct(`${body}${reviewableContent}`), }; platform.getBranchPr.mockResolvedValueOnce(changedPr); @@ -293,6 +312,10 @@ describe('workers/repository/update/pr/index', () => { expect(res).toEqual({ type: 'with-pr', pr: changedPr }); expect(platform.updatePr).not.toHaveBeenCalled(); expect(platform.createPr).not.toHaveBeenCalled(); + expect(prCache.setPrCache).toHaveBeenCalled(); + expect(logger.logger.debug).toHaveBeenCalledWith( + 'PR1 does not need updating' + ); }); }); @@ -364,6 +387,7 @@ describe('workers/repository/update/pr/index', () => { }); expect(platform.updatePr).not.toHaveBeenCalled(); expect(platform.createPr).not.toHaveBeenCalled(); + expect(prCache.setPrCache).not.toHaveBeenCalled(); }); it('adds assignees for PR automerge with red status', async () => { @@ -384,6 +408,7 @@ describe('workers/repository/update/pr/index', () => { expect(res).toEqual({ type: 'with-pr', pr: changedPr }); expect(participants.addParticipants).toHaveBeenCalled(); + expect(prCache.setPrCache).toHaveBeenCalled(); }); it('skips branch automerge and forces PR creation due to artifact errors', async () => { @@ -399,6 +424,7 @@ describe('workers/repository/update/pr/index', () => { expect(res).toEqual({ type: 'with-pr', pr }); expect(platform.createPr).toHaveBeenCalled(); expect(participants.addParticipants).not.toHaveBeenCalled(); + expect(prCache.setPrCache).toHaveBeenCalled(); }); it('skips branch automerge and forces PR creation due to prNotPendingHours exceeded', async () => { @@ -419,6 +445,7 @@ describe('workers/repository/update/pr/index', () => { expect(res).toEqual({ type: 'with-pr', pr }); expect(platform.createPr).toHaveBeenCalled(); + expect(prCache.setPrCache).toHaveBeenCalled(); }); it('automerges branch when prNotPendingHours are not exceeded', async () => { @@ -720,7 +747,17 @@ describe('workers/repository/update/pr/index', () => { expect(logger.logger.debug).toHaveBeenCalledWith('PR cache not found'); }); - it('fetches changelogs when pr cache does not match ', async () => { + it('does not log when cache is disabled and pr-cache is absent', async () => { + config.repositoryCache = 'disabled'; + platform.getBranchPr.mockResolvedValue(existingPr); + prCache.getPrCache.mockReturnValueOnce(null); + await ensurePr(config); + expect(logger.logger.debug).not.toHaveBeenCalledWith( + 'PR cache not found' + ); + }); + + it('logs when pr cache does not match', async () => { config.repositoryCache = 'enabled'; platform.getBranchPr.mockResolvedValue(existingPr); cachedPr = { @@ -728,13 +765,17 @@ describe('workers/repository/update/pr/index', () => { lastEdited: new Date().toISOString(), }; prCache.getPrCache.mockReturnValueOnce(cachedPr); - await ensurePr(config); + const res = await ensurePr(config); + expect(res).toEqual({ + type: 'with-pr', + pr: existingPr, + }); expect(logger.logger.debug).toHaveBeenCalledWith( 'PR fingerprints mismatch, processing PR' ); }); - it('fetches changelogs when pr cache matches but pr was edited within 24 hours', async () => { + it('logs when pr cache matches but pr was edited within 24 hours', async () => { config.repositoryCache = 'enabled'; platform.getBranchPr.mockResolvedValue(existingPr); cachedPr = { @@ -748,7 +789,7 @@ describe('workers/repository/update/pr/index', () => { ); }); - it('fetches changelogs when pr cache matches but lastEdited date string is invalid', async () => { + it('logs when pr cache matches but lastEdited date string is invalid', async () => { config.repositoryCache = 'enabled'; platform.getBranchPr.mockResolvedValue(existingPr); cachedPr = { @@ -770,7 +811,11 @@ describe('workers/repository/update/pr/index', () => { lastEdited: new Date('2020-01-20T00:00:00Z').toISOString(), }; prCache.getPrCache.mockReturnValueOnce(cachedPr); - await ensurePr(config); + const res = await ensurePr(config); + expect(res).toEqual({ + type: 'with-pr', + pr: existingPr, + }); expect(logger.logger.debug).toHaveBeenCalledWith( 'PR cache matches and no PR changes in last 24hrs, so skipping PR body check' ); From 9aef1edee0edac067dd64fffaee2749813e61700 Mon Sep 17 00:00:00 2001 From: RahulGautamSingh Date: Tue, 31 Jan 2023 05:23:04 +0530 Subject: [PATCH 33/48] update tests --- lib/util/date.spec.ts | 2 +- lib/util/date.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/util/date.spec.ts b/lib/util/date.spec.ts index 22e39a6b26b240..87d3742ac28923 100644 --- a/lib/util/date.spec.ts +++ b/lib/util/date.spec.ts @@ -30,7 +30,7 @@ describe('util/date', () => { expect(getElapsedHours(Jan1)).toBe(elapsedHours); // JS Date }); - it('throws when invalid date is passed', () => { + it('returns zero when date passed is invalid', () => { expect(getElapsedHours(new Date('invalid_date_string'))).toBe(0); }); }); diff --git a/lib/util/date.ts b/lib/util/date.ts index e18c7614befea4..6ddffaa38b7ac1 100644 --- a/lib/util/date.ts +++ b/lib/util/date.ts @@ -24,5 +24,5 @@ export function getElapsedHours(time: Date | string): number { } const diff = DateTime.now().diff(pastTime, 'hours'); - return diff.hours; + return Math.floor(diff.hours); } From 033d445b2333963cdae0699b5204d9ae8b0335ea Mon Sep 17 00:00:00 2001 From: RahulGautamSingh Date: Thu, 2 Feb 2023 07:09:50 +0530 Subject: [PATCH 34/48] Update lib/workers/repository/update/pr/index.ts Co-authored-by: Rhys Arkins --- lib/workers/repository/update/pr/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/workers/repository/update/pr/index.ts b/lib/workers/repository/update/pr/index.ts index 3ba745e8af49a9..7c42ada55c9cd0 100644 --- a/lib/workers/repository/update/pr/index.ts +++ b/lib/workers/repository/update/pr/index.ts @@ -342,8 +342,8 @@ export async function ensurePr( platformOptions: getPlatformPrOptions(config), }); logger.info({ pr: existingPr.number, prTitle }, `PR updated`); + setPrCache(branchName, prFingerprint); } - setPrCache(branchName, prFingerprint); return { type: 'with-pr', pr: existingPr }; } logger.debug({ branch: branchName, prTitle }, `Creating PR`); From 85c37b6856eb573dfc40f040d6e5e84a8d110806 Mon Sep 17 00:00:00 2001 From: RahulGautamSingh Date: Thu, 2 Feb 2023 07:13:51 +0530 Subject: [PATCH 35/48] refactor(util/date): rename time->date --- lib/util/date.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/util/date.ts b/lib/util/date.ts index 6ddffaa38b7ac1..53d7877da52dc5 100644 --- a/lib/util/date.ts +++ b/lib/util/date.ts @@ -13,16 +13,16 @@ export function getElapsedMinutes(date: Date): number { return Math.floor((new Date().getTime() - date.getTime()) / ONE_MINUTE_MS); } -export function getElapsedHours(time: Date | string): number { - const pastTime = - typeof time === 'string' - ? DateTime.fromISO(time) - : DateTime.fromJSDate(time); +export function getElapsedHours(date: Date | string): number { + const pastDate = + typeof date === 'string' + ? DateTime.fromISO(date) + : DateTime.fromJSDate(date); - if (!pastTime.isValid) { + if (!pastDate.isValid) { return 0; } - const diff = DateTime.now().diff(pastTime, 'hours'); + const diff = DateTime.now().diff(pastDate, 'hours'); return Math.floor(diff.hours); } From 6a4d2174deea5024fe5415438f2d84efc0cc6d21 Mon Sep 17 00:00:00 2001 From: RahulGautamSingh Date: Thu, 2 Feb 2023 07:37:35 +0530 Subject: [PATCH 36/48] Update lib/workers/repository/update/pr/index.ts --- lib/workers/repository/update/pr/index.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/workers/repository/update/pr/index.ts b/lib/workers/repository/update/pr/index.ts index 7c42ada55c9cd0..74e32d5d3b6454 100644 --- a/lib/workers/repository/update/pr/index.ts +++ b/lib/workers/repository/update/pr/index.ts @@ -311,7 +311,9 @@ export async function ensurePr( ) { // TODO: types (#7154) logger.debug(`${existingPr.displayNumber!} does not need updating`); +if(!prCache){ setPrCache(branchName, prFingerprint); + } return { type: 'with-pr', pr: existingPr }; } // PR must need updating From 5556adeed20d3dcd0926a811e89b46f8699d6860 Mon Sep 17 00:00:00 2001 From: RahulGautamSingh Date: Thu, 2 Feb 2023 08:08:25 +0530 Subject: [PATCH 37/48] add sensible tests --- .../repository/update/pr/index.spec.ts | 84 +++++++++++-------- lib/workers/repository/update/pr/index.ts | 7 +- 2 files changed, 52 insertions(+), 39 deletions(-) diff --git a/lib/workers/repository/update/pr/index.spec.ts b/lib/workers/repository/update/pr/index.spec.ts index 2708e87daddd7b..9e3070140efd01 100644 --- a/lib/workers/repository/update/pr/index.spec.ts +++ b/lib/workers/repository/update/pr/index.spec.ts @@ -58,6 +58,7 @@ describe('workers/repository/update/pr/index', () => { title: prTitle, bodyStruct, state: 'open', + displayNumber: '123', }; const config: BranchConfig = { @@ -739,31 +740,9 @@ describe('workers/repository/update/pr/index', () => { }; let cachedPr: PrCache | null = null; - it('logs when cache is enabled but pr-cache is absent', async () => { - config.repositoryCache = 'enabled'; - platform.getBranchPr.mockResolvedValue(existingPr); - prCache.getPrCache.mockReturnValueOnce(null); - await ensurePr(config); - expect(logger.logger.debug).toHaveBeenCalledWith('PR cache not found'); - }); - - it('does not log when cache is disabled and pr-cache is absent', async () => { - config.repositoryCache = 'disabled'; - platform.getBranchPr.mockResolvedValue(existingPr); - prCache.getPrCache.mockReturnValueOnce(null); - await ensurePr(config); - expect(logger.logger.debug).not.toHaveBeenCalledWith( - 'PR cache not found' - ); - }); - - it('logs when pr cache does not match', async () => { - config.repositoryCache = 'enabled'; + it('adds pr-cache when not present', async () => { platform.getBranchPr.mockResolvedValue(existingPr); - cachedPr = { - fingerprint: 'fingerprint', - lastEdited: new Date().toISOString(), - }; + cachedPr = null; prCache.getPrCache.mockReturnValueOnce(cachedPr); const res = await ensurePr(config); expect(res).toEqual({ @@ -771,39 +750,54 @@ describe('workers/repository/update/pr/index', () => { pr: existingPr, }); expect(logger.logger.debug).toHaveBeenCalledWith( - 'PR fingerprints mismatch, processing PR' + '123 does not need updating' ); + expect(prCache.setPrCache).toHaveBeenCalledTimes(1); }); - it('logs when pr cache matches but pr was edited within 24 hours', async () => { - config.repositoryCache = 'enabled'; + it('does not update pr-cache when pr fingerprint is same but pr was edited within 24hrs', async () => { platform.getBranchPr.mockResolvedValue(existingPr); cachedPr = { fingerprint: fingerprint(generatePrFingerprintConfig(config)), lastEdited: new Date().toISOString(), }; prCache.getPrCache.mockReturnValueOnce(cachedPr); - await ensurePr(config); + const res = await ensurePr(config); + expect(res).toEqual({ + type: 'with-pr', + pr: existingPr, + }); + expect(logger.logger.debug).toHaveBeenCalledWith( + '123 does not need updating' + ); expect(logger.logger.debug).toHaveBeenCalledWith( 'PR cache matches but it has been edited in the past 24hrs, so processing PR' ); + expect(prCache.setPrCache).not.toHaveBeenCalled(); }); - it('logs when pr cache matches but lastEdited date string is invalid', async () => { - config.repositoryCache = 'enabled'; - platform.getBranchPr.mockResolvedValue(existingPr); + it('updates pr-cache when pr fingerprint is different', async () => { + platform.getBranchPr.mockResolvedValue({ + ...existingPr, + title: 'Another title', + }); cachedPr = { - fingerprint: fingerprint(generatePrFingerprintConfig(config)), - lastEdited: 'invalid string', + fingerprint: 'old', + lastEdited: new Date('2020-01-20T00:00:00Z').toISOString(), }; prCache.getPrCache.mockReturnValueOnce(cachedPr); - await ensurePr(config); + const res = await ensurePr(config); + expect(res).toEqual({ + type: 'with-pr', + pr: { ...existingPr, title: 'Another title' }, + }); expect(logger.logger.debug).toHaveBeenCalledWith( - 'PR cache matches but it has been edited in the past 24hrs, so processing PR' + 'PR fingerprints mismatch, processing PR' ); + expect(prCache.setPrCache).toHaveBeenCalledTimes(1); }); - it('skips fetching changelogs', async () => { + it('skips fetching changelogs when cache is valid and pr was lastEdited before 24hrs', async () => { config.repositoryCache = 'enabled'; platform.getBranchPr.mockResolvedValue(existingPr); cachedPr = { @@ -821,6 +815,24 @@ describe('workers/repository/update/pr/index', () => { ); expect(embedChangelog).toHaveBeenCalledTimes(0); }); + + it('logs when cache is enabled but pr-cache is absent', async () => { + config.repositoryCache = 'enabled'; + platform.getBranchPr.mockResolvedValue(existingPr); + prCache.getPrCache.mockReturnValueOnce(null); + await ensurePr(config); + expect(logger.logger.debug).toHaveBeenCalledWith('PR cache not found'); + }); + + it('does not log when cache is disabled and pr-cache is absent', async () => { + config.repositoryCache = 'disabled'; + platform.getBranchPr.mockResolvedValue(existingPr); + prCache.getPrCache.mockReturnValueOnce(null); + await ensurePr(config); + expect(logger.logger.debug).not.toHaveBeenCalledWith( + 'PR cache not found' + ); + }); }); }); }); diff --git a/lib/workers/repository/update/pr/index.ts b/lib/workers/repository/update/pr/index.ts index 74e32d5d3b6454..058d7aa76b84cf 100644 --- a/lib/workers/repository/update/pr/index.ts +++ b/lib/workers/repository/update/pr/index.ts @@ -95,9 +95,9 @@ export async function ensurePr( config.dependencyDashboardChecks?.[config.branchName]; // Check if PR already exists const existingPr = await platform.getBranchPr(branchName); + const prCache = getPrCache(branchName); if (existingPr) { logger.debug('Found existing PR'); - const prCache = getPrCache(branchName); if (prCache) { logger.trace({ prCache }, 'Found existing PR cache'); // return if pr cache is valid and pr was not changed in the past 24hrs @@ -311,8 +311,9 @@ export async function ensurePr( ) { // TODO: types (#7154) logger.debug(`${existingPr.displayNumber!} does not need updating`); -if(!prCache){ - setPrCache(branchName, prFingerprint); + // adds or-cache for existing PRs + if (!prCache) { + setPrCache(branchName, prFingerprint); } return { type: 'with-pr', pr: existingPr }; } From 1bc39321778fe197e0656e26af4d6b9fb1513b22 Mon Sep 17 00:00:00 2001 From: RahulGautamSingh Date: Thu, 2 Feb 2023 13:46:52 +0530 Subject: [PATCH 38/48] setPrCache(): make lastEdited update optional --- lib/workers/repository/update/pr/index.ts | 8 +++----- lib/workers/repository/update/pr/pr-cache.spec.ts | 4 ++-- lib/workers/repository/update/pr/pr-cache.ts | 11 +++++++++-- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/lib/workers/repository/update/pr/index.ts b/lib/workers/repository/update/pr/index.ts index 058d7aa76b84cf..975423a443d220 100644 --- a/lib/workers/repository/update/pr/index.ts +++ b/lib/workers/repository/update/pr/index.ts @@ -312,9 +312,7 @@ export async function ensurePr( // TODO: types (#7154) logger.debug(`${existingPr.displayNumber!} does not need updating`); // adds or-cache for existing PRs - if (!prCache) { - setPrCache(branchName, prFingerprint); - } + setPrCache(branchName, prFingerprint, false); return { type: 'with-pr', pr: existingPr }; } // PR must need updating @@ -345,7 +343,7 @@ export async function ensurePr( platformOptions: getPlatformPrOptions(config), }); logger.info({ pr: existingPr.number, prTitle }, `PR updated`); - setPrCache(branchName, prFingerprint); + setPrCache(branchName, prFingerprint, true); } return { type: 'with-pr', pr: existingPr }; } @@ -439,7 +437,7 @@ export async function ensurePr( } // TODO: types (#7154) logger.debug(`Created ${pr.displayNumber!}`); - setPrCache(branchName, prFingerprint); + setPrCache(branchName, prFingerprint, true); return { type: 'with-pr', pr }; } } catch (err) { diff --git a/lib/workers/repository/update/pr/pr-cache.spec.ts b/lib/workers/repository/update/pr/pr-cache.spec.ts index d55fa886cd01c3..e8c6caff9c66de 100644 --- a/lib/workers/repository/update/pr/pr-cache.spec.ts +++ b/lib/workers/repository/update/pr/pr-cache.spec.ts @@ -51,7 +51,7 @@ describe('workers/repository/update/pr/pr-cache', () => { describe('setPrCache()', () => { it('logs if branch not found', () => { cache.getCache.mockReturnValue(dummyCache); - setPrCache('branch_1', 'fingerprint_hash'); + setPrCache('branch_1', 'fingerprint_hash', false); expect(logger.logger.debug).toHaveBeenCalledWith( 'setPrCache(): Branch cache not present' ); @@ -60,7 +60,7 @@ describe('workers/repository/update/pr/pr-cache', () => { it('set prCache', () => { cache.getCache.mockReturnValue(dummyCache); jest.useFakeTimers().setSystemTime(new Date('2020-01-01')); - setPrCache('branch_name', 'fingerprint_hash'); + setPrCache('branch_name', 'fingerprint_hash', true); expect(dummyCache).toStrictEqual({ branches: [ { diff --git a/lib/workers/repository/update/pr/pr-cache.ts b/lib/workers/repository/update/pr/pr-cache.ts index 989a2cd46fc3f8..9047d630662385 100644 --- a/lib/workers/repository/update/pr/pr-cache.ts +++ b/lib/workers/repository/update/pr/pr-cache.ts @@ -17,7 +17,11 @@ export function getPrCache(branchName: string): PrCache | null { } // store the time a PR was last updated -export function setPrCache(branchName: string, fingerprint: string): void { +export function setPrCache( + branchName: string, + fingerprint: string, + prModified: boolean +): void { logger.debug(`setPrCache()`); const cache = getCache(); const branch = cache.branches?.find( @@ -29,8 +33,11 @@ export function setPrCache(branchName: string, fingerprint: string): void { return; } + const lastEdited = branch.prCache?.lastEdited; branch.prCache = { fingerprint, - lastEdited: new Date().toISOString(), + // update time when creating new cache or when pr was modified + lastEdited: + lastEdited && !prModified ? lastEdited : new Date().toISOString(), }; } From e47c5d8f552eca1f85ed37980ee88f7b9cef9b18 Mon Sep 17 00:00:00 2001 From: RahulGautamSingh Date: Sat, 4 Feb 2023 12:36:29 +0530 Subject: [PATCH 39/48] feat: add pendingVersions to PrFingerprintConnfig --- lib/workers/repository/update/pr/pr-fingerprint.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/workers/repository/update/pr/pr-fingerprint.ts b/lib/workers/repository/update/pr/pr-fingerprint.ts index 60d4b1264d88b4..dedd97570b6753 100644 --- a/lib/workers/repository/update/pr/pr-fingerprint.ts +++ b/lib/workers/repository/update/pr/pr-fingerprint.ts @@ -38,6 +38,7 @@ export interface PrFingerprintConfig { timezone?: string; updateType?: UpdateType; warnings?: ValidationMessage[]; + pendingVersions?: string[]; filteredUpgrades?: FilteredBranchUpgradeConfig[]; } @@ -74,6 +75,7 @@ export function generatePrFingerprintConfig( timezone: config.timezone, updateType: config.updateType, warnings: config.warnings, + pendingVersions: config.pendingVersions, }; } From ab3e3e12920158c4b02a39cc09cc786ca6c56cba Mon Sep 17 00:00:00 2001 From: RahulGautamSingh Date: Sat, 4 Feb 2023 12:59:16 +0530 Subject: [PATCH 40/48] refactor: format --- lib/workers/repository/update/pr/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/workers/repository/update/pr/index.ts b/lib/workers/repository/update/pr/index.ts index 975423a443d220..0ee7818992a30c 100644 --- a/lib/workers/repository/update/pr/index.ts +++ b/lib/workers/repository/update/pr/index.ts @@ -312,7 +312,7 @@ export async function ensurePr( // TODO: types (#7154) logger.debug(`${existingPr.displayNumber!} does not need updating`); // adds or-cache for existing PRs - setPrCache(branchName, prFingerprint, false); + setPrCache(branchName, prFingerprint, false); return { type: 'with-pr', pr: existingPr }; } // PR must need updating From b32cd60d28c38d4534b3ec155bfc4565febce298 Mon Sep 17 00:00:00 2001 From: RahulGautamSingh Date: Sun, 5 Feb 2023 19:50:53 +0530 Subject: [PATCH 41/48] fix tests --- lib/workers/repository/update/pr/index.spec.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/workers/repository/update/pr/index.spec.ts b/lib/workers/repository/update/pr/index.spec.ts index 9e3070140efd01..f656a59792153f 100644 --- a/lib/workers/repository/update/pr/index.spec.ts +++ b/lib/workers/repository/update/pr/index.spec.ts @@ -755,7 +755,7 @@ describe('workers/repository/update/pr/index', () => { expect(prCache.setPrCache).toHaveBeenCalledTimes(1); }); - it('does not update pr-cache when pr fingerprint is same but pr was edited within 24hrs', async () => { + it('does not update lastEdited pr-cache when pr fingerprint is same but pr was edited within 24hrs', async () => { platform.getBranchPr.mockResolvedValue(existingPr); cachedPr = { fingerprint: fingerprint(generatePrFingerprintConfig(config)), @@ -773,7 +773,11 @@ describe('workers/repository/update/pr/index', () => { expect(logger.logger.debug).toHaveBeenCalledWith( 'PR cache matches but it has been edited in the past 24hrs, so processing PR' ); - expect(prCache.setPrCache).not.toHaveBeenCalled(); + expect(prCache.setPrCache).toHaveBeenCalledWith( + sourceBranch, + cachedPr.fingerprint, + false + ); }); it('updates pr-cache when pr fingerprint is different', async () => { From a5af9b17f41f61b33d97d333fa63ae3f79c9f9c8 Mon Sep 17 00:00:00 2001 From: RahulGautamSingh Date: Tue, 14 Feb 2023 04:26:34 +0530 Subject: [PATCH 42/48] apply suggestions --- lib/workers/repository/update/pr/index.spec.ts | 6 +++--- lib/workers/repository/update/pr/pr-cache.spec.ts | 2 +- lib/workers/repository/update/pr/pr-cache.ts | 6 +++--- lib/workers/repository/update/pr/pr-fingerprint.ts | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/workers/repository/update/pr/index.spec.ts b/lib/workers/repository/update/pr/index.spec.ts index f97d5519e6672e..8e4a6b6f1244e3 100644 --- a/lib/workers/repository/update/pr/index.spec.ts +++ b/lib/workers/repository/update/pr/index.spec.ts @@ -58,7 +58,7 @@ describe('workers/repository/update/pr/index', () => { title: prTitle, bodyStruct, state: 'open', - displayNumber: '123', + displayNumber: `Pull Request #${number}`, }; const config: BranchConfig = { @@ -767,7 +767,7 @@ describe('workers/repository/update/pr/index', () => { pr: existingPr, }); expect(logger.logger.debug).toHaveBeenCalledWith( - '123 does not need updating' + 'Pull Request #123 does not need updating' ); expect(prCache.setPrCache).toHaveBeenCalledTimes(1); }); @@ -785,7 +785,7 @@ describe('workers/repository/update/pr/index', () => { pr: existingPr, }); expect(logger.logger.debug).toHaveBeenCalledWith( - '123 does not need updating' + 'Pull Request #123 does not need updating' ); expect(logger.logger.debug).toHaveBeenCalledWith( 'PR cache matches but it has been edited in the past 24hrs, so processing PR' diff --git a/lib/workers/repository/update/pr/pr-cache.spec.ts b/lib/workers/repository/update/pr/pr-cache.spec.ts index e8c6caff9c66de..dcab378e75ac2c 100644 --- a/lib/workers/repository/update/pr/pr-cache.spec.ts +++ b/lib/workers/repository/update/pr/pr-cache.spec.ts @@ -30,7 +30,7 @@ describe('workers/repository/update/pr/pr-cache', () => { expect(getPrCache('branch_name')).toBeNull(); }); - it('return null if prCache is falsy', () => { + it('return null if prCache is null/undefined', () => { cache.getCache.mockReturnValue(dummyCache); expect(getPrCache('branch_name')).toBeNull(); }); diff --git a/lib/workers/repository/update/pr/pr-cache.ts b/lib/workers/repository/update/pr/pr-cache.ts index 9047d630662385..337c34eb678cae 100644 --- a/lib/workers/repository/update/pr/pr-cache.ts +++ b/lib/workers/repository/update/pr/pr-cache.ts @@ -9,11 +9,11 @@ export function getPrCache(branchName: string): PrCache | null { (branch) => branchName === branch.branchName ); - if (branch?.prCache) { - return branch.prCache; + if (!branch?.prCache) { + return null; } - return null; + return branch.prCache; } // store the time a PR was last updated diff --git a/lib/workers/repository/update/pr/pr-fingerprint.ts b/lib/workers/repository/update/pr/pr-fingerprint.ts index dedd97570b6753..bf066bd6db36a1 100644 --- a/lib/workers/repository/update/pr/pr-fingerprint.ts +++ b/lib/workers/repository/update/pr/pr-fingerprint.ts @@ -9,7 +9,7 @@ import { getElapsedHours } from '../../../../util/date'; import type { BranchConfig } from '../../../types'; // BranchUpgradeConfig - filtered -interface FilteredBranchUpgradeConfig { +export interface FilteredBranchUpgradeConfig { depName?: string; gitRef?: boolean; hasReleaseNotes?: boolean; From 667350fe56139afb4eccc181fb0f12b0a7fe4aef Mon Sep 17 00:00:00 2001 From: RahulGautamSingh Date: Thu, 16 Feb 2023 16:32:24 +0530 Subject: [PATCH 43/48] update test + move log msg --- lib/workers/repository/update/pr/index.spec.ts | 4 +--- lib/workers/repository/update/pr/index.ts | 3 --- lib/workers/repository/update/pr/pr-fingerprint.ts | 3 +++ 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/lib/workers/repository/update/pr/index.spec.ts b/lib/workers/repository/update/pr/index.spec.ts index a12319dc728096..ac344e4d216187 100644 --- a/lib/workers/repository/update/pr/index.spec.ts +++ b/lib/workers/repository/update/pr/index.spec.ts @@ -58,7 +58,6 @@ describe('workers/repository/update/pr/index', () => { title: prTitle, bodyStruct, state: 'open', - displayNumber: `Pull Request #${number}`, }; const config: BranchConfig = { @@ -303,7 +302,6 @@ describe('workers/repository/update/pr/index', () => { 'something'; const changedPr: Pr = { ...pr, - displayNumber: 'PR1', bodyStruct: getPrBodyStruct(`${body}${reviewableContent}`), }; platform.getBranchPr.mockResolvedValueOnce(changedPr); @@ -315,7 +313,7 @@ describe('workers/repository/update/pr/index', () => { expect(platform.createPr).not.toHaveBeenCalled(); expect(prCache.setPrCache).toHaveBeenCalled(); expect(logger.logger.debug).toHaveBeenCalledWith( - 'PR1 does not need updating' + 'Pull Request #123 does not need updating' ); }); }); diff --git a/lib/workers/repository/update/pr/index.ts b/lib/workers/repository/update/pr/index.ts index 1645b5fe126f20..9506858698c220 100644 --- a/lib/workers/repository/update/pr/index.ts +++ b/lib/workers/repository/update/pr/index.ts @@ -116,9 +116,6 @@ export async function ensurePr( logger.trace({ prCache }, 'Found existing PR cache'); // return if pr cache is valid and pr was not changed in the past 24hrs if (validatePrCache(prCache, prFingerprint)) { - logger.debug( - 'PR cache matches and no PR changes in last 24hrs, so skipping PR body check' - ); return { type: 'with-pr', pr: existingPr }; } } else if (config.repositoryCache === 'enabled') { diff --git a/lib/workers/repository/update/pr/pr-fingerprint.ts b/lib/workers/repository/update/pr/pr-fingerprint.ts index bf066bd6db36a1..62a5878e14fc1c 100644 --- a/lib/workers/repository/update/pr/pr-fingerprint.ts +++ b/lib/workers/repository/update/pr/pr-fingerprint.ts @@ -95,5 +95,8 @@ export function validatePrCache( return false; } + logger.debug( + 'PR cache matches and no PR changes in last 24hrs, so skipping PR body check' + ); return true; } From 07ceb04be36194ea35a5ac68f0a2b2207fd5ed7e Mon Sep 17 00:00:00 2001 From: RahulGautamSingh Date: Thu, 16 Feb 2023 17:20:08 +0530 Subject: [PATCH 44/48] Update types.ts --- lib/util/cache/repository/types.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/util/cache/repository/types.ts b/lib/util/cache/repository/types.ts index 3fe6c8fc02cd45..9faa3343923ce4 100644 --- a/lib/util/cache/repository/types.ts +++ b/lib/util/cache/repository/types.ts @@ -28,6 +28,9 @@ export interface BranchUpgradeCache { export interface PrCache { fingerprint: string; + /** + *Whether this PR was last edited + */ lastEdited: string; } From 4f5385deae880af7765852ff75fad0808f86b70a Mon Sep 17 00:00:00 2001 From: RahulGautamSingh Date: Thu, 16 Feb 2023 17:21:26 +0530 Subject: [PATCH 45/48] Update types.ts --- lib/util/cache/repository/types.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/util/cache/repository/types.ts b/lib/util/cache/repository/types.ts index 9faa3343923ce4..870d861edb8f42 100644 --- a/lib/util/cache/repository/types.ts +++ b/lib/util/cache/repository/types.ts @@ -29,14 +29,14 @@ export interface BranchUpgradeCache { export interface PrCache { fingerprint: string; /** - *Whether this PR was last edited + * Whether this PR was last edited */ lastEdited: string; } export interface BranchCache { /** - *Whether this branch has automerge enabled + * Whether this branch has automerge enabled */ automerge: boolean; /** @@ -68,7 +68,7 @@ export interface BranchCache { */ isModified?: boolean; /** - * + * */ pristine?: boolean; /** From 487633c93371e0c031075e733e2b7f7319abb3a7 Mon Sep 17 00:00:00 2001 From: RahulGautamSingh Date: Thu, 16 Feb 2023 18:01:08 +0530 Subject: [PATCH 46/48] fix lint issue --- lib/util/cache/repository/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/util/cache/repository/types.ts b/lib/util/cache/repository/types.ts index 870d861edb8f42..fda6b898663094 100644 --- a/lib/util/cache/repository/types.ts +++ b/lib/util/cache/repository/types.ts @@ -68,7 +68,7 @@ export interface BranchCache { */ isModified?: boolean; /** - * + * */ pristine?: boolean; /** From 3f5351e27b1787a3835a8fe138e5f13a3027780f Mon Sep 17 00:00:00 2001 From: RahulGautamSingh Date: Tue, 21 Feb 2023 00:36:21 +0530 Subject: [PATCH 47/48] Update lib/util/cache/repository/types.ts Co-authored-by: Michael Kriese --- lib/util/cache/repository/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/util/cache/repository/types.ts b/lib/util/cache/repository/types.ts index fda6b898663094..9e92ecba463dd6 100644 --- a/lib/util/cache/repository/types.ts +++ b/lib/util/cache/repository/types.ts @@ -29,7 +29,7 @@ export interface BranchUpgradeCache { export interface PrCache { fingerprint: string; /** - * Whether this PR was last edited + * last PR modified ISO timestamp */ lastEdited: string; } From fcda03c298d34c417dee6b79493abfe0694faed1 Mon Sep 17 00:00:00 2001 From: RahulGautamSingh Date: Tue, 21 Feb 2023 00:52:35 +0530 Subject: [PATCH 48/48] prettier-fix --- lib/util/cache/repository/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/util/cache/repository/types.ts b/lib/util/cache/repository/types.ts index 9e92ecba463dd6..3146e6e06385c4 100644 --- a/lib/util/cache/repository/types.ts +++ b/lib/util/cache/repository/types.ts @@ -29,7 +29,7 @@ export interface BranchUpgradeCache { export interface PrCache { fingerprint: string; /** - * last PR modified ISO timestamp + * last PR modified ISO timestamp */ lastEdited: string; }