From 9ad9941e3d64d95e606b2ac7731f2406c032e220 Mon Sep 17 00:00:00 2001 From: Rahul Gautam Singh Date: Fri, 20 Dec 2024 17:28:35 +0530 Subject: [PATCH 1/6] refactor(worker/pr): make cron schedule readable --- .../repository/update/branch/schedule.spec.ts | 8 ----- .../update/pr/body/config-description.spec.ts | 6 ++-- .../update/pr/body/config-description.ts | 30 ++++++++++++++++++- 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/lib/workers/repository/update/branch/schedule.spec.ts b/lib/workers/repository/update/branch/schedule.spec.ts index 4dacb99da885dd..5339e20678092a 100644 --- a/lib/workers/repository/update/branch/schedule.spec.ts +++ b/lib/workers/repository/update/branch/schedule.spec.ts @@ -496,13 +496,5 @@ describe('workers/repository/update/branch/schedule', () => { const result = cronstrue.toString('* 23 * * *'); expect(result).toBe('Every minute, between 11:00 PM and 11:59 PM'); }); - - it('should not throw an error for an invalid cron expression "* * */2 6#1"', () => { - expect(() => { - cronstrue.toString('* * */2 6#1', { - throwExceptionOnParseError: false, - }); - }).not.toThrow(); - }); }); }); diff --git a/lib/workers/repository/update/pr/body/config-description.spec.ts b/lib/workers/repository/update/pr/body/config-description.spec.ts index 25e835bde61f04..2045c0baadb9e4 100644 --- a/lib/workers/repository/update/pr/body/config-description.spec.ts +++ b/lib/workers/repository/update/pr/body/config-description.spec.ts @@ -53,9 +53,11 @@ describe('workers/repository/update/pr/body/config-description', () => { it('renders UTC as the default timezone', () => { const res = getPrConfigDescription({ ...config, - schedule: ['* 1 * * * *'], + schedule: ['* 1 * * *', '* * 2 * 1'], }); - expect(res).toContain(`"* 1 * * * *" (UTC)`); + expect(res).toContain( + 'Between 01:00 AM and 01:59 AM ("* 1 * * *"),On day 2 of the month, and on Monday ("* * 2 * 1") (UTC)', + ); }); it('renders undefined schedule', () => { diff --git a/lib/workers/repository/update/pr/body/config-description.ts b/lib/workers/repository/update/pr/body/config-description.ts index 9249247ad25696..0b2c6e1426ee70 100644 --- a/lib/workers/repository/update/pr/body/config-description.ts +++ b/lib/workers/repository/update/pr/body/config-description.ts @@ -1,3 +1,6 @@ +import { CronPattern } from 'croner'; +import cronstrue from 'cronstrue'; +import { capitalize } from '../../../../../../tools/docs/utils'; import { emojify } from '../../../../../util/emoji'; import type { BranchConfig } from '../../../../types'; @@ -51,7 +54,8 @@ function scheduleToString( ): string { let scheduleString = ''; if (schedule && schedule[0] !== 'at any time') { - scheduleString += `"${String(schedule)}"`; + scheduleString = + getReadableCronSchedule(schedule) ?? `"${String(schedule)}"`; if (timezone) { scheduleString += ` in timezone ${timezone}`; } else { @@ -62,3 +66,27 @@ function scheduleToString( } return scheduleString; } + +/** + * Return human-readable cron schedule summary if the schedule is a valid cron + * else return null + */ +function getReadableCronSchedule(scheduleText: string[]): string | null { + // assuming if one schedule is cron the others in the array will be cron too + try { + new CronPattern(scheduleText[0]); // validate cron + const scheduleStr = scheduleText.map( + (cron) => + capitalize( + cronstrue + .toString(cron, { + throwExceptionOnParseError: false, + }) + .replace('Every minute, ', ''), + ) + ` ("${cron}")`, + ); + return `${String(scheduleStr)}`; + } catch { + return null; + } +} From 7679095c62d11f25032513d5f69f484c5fb8041e Mon Sep 17 00:00:00 2001 From: Rahul Gautam Singh Date: Sat, 21 Dec 2024 09:40:04 +0530 Subject: [PATCH 2/6] fix: prevent unexpected italic effect --- .../update/pr/body/config-description.spec.ts | 2 +- .../update/pr/body/config-description.ts | 24 ++++++++++--------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/lib/workers/repository/update/pr/body/config-description.spec.ts b/lib/workers/repository/update/pr/body/config-description.spec.ts index 2045c0baadb9e4..cd4b256611d21a 100644 --- a/lib/workers/repository/update/pr/body/config-description.spec.ts +++ b/lib/workers/repository/update/pr/body/config-description.spec.ts @@ -56,7 +56,7 @@ describe('workers/repository/update/pr/body/config-description', () => { schedule: ['* 1 * * *', '* * 2 * 1'], }); expect(res).toContain( - 'Between 01:00 AM and 01:59 AM ("* 1 * * *"),On day 2 of the month, and on Monday ("* * 2 * 1") (UTC)', + 'Between 01:00 AM and 01:59 AM ( * 1 * * * ), On day 2 of the month, and on Monday ( * * 2 * 1 ) (UTC)', ); }); diff --git a/lib/workers/repository/update/pr/body/config-description.ts b/lib/workers/repository/update/pr/body/config-description.ts index 0b2c6e1426ee70..5c5a9fbb3c8842 100644 --- a/lib/workers/repository/update/pr/body/config-description.ts +++ b/lib/workers/repository/update/pr/body/config-description.ts @@ -75,17 +75,19 @@ function getReadableCronSchedule(scheduleText: string[]): string | null { // assuming if one schedule is cron the others in the array will be cron too try { new CronPattern(scheduleText[0]); // validate cron - const scheduleStr = scheduleText.map( - (cron) => - capitalize( - cronstrue - .toString(cron, { - throwExceptionOnParseError: false, - }) - .replace('Every minute, ', ''), - ) + ` ("${cron}")`, - ); - return `${String(scheduleStr)}`; + return scheduleText + .map( + (cron) => + capitalize( + cronstrue + .toString(cron, { + throwExceptionOnParseError: false, + }) + .replace('Every minute, ', ''), + ) + ` ( ${String(cron)} )`, + ) + .join(', '); + // return `${String(scheduleStr)}`; } catch { return null; } From d2284b73bf341130747d4f01b52165a0f6fb7939 Mon Sep 17 00:00:00 2001 From: Rahul Gautam Singh Date: Sat, 21 Dec 2024 09:44:35 +0530 Subject: [PATCH 3/6] refactor: remove unrelated change --- lib/workers/repository/update/branch/schedule.spec.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/workers/repository/update/branch/schedule.spec.ts b/lib/workers/repository/update/branch/schedule.spec.ts index 5339e20678092a..4dacb99da885dd 100644 --- a/lib/workers/repository/update/branch/schedule.spec.ts +++ b/lib/workers/repository/update/branch/schedule.spec.ts @@ -496,5 +496,13 @@ describe('workers/repository/update/branch/schedule', () => { const result = cronstrue.toString('* 23 * * *'); expect(result).toBe('Every minute, between 11:00 PM and 11:59 PM'); }); + + it('should not throw an error for an invalid cron expression "* * */2 6#1"', () => { + expect(() => { + cronstrue.toString('* * */2 6#1', { + throwExceptionOnParseError: false, + }); + }).not.toThrow(); + }); }); }); From b5cfa4ed53e572c66cdccf91be2f61020e6a4e30 Mon Sep 17 00:00:00 2001 From: Rahul Gautam Singh Date: Sat, 21 Dec 2024 09:46:40 +0530 Subject: [PATCH 4/6] add new test --- .../update/pr/body/config-description.spec.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/workers/repository/update/pr/body/config-description.spec.ts b/lib/workers/repository/update/pr/body/config-description.spec.ts index cd4b256611d21a..dc446103d06e94 100644 --- a/lib/workers/repository/update/pr/body/config-description.spec.ts +++ b/lib/workers/repository/update/pr/body/config-description.spec.ts @@ -51,6 +51,16 @@ describe('workers/repository/update/pr/body/config-description', () => { }); it('renders UTC as the default timezone', () => { + const res = getPrConfigDescription({ + ...config, + schedule: ['* 1 * * *'], + }); + expect(res).toContain( + 'Between 01:00 AM and 01:59 AM ( * 1 * * * ) (UTC)', + ); + }); + + it('summarizes cron schedules', () => { const res = getPrConfigDescription({ ...config, schedule: ['* 1 * * *', '* * 2 * 1'], From 8772675e2f8ef0821aac4411072f4ce1473060bf Mon Sep 17 00:00:00 2001 From: Rahul Gautam Singh Date: Sat, 21 Dec 2024 09:48:20 +0530 Subject: [PATCH 5/6] refactor: cleanup --- lib/workers/repository/update/pr/body/config-description.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/workers/repository/update/pr/body/config-description.ts b/lib/workers/repository/update/pr/body/config-description.ts index 5c5a9fbb3c8842..cc5122ae8230cd 100644 --- a/lib/workers/repository/update/pr/body/config-description.ts +++ b/lib/workers/repository/update/pr/body/config-description.ts @@ -87,7 +87,6 @@ function getReadableCronSchedule(scheduleText: string[]): string | null { ) + ` ( ${String(cron)} )`, ) .join(', '); - // return `${String(scheduleStr)}`; } catch { return null; } From 47f5b9d6371f5f3918b50d7de16b59f916243bf6 Mon Sep 17 00:00:00 2001 From: Rahul Gautam Singh Date: Wed, 25 Dec 2024 10:55:50 +0530 Subject: [PATCH 6/6] add test --- .../update/pr/body/config-description.spec.ts | 10 ++++++++++ .../repository/update/pr/body/config-description.ts | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/workers/repository/update/pr/body/config-description.spec.ts b/lib/workers/repository/update/pr/body/config-description.spec.ts index dc446103d06e94..47a8956c8314fd 100644 --- a/lib/workers/repository/update/pr/body/config-description.spec.ts +++ b/lib/workers/repository/update/pr/body/config-description.spec.ts @@ -70,6 +70,16 @@ describe('workers/repository/update/pr/body/config-description', () => { ); }); + it('displays later schedules', () => { + const res = getPrConfigDescription({ + ...config, + schedule: ['before 6am on Monday', 'after 3pm on Tuesday'], + }); + expect(res).toContain( + '"before 6am on Monday,after 3pm on Tuesday" (UTC)', + ); + }); + it('renders undefined schedule', () => { const res = getPrConfigDescription(config); expect(res).toContain(`At any time (no schedule defined).`); diff --git a/lib/workers/repository/update/pr/body/config-description.ts b/lib/workers/repository/update/pr/body/config-description.ts index cc5122ae8230cd..8cea8e4d68df10 100644 --- a/lib/workers/repository/update/pr/body/config-description.ts +++ b/lib/workers/repository/update/pr/body/config-description.ts @@ -84,7 +84,7 @@ function getReadableCronSchedule(scheduleText: string[]): string | null { throwExceptionOnParseError: false, }) .replace('Every minute, ', ''), - ) + ` ( ${String(cron)} )`, + ) + ` ( ${cron} )`, ) .join(', '); } catch {