fix: update OSS weekend gating and messaging

This commit is contained in:
Mario Zechner
2026-04-02 11:15:19 +02:00
parent 617f1870f8
commit 71f3e50a16
6 changed files with 48 additions and 44 deletions

View File

@@ -1,9 +1,10 @@
{
"active": true,
"mode": "weekend",
"startsAt": "2026-03-27T01:31:56.951Z",
"startsAtText": "Friday, March 27, 2026",
"reopensOn": "2026-04-06",
"reopensOnText": "Monday, April 6, 2026",
"startsAt": "2026-04-02T09:13:17.643Z",
"startsAtText": "Thursday, April 2, 2026",
"reopensOn": "2026-04-13",
"reopensOnText": "Monday, April 13, 2026",
"reason": "at the moment i'm deep in refactoring internals, and need to focus.",
"discordUrl": "https://discord.com/invite/3cU7Bz4UPx"
}

View File

@@ -57,6 +57,13 @@ jobs:
return;
}
const approvedContent = await getTextFile('.github/APPROVED_CONTRIBUTORS');
const approvedList = approvedContent
.split('\n')
.map(line => line.trim().toLowerCase())
.filter(line => line && !line.startsWith('#'));
const isApprovedContributor = approvedList.includes(issueAuthor.toLowerCase());
let weekendState;
try {
weekendState = JSON.parse(await getTextFile('.github/oss-weekend.json'));
@@ -73,12 +80,19 @@ jobs:
return;
}
if (isApprovedContributor) {
console.log(`${issueAuthor} is in the approved contributors list`);
return;
}
const reopenDate = weekendState.reopensOnText || weekendState.reopensOn || 'after the weekend';
const discordUrl = weekendState.discordUrl || 'https://discord.com/invite/3cU7Bz4UPx';
const reason = typeof weekendState.reason === 'string' && weekendState.reason.trim() ? weekendState.reason.trim() : null;
const message = [
`Hi @${issueAuthor}, thanks for opening an issue.`,
'',
`OSS weekend is active until ${reopenDate}, so new issues are being auto-closed for now.`,
`OSS weekend is active until ${reopenDate}, so new issues from unapproved contributors are being auto-closed for now.`,
...(reason ? ['', `Current focus: ${reason}`] : []),
'',
`Please reopen or submit this issue again after ${reopenDate}. For support, join [Discord](${discordUrl}).`,
].join('\n');

View File

@@ -81,34 +81,6 @@ jobs:
.filter(line => line && !line.startsWith('#'));
const isApprovedContributor = approvedList.includes(prAuthor.toLowerCase());
let weekendState = null;
try {
weekendState = JSON.parse(await getTextFile('.github/oss-weekend.json'));
} catch (error) {
if (!(error && typeof error === 'object' && 'status' in error && error.status === 404)) {
throw error;
}
}
if (weekendState?.active && isApprovedContributor) {
console.log(`${prAuthor} is approved, but OSS weekend is active`);
const reopenDate = weekendState.reopensOnText || weekendState.reopensOn || 'after the weekend';
const discordUrl = weekendState.discordUrl || 'https://discord.com/invite/3cU7Bz4UPx';
const message = [
`Hi @${prAuthor}, thanks for the PR.`,
'',
`OSS weekend is active until ${reopenDate}, so external PRs are being paused for now.`,
'',
'You are already on the approved contributors list, so you can resubmit this PR after the weekend without reapproval.',
'',
`This PR will be closed automatically. For support, join [Discord](${discordUrl}).`,
].join('\n');
await closePullRequest(message);
return;
}
if (isApprovedContributor) {
console.log(`${prAuthor} is in the approved contributors list`);
return;

View File

@@ -1,9 +1,11 @@
<!-- OSS_WEEKEND_START -->
# 🏖️ OSS Weekend
**Issue tracker reopens Monday, April 6, 2026.**
**Issue tracker reopens Monday, April 13, 2026.**
OSS weekend runs Friday, March 27, 2026 through Monday, April 6, 2026. New issues are auto-closed during this time. For support, join [Discord](https://discord.com/invite/3cU7Bz4UPx).
OSS weekend runs Thursday, April 2, 2026 through Monday, April 13, 2026. New issues and PRs from unapproved contributors are auto-closed during this time. Approved contributors can still open issues and PRs. For support, join [Discord](https://discord.com/invite/3cU7Bz4UPx).
Current focus: at the moment i'm deep in refactoring internals, and need to focus.
<!-- OSS_WEEKEND_END -->
---

View File

@@ -1,9 +1,11 @@
<!-- OSS_WEEKEND_START -->
# 🏖️ OSS Weekend
**Issue tracker reopens Monday, April 6, 2026.**
**Issue tracker reopens Monday, April 13, 2026.**
OSS weekend runs Friday, March 27, 2026 through Monday, April 6, 2026. New issues are auto-closed during this time. For support, join [Discord](https://discord.com/invite/3cU7Bz4UPx).
OSS weekend runs Thursday, April 2, 2026 through Monday, April 13, 2026. New issues and PRs from unapproved contributors are auto-closed during this time. Approved contributors can still open issues and PRs. For support, join [Discord](https://discord.com/invite/3cU7Bz4UPx).
Current focus: at the moment i'm deep in refactoring internals, and need to focus.
<!-- OSS_WEEKEND_END -->
---

View File

@@ -9,6 +9,11 @@ const MARKER_START = "<!-- OSS_WEEKEND_START -->";
const MARKER_END = "<!-- OSS_WEEKEND_END -->";
const DISCORD_URL = "https://discord.com/invite/3cU7Bz4UPx";
function normalizeReason(reason) {
const trimmedReason = reason.trim();
return trimmedReason ? trimmedReason : null;
}
function parseArgs(argv) {
const options = {};
@@ -69,9 +74,10 @@ function parseDateInput(value) {
return new Date(Date.UTC(Number(year), Number(month) - 1, Number(day), 12, 0, 0));
}
function buildBanner(now, endDate) {
function buildBanner(now, endDate, reason) {
const startDate = formatLongDate(now);
const reopenDate = formatLongDate(endDate);
const normalizedReason = normalizeReason(reason ?? "");
return [
MARKER_START,
@@ -79,7 +85,8 @@ function buildBanner(now, endDate) {
"",
`**Issue tracker reopens ${reopenDate}.**`,
"",
`OSS weekend runs ${startDate} through ${reopenDate}. New issues are auto-closed during this time. For support, join [Discord](${DISCORD_URL}).`,
`OSS weekend runs ${startDate} through ${reopenDate}. New issues and PRs from unapproved contributors are auto-closed during this time. Approved contributors can still open issues and PRs. For support, join [Discord](${DISCORD_URL}).`,
...(normalizedReason ? ["", `Current focus: ${normalizedReason}`] : []),
MARKER_END,
"",
"---",
@@ -88,8 +95,8 @@ function buildBanner(now, endDate) {
].join("\n");
}
function upsertBanner(readme, now, endDate) {
const banner = buildBanner(now, endDate);
function upsertBanner(readme, now, endDate, reason) {
const banner = buildBanner(now, endDate, reason);
const bannerPattern = new RegExp(
`${escapeRegExp(MARKER_START)}[\\s\\S]*?${escapeRegExp(MARKER_END)}\\n\\n---\\n\\n?`,
"m",
@@ -121,7 +128,9 @@ function parseReadmePaths(cliOptions) {
.filter(Boolean);
}
function buildState(now, endDateInput, endDate) {
function buildState(now, endDateInput, endDate, reason) {
const normalizedReason = normalizeReason(reason ?? "");
return JSON.stringify(
{
active: true,
@@ -130,6 +139,7 @@ function buildState(now, endDateInput, endDate) {
startsAtText: formatLongDate(now),
reopensOn: endDateInput,
reopensOnText: formatLongDate(endDate),
reason: normalizedReason,
discordUrl: DISCORD_URL,
},
null,
@@ -229,6 +239,7 @@ function printUsage() {
" --end-date=YYYY-MM-DD Required for --mode=close.",
" --readme=PATHS Optional comma-separated README paths. Defaults to README.md,packages/coding-agent/README.md.",
" --state=PATH Optional state file path. Defaults to .github/oss-weekend.json.",
" --reason=TEXT Optional reason shown in the README banner and weekend auto-close comments.",
" --git Stage only the OSS weekend files, commit, and push after updating them.",
" --dry-run Preview without editing files or running git operations.",
" --now=ISO Optional current timestamp override for testing.",
@@ -257,6 +268,7 @@ async function main() {
const readmePaths = parseReadmePaths(cliOptions);
const statePath = getOption("state", cliOptions, "OSS_WEEKEND_STATE_PATH", DEFAULT_STATE_PATH);
const endDateInput = getOption("end-date", cliOptions, "OSS_WEEKEND_END_DATE", "");
const reason = normalizeReason(getOption("reason", cliOptions, "OSS_WEEKEND_REASON", ""));
const now = nowInput ? new Date(nowInput) : new Date();
if (Number.isNaN(now.getTime())) {
@@ -272,7 +284,7 @@ async function main() {
for (const readmePath of readmePaths) {
const currentReadme = await readFile(readmePath, "utf8");
const nextReadme = mode === "close" ? upsertBanner(currentReadme, now, endDate) : removeBanner(currentReadme);
const nextReadme = mode === "close" ? upsertBanner(currentReadme, now, endDate, reason) : removeBanner(currentReadme);
const changed = nextReadme !== currentReadme;
if (changed && !dryRun) {
@@ -283,7 +295,7 @@ async function main() {
}
const currentState = await readOptionalFile(statePath);
const nextState = mode === "close" ? buildState(now, endDateInput, endDate) : null;
const nextState = mode === "close" ? buildState(now, endDateInput, endDate, reason) : null;
const stateChanged = mode === "close" ? currentState !== nextState : currentState !== null;
if (!dryRun) {
@@ -317,6 +329,7 @@ async function main() {
git_commands: gitResult ? gitResult.commands.join(" && ") : "",
end_date: endDate ? endDateInput : "",
end_date_text: endDate ? formatLongDate(endDate) : "",
reason: reason ?? "",
now_utc: now.toISOString(),
now_berlin: new Intl.DateTimeFormat("sv-SE", {
timeZone: TIME_ZONE,