diff --git a/config.json b/config.json index f28adaff9..530e1b13f 100644 --- a/config.json +++ b/config.json @@ -4,8 +4,8 @@ "releasePaginationLimit": 10, "commentsPaginationLimit": 100, "retrospective": { - "lastDay": "2025-12-14", - "nextDay": "2025-12-21" + "lastDay": "2026-02-08", + "nextDay": "2026-02-15" }, "breakDelimiter": "", "discussionsInScope": [ diff --git a/scripts/collect-retrospective.js b/scripts/collect-retrospective.js index 2b8198703..2ff604461 100644 --- a/scripts/collect-retrospective.js +++ b/scripts/collect-retrospective.js @@ -1,19 +1,28 @@ import got from 'got' -import { buildRFC822Date, overwriteConfig, composeFeedItem, getFeedContent, overwriteFeedContent, getConfig, generateRetroRequestUrl, parseRetrospectiveContent, generateRetroUIUrl } from '../utils/index.js' +import { buildRFC822Date, overwriteConfig, composeFeedItem, getFeedContent, overwriteFeedContent, getConfig, generateRetroRequestUrl, parseRetrospectiveContent, generateRetroUIUrl, getCurrentRetroDate, getNextRetroDate } from '../utils/index.js' // Collect new retrospective -const { retrospective: currentConfig, breakDelimiter } = getConfig() -const url = generateRetroRequestUrl(currentConfig.nextDay) +// Calculate the target date dynamically instead of using config.nextDay +// This ensures we always get the current week's retro, not sequentially catch up old ones +const { breakDelimiter } = getConfig() +const targetDate = getCurrentRetroDate() +const url = generateRetroRequestUrl(targetDate) try { const content = await got(url).text() const data = parseRetrospectiveContent(content) + + // Use the calculated targetDate for dates instead of parsed dates from title + // This makes the script robust against title format changes in retro-weekly + const lastDay = targetDate + const nextDay = getNextRetroDate(targetDate) + const retrospective = composeFeedItem({ title: data.title, description: `${data.description}

]]>`, - pubDate: buildRFC822Date(data.lastDay), - link: generateRetroUIUrl(data.lastDay), - guid: generateRetroUIUrl(data.lastDay) + pubDate: buildRFC822Date(lastDay), + link: generateRetroUIUrl(lastDay), + guid: generateRetroUIUrl(lastDay) }) // Add the new item to the feed const feedContent = getFeedContent() @@ -26,8 +35,8 @@ try { overwriteConfig({ ...config, retrospective: { - lastDay: data.lastDay, - nextDay: data.nextDay + lastDay, + nextDay } }) } catch (error) { diff --git a/utils/__tests__/utils.test.js b/utils/__tests__/utils.test.js index a63daeaee..b95059a05 100644 --- a/utils/__tests__/utils.test.js +++ b/utils/__tests__/utils.test.js @@ -1,6 +1,6 @@ import { describe, it } from 'node:test' -import { strictEqual } from 'node:assert/strict' -import { buildRFC822Date } from '../index.js' +import { strictEqual, match } from 'node:assert/strict' +import { buildRFC822Date, getCurrentRetroDate, getNextRetroDate } from '../index.js' describe('Utils', () => { describe('buildRFC822Date', () => { @@ -9,4 +9,136 @@ describe('Utils', () => { strictEqual(buildRFC822Date('2021-09-08T00:00:00.000+01:00'), 'Wed, 08 Sep 2021 01:00:00 BST') }) }) + + describe('getCurrentRetroDate', () => { + it('should return a date in YYYY-MM-DD format', () => { + const result = getCurrentRetroDate() + match(result, /^\d{4}-\d{2}-\d{2}$/) + }) + + it('should return a Sunday date', () => { + const result = getCurrentRetroDate() + const date = new Date(result + 'T00:00:00Z') + strictEqual(date.getUTCDay(), 0) // 0 = Sunday + }) + + it('should return a date in the past', () => { + const result = getCurrentRetroDate() + const resultDate = new Date(result + 'T00:00:00Z') + const today = new Date() + today.setUTCHours(0, 0, 0, 0) + strictEqual(resultDate < today, true) + }) + + it('should return previous Sunday when called on a Sunday', () => { + // Mock Date to be Sunday Feb 15, 2026 + const originalDate = globalThis.Date + const mockDate = class extends Date { + constructor (...args) { + if (args.length === 0) { + super('2026-02-15T12:00:00Z') + } else { + super(...args) + } + } + } + globalThis.Date = mockDate + + const result = getCurrentRetroDate() + strictEqual(result, '2026-02-08') + + globalThis.Date = originalDate + }) + + it('should return most recent Sunday when called on a weekday', () => { + // Mock Date to be Wednesday Feb 18, 2026 + const originalDate = globalThis.Date + const mockDate = class extends Date { + constructor (...args) { + if (args.length === 0) { + super('2026-02-18T12:00:00Z') + } else { + super(...args) + } + } + } + globalThis.Date = mockDate + + const result = getCurrentRetroDate() + strictEqual(result, '2026-02-15') + + globalThis.Date = originalDate + }) + + it('should return most recent Sunday when called on a Saturday', () => { + // Mock Date to be Saturday Feb 21, 2026 + const originalDate = globalThis.Date + const mockDate = class extends Date { + constructor (...args) { + if (args.length === 0) { + super('2026-02-21T12:00:00Z') + } else { + super(...args) + } + } + } + globalThis.Date = mockDate + + const result = getCurrentRetroDate() + strictEqual(result, '2026-02-15') + + globalThis.Date = originalDate + }) + + it('should handle year boundary correctly', () => { + // Mock Date to be Sunday Jan 4, 2026 + const originalDate = globalThis.Date + const mockDate = class extends Date { + constructor (...args) { + if (args.length === 0) { + super('2026-01-04T12:00:00Z') + } else { + super(...args) + } + } + } + globalThis.Date = mockDate + + const result = getCurrentRetroDate() + strictEqual(result, '2025-12-28') + + globalThis.Date = originalDate + }) + }) + + describe('getNextRetroDate', () => { + it('should return the date 7 days after the input', () => { + strictEqual(getNextRetroDate('2026-02-08'), '2026-02-15') + strictEqual(getNextRetroDate('2025-12-28'), '2026-01-04') + strictEqual(getNextRetroDate('2026-02-22'), '2026-03-01') + }) + + it('should return a date in YYYY-MM-DD format', () => { + const result = getNextRetroDate('2026-02-08') + match(result, /^\d{4}-\d{2}-\d{2}$/) + }) + + it('should handle year boundary correctly', () => { + strictEqual(getNextRetroDate('2025-12-28'), '2026-01-04') + strictEqual(getNextRetroDate('2025-12-21'), '2025-12-28') + }) + + it('should handle month boundaries correctly', () => { + strictEqual(getNextRetroDate('2026-01-25'), '2026-02-01') + strictEqual(getNextRetroDate('2026-03-29'), '2026-04-05') + strictEqual(getNextRetroDate('2026-07-26'), '2026-08-02') + }) + + it('should handle leap year correctly', () => { + // 2024 is a leap year + strictEqual(getNextRetroDate('2024-02-25'), '2024-03-03') + // 2025 is not a leap year + strictEqual(getNextRetroDate('2025-02-23'), '2025-03-02') + }) + }) }) diff --git a/utils/index.js b/utils/index.js index fd605bddc..c4900bce8 100644 --- a/utils/index.js +++ b/utils/index.js @@ -100,3 +100,43 @@ export function parseRetrospectiveContent (data) { const dates = title.split(dateRegex) return { title, description, lastDay: dates[1], nextDay: dates[3] } } + +/** + * Calculate the current week's retrospective date. + * Returns the date of the most recent Sunday (previous Sunday if today is Sunday). + * Retro files are named by the Sunday start date of the week they cover. + * @returns {string} Date in YYYY-MM-DD format + */ +export function getCurrentRetroDate () { + const today = new Date() + const day = today.getUTCDay() // 0=Sun, 1=Mon, ..., 6=Sat + + // Calculate days to the previous Sunday + // If today is Sunday (0), go back 7 days to get the previous Sunday + // Otherwise, go back 'day' days to reach the most recent Sunday + const daysBack = day === 0 ? 7 : day + + const targetDate = new Date(today) + targetDate.setUTCDate(today.getUTCDate() - daysBack) + + // Format as YYYY-MM-DD + const year = targetDate.getUTCFullYear() + const month = addLeadingZero(targetDate.getUTCMonth() + 1) + const dateNum = addLeadingZero(targetDate.getUTCDate()) + return `${year}-${month}-${dateNum}` +} + +/** + * Calculate the next week's retrospective date from a given date. + * @param {string} dateString - Date in YYYY-MM-DD format + * @returns {string} Date in YYYY-MM-DD format, 7 days later + */ +export function getNextRetroDate (dateString) { + const date = new Date(dateString + 'T00:00:00Z') + date.setUTCDate(date.getUTCDate() + 7) + + const year = date.getUTCFullYear() + const month = addLeadingZero(date.getUTCMonth() + 1) + const dateNum = addLeadingZero(date.getUTCDate()) + return `${year}-${month}-${dateNum}` +}