Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
14aa77f
feat(w3c): auto-refresh groups list every 24 hours
marcoscaceres Apr 26, 2026
256952a
fix(w3c): guard concurrent refresh and self-heal on corrupt JSON
marcoscaceres Apr 27, 2026
5f14fd3
Apply suggestions from code review
marcoscaceres Apr 27, 2026
c9c92b6
Apply suggestion from @Copilot
marcoscaceres Apr 27, 2026
e18c1fa
Apply suggestion from @Copilot
marcoscaceres Apr 27, 2026
edfd844
Apply suggestion from @Copilot
marcoscaceres Apr 27, 2026
4c64814
Apply suggestion from @Copilot
marcoscaceres Apr 27, 2026
8d47d75
Apply suggestion from @Copilot
marcoscaceres Apr 27, 2026
595b1b0
Apply suggestions from code review
marcoscaceres Apr 27, 2026
06a077c
fix(w3c): clean up group.ts - fix TDZ, duplicates, add retry/backoff
Copilot Apr 27, 2026
a85782b
Apply suggestion from @Copilot
marcoscaceres Apr 27, 2026
13f33f2
Apply suggestion from @Copilot
marcoscaceres Apr 27, 2026
153aa7e
Apply suggestion from @Copilot
marcoscaceres Apr 27, 2026
be80aca
Apply suggestion from @Copilot
marcoscaceres Apr 27, 2026
1314d8a
Merge branch 'main' into feat/auto-refresh-groups
marcoscaceres Apr 27, 2026
33c5e5f
fix(w3c): reloadGroups returns boolean, retry on any refresh failure
Copilot Apr 27, 2026
d3b6242
Merge branch 'main' into feat/auto-refresh-groups
marcoscaceres Apr 27, 2026
c840be6
Merge branch 'main' into feat/auto-refresh-groups
marcoscaceres Apr 28, 2026
9f88197
refactor(w3c): use BackgroundTaskQueue and webhook update model
marcoscaceres Apr 29, 2026
b2ecc13
fix(w3c): address Sid's review feedback on group update route
marcoscaceres May 3, 2026
4936436
fix(w3c): return 500 when groups reload fails after update
marcoscaceres May 3, 2026
6b4947e
Merge branch 'main' into feat/auto-refresh-groups
marcoscaceres May 15, 2026
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
1 change: 1 addition & 0 deletions .env.sample
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ DATA_DIR=/home/respec.org/data

# GitHub webhook secrets
W3C_WEBREF_SECRET=xxxxxxxxxxxxxxxxxxxxxx
W3C_GROUPS_SECRET=xxxxxxxxxxxxxxxxxxxxxx
CANIUSE_SECRET=xxxxxxxxxxxxxxxxxxxxxx
RESPEC_SECRET=xxxxxxxxxxxxxxxxxxxxxx
WEB_FEATURES_SECRET=xxxxxxxxxxxxxxxxxxxxxx
Expand Down
20 changes: 19 additions & 1 deletion routes/w3c/group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ type GroupType = "wg" | "cg" | "ig" | "bg" | "other";
export type Groups = Record<string, GroupMeta>;
export type GroupsByType = Record<GroupType, Groups>;

const groups: GroupsByType = JSON.parse(readFileSync(dataSource, "utf-8"));
const EMPTY_GROUPS: GroupsByType = { wg: {}, cg: {}, ig: {}, bg: {}, other: {} };

interface Group {
id: number;
Expand All @@ -32,6 +32,24 @@ interface Group {
}
const cache = new MemCache<Group>(ms("1 day"));

let groups: GroupsByType = EMPTY_GROUPS;
try {
groups = JSON.parse(readFileSync(dataSource, "utf-8"));
} catch (error) {
console.error("Failed to parse groups.json at startup:", error);
}

export function reloadGroups(): boolean {
try {
groups = JSON.parse(readFileSync(dataSource, "utf-8"));
cache.clear();
return true;
} catch (error) {
console.error("Failed to reload groups.json:", error);
return false;
}
}

// Support non W3C shortnames for backward compatibility.
const LEGACY_SHORTNAMES = new Map([
["wai-apa", "apa"],
Expand Down
5 changes: 5 additions & 0 deletions routes/w3c/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import { Router } from "express";
import cors from "cors";

import authGithubWebhook from "../../utils/auth-github-webhook.js";
import { env } from "../../utils/misc.js";

import groupsRoute from "./group.js";
import updateRoute from "./update.js";

const w3c = Router();
w3c.get("/groups{/:shortname}{/:type}", cors(), groupsRoute);
w3c.post("/update", authGithubWebhook(env("W3C_GROUPS_SECRET")), updateRoute);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What will trigger this webhook?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's supposed to be a cron job.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sidvishnoi sidvishnoi May 15, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A cron GitHub action in this repo, that sends a request to update endpoint? Will it have same payload format we expect in authGithubWebhook?

Edit: just saw #505 (comment)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, does that sound ok?


export default w3c;
28 changes: 28 additions & 0 deletions routes/w3c/update.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import path from "path";

import { Request, Response } from "express";

import { BackgroundTaskQueue } from "../../utils/background-task-queue.js";

import { reloadGroups } from "./group.js";

const workerFile = path.join(import.meta.dirname, "update.worker.js");
const taskQueue = new BackgroundTaskQueue<typeof import("./update.worker.ts")>(
workerFile,
"w3c_groups_update",
);

export default async function route(_req: Request, res: Response) {
const job = taskQueue.add();
try {
const { updated } = await job.run();
if (updated && !reloadGroups()) {
res.status(500);
}
} catch {
res.status(500);
} finally {
res.locals.job = job.id;
res.send(job.id);
}
}
11 changes: 11 additions & 0 deletions routes/w3c/update.worker.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import w3cGroupsScraper from "../../scripts/update-w3c-groups-list.js";

export default async function w3cGroupsUpdate() {
try {
await w3cGroupsScraper();
return { updated: true };
} catch (error) {
console.error("W3C groups update failed:", error);
return { updated: false };
}
}