Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": "</image>",
"discussionsInScope": [
Expand Down
25 changes: 17 additions & 8 deletions scripts/collect-retrospective.js
Original file line number Diff line number Diff line change
@@ -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: `<![CDATA[<p>${data.description}</p>]]>`,
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()
Expand All @@ -26,8 +35,8 @@ try {
overwriteConfig({
...config,
retrospective: {
lastDay: data.lastDay,
nextDay: data.nextDay
lastDay,
nextDay
}
})
} catch (error) {
Expand Down
136 changes: 134 additions & 2 deletions utils/__tests__/utils.test.js
Original file line number Diff line number Diff line change
@@ -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', () => {
Expand All @@ -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')
})
})
})
40 changes: 40 additions & 0 deletions utils/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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}`
}