diff --git a/.github/workflow-scripts/__tests__/extractIssueOncalls-test.js b/.github/workflow-scripts/__tests__/extractIssueOncalls-test.js index 7ad91ddc06a1..53e67893a395 100644 --- a/.github/workflow-scripts/__tests__/extractIssueOncalls-test.js +++ b/.github/workflow-scripts/__tests__/extractIssueOncalls-test.js @@ -31,6 +31,7 @@ describe('extractIssueOncalls', () => { }); afterEach(() => { + jest.restoreAllMocks(); jest.useRealTimers(); }); it('extracts m and f on 6 of April', () => { @@ -80,4 +81,16 @@ describe('extractIssueOncalls', () => { const oncalls = extractIssueOncalls(schedule, userMap); expect(oncalls).toEqual([userMap['@g'], userMap['@d']]); }); + + it('continues the latest rotation after the schedule ends', () => { + const warn = jest.spyOn(console, 'warn').mockImplementation(() => {}); + jest.setSystemTime(new Date(2025, 3, 15)); + + const oncalls = extractIssueOncalls(schedule, userMap); + + expect(oncalls).toEqual([userMap['@g'], userMap['@d']]); + expect(warn).toHaveBeenCalledWith( + 'No issue oncall schedule found for 2025-04-15; continuing the rotation from 2025-04-08', + ); + }); }); diff --git a/.github/workflow-scripts/extractIssueOncalls.js b/.github/workflow-scripts/extractIssueOncalls.js index 3aa6748d69d7..a7bfa3248b6f 100644 --- a/.github/workflow-scripts/extractIssueOncalls.js +++ b/.github/workflow-scripts/extractIssueOncalls.js @@ -20,8 +20,23 @@ function extractUsersFromScheduleAndDate(schedule, userMap, date) { const month = date.getMonth() + 1; // 0 is January, 1 is February const day = date.getDate(); const dateStr = `${year}-${month < 10 ? `0${month}` : month}-${day < 10 ? `0${day}` : day}`; - const user1 = userMap[schedule[dateStr][0]]; - const user2 = userMap[schedule[dateStr][1]]; + const scheduledDate = Object.keys(schedule) + .filter(candidateDate => candidateDate <= dateStr) + .sort() + .at(-1); + + if (scheduledDate == null) { + throw new Error(`No issue oncall schedule found on or before ${dateStr}`); + } + + if (scheduledDate !== dateStr) { + console.warn( + `No issue oncall schedule found for ${dateStr}; continuing the rotation from ${scheduledDate}`, + ); + } + + const user1 = userMap[schedule[scheduledDate][0]]; + const user2 = userMap[schedule[scheduledDate][1]]; return [user1, user2]; } @@ -47,6 +62,8 @@ function extractUsersFromScheduleAndDate(schedule, userMap, date) { * } * ``` * + * Each dated entry stays active until a newer entry takes effect. + * * When uploading the secret, make sure that the JSON strings are escaped! * The script will fail otherwise, because GitHub will remove the `"` characters. */