From 51e29f1c9ab6a46bf79c7d9c245dcba45b3a9d91 Mon Sep 17 00:00:00 2001 From: Daniel Date: Fri, 16 Jan 2026 16:59:42 +0100 Subject: [PATCH 1/3] First attempt, at allowing custom github props for monorepos --- src/core/github.js | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/src/core/github.js b/src/core/github.js index e6d14bcda1..00fb932999 100644 --- a/src/core/github.js +++ b/src/core/github.js @@ -93,10 +93,22 @@ export async function run(conf) { } const branch = conf.github.branch || "gh-pages"; const issueBase = new URL("./issues/", ghURL).href; - const commitHistoryURL = new URL( - `./commits/${conf.github.branch ?? ""}`, - ghURL.href - ); + + // Allow custom pullsURL and commitsURL for monorepo scenarios + let pullsURL; + if (typeof conf.github === "object" && !conf.github.hasOwnProperty("pullsURL")) { + pullsURL = new URL("./pulls/", ghURL).href; + } else { + pullsURL = conf.github.pullsURL; + } + + let commitHistoryURL; + if (typeof conf.github === "object" && !conf.github.hasOwnProperty("commitHistoryURL")) { + commitHistoryURL = new URL(`./commits/${branch}`, ghURL.href).href; + } else { + commitHistoryURL = conf.github.commitHistoryURL; + } + const newProps = { edDraftURI: `https://${org.toLowerCase()}.github.io/${repo}/`, githubToken: undefined, @@ -104,7 +116,7 @@ export async function run(conf) { issueBase, atRiskBase: issueBase, otherLinks: [], - pullBase: new URL("./pulls/", ghURL).href, + pullBase: pullsURL, shortName: repo, }; // Assign new properties, but retain existing ones @@ -133,11 +145,11 @@ export async function run(conf) { }, { value: l10n.commit_history, - href: commitHistoryURL.href, + href: commitHistoryURL, }, { value: "Pull requests", - href: newProps.pullBase, + href: pullsURL, }, ], }; @@ -152,9 +164,9 @@ export async function run(conf) { apiBase: githubAPI, fullName: `${org}/${repo}`, issuesURL: issueBase, - pullsURL: newProps.pullBase, + pullsURL: pullsURL, newIssuesURL: new URL("./new/choose", issueBase).href, - commitHistoryURL: commitHistoryURL.href, + commitHistoryURL: commitHistoryURL, }; resolveGithubPromise(normalizedGHObj); From 78421c4ef9858d017f7f2069c59073f3832ab4f8 Mon Sep 17 00:00:00 2001 From: Daniel Date: Mon, 19 Jan 2026 12:42:47 +0100 Subject: [PATCH 2/3] Good variable name --- tests/spec/core/github-spec.js | 70 ++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/tests/spec/core/github-spec.js b/tests/spec/core/github-spec.js index 6581b9f36b..b3e58a6b51 100644 --- a/tests/spec/core/github-spec.js +++ b/tests/spec/core/github-spec.js @@ -81,6 +81,29 @@ describe("Core - Github", () => { const doc = await makeRSDoc(opts); doesntOverrideTest(doc); }); + it("normalizes github object with custom pullsURL and commitsURL", async () => { + const opts = { + config: Object.assign(makeBasicConfig(), { + github: { + repoURL: "https://github.com/w3c/core-aam/", + pullsURL: "https://github.com/w3c/aria/pulls/", + commitsURL: "https://github.com/w3c/aria/commits/", + }, + }), + body: makeDefaultBody(), + }; + delete opts.config.edDraftURI; + delete opts.config.shortName; + + const doc = await makeRSDoc(opts); + const { respecConfig: conf } = doc.defaultView; + + // Check that the github object is normalized correctly + expect(conf.github.pullsURL).toBe("https://github.com/w3c/aria/pulls/"); + expect(conf.github.commitHistoryURL).toBe("https://github.com/w3c/aria/commits/"); + expect(conf.github.issuesURL).toBe("https://github.com/w3c/core-aam/issues/"); + expect(conf.github.repoURL).toBe("https://github.com/w3c/core-aam/"); + }); }); describe("the definition list items (localized)", () => { const l10n = { @@ -135,5 +158,52 @@ describe("Core - Github", () => { "https://github.com/speced/respec/commits/develop" ); }); + it("supports custom pullsURL and commitsURL for monorepo scenarios", async () => { + const customOpt = { + config: Object.assign(makeBasicConfig(), { + github: { + repoURL: "https://github.com/w3c/core-aam/", + pullsURL: "https://github.com/w3c/aria/pulls/", + commitsURL: "https://github.com/w3c/aria/commits/", + }, + excludeGithubLinks: false, + }), + body: makeDefaultBody(), + htmlAttrs: { + lang: "nl", + }, + }; + delete customOpt.config.edDraftURI; + delete customOpt.config.shortName; + + const doc = await makeRSDoc(customOpt); + + // Check that the custom pull request URL is used + const pullRequests = Array.from(doc.querySelectorAll("dd")).find( + elem => elem.textContent.trim() === "Pull requests" + ); + expect(pullRequests).toBeTruthy(); + expect(pullRequests.querySelector("a").href).toBe( + "https://github.com/w3c/aria/pulls/" + ); + + // Check that the custom commit history URL is used + const commitHistory = Array.from(doc.querySelectorAll("dd")).find( + elem => elem.textContent.trim() === "Revisiehistorie" + ); + expect(commitHistory).toBeTruthy(); + expect(commitHistory.querySelector("a").href).toBe( + "https://github.com/w3c/aria/commits/" + ); + + // Issue base should still use repoURL + const fileABug = Array.from(doc.querySelectorAll("dd")).find( + elem => elem.textContent.trim() === "Dien een melding in" + ); + expect(fileABug).toBeTruthy(); + expect(fileABug.querySelector("a").href).toBe( + "https://github.com/w3c/core-aam/issues/" + ); + }); }); }); From 46ff022bf1fca07c9550d94150ee767ca8ddddeb Mon Sep 17 00:00:00 2001 From: Daniel Date: Mon, 19 Jan 2026 12:58:49 +0100 Subject: [PATCH 3/3] Add validation for custom pullsURL and commitHistoryURL values --- src/core/github.js | 44 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/src/core/github.js b/src/core/github.js index 00fb932999..c838bafd76 100644 --- a/src/core/github.js +++ b/src/core/github.js @@ -94,7 +94,7 @@ export async function run(conf) { const branch = conf.github.branch || "gh-pages"; const issueBase = new URL("./issues/", ghURL).href; - // Allow custom pullsURL and commitsURL for monorepo scenarios + // Allow custom pullsURL and commitHistoryURL for monorepo scenarios let pullsURL; if (typeof conf.github === "object" && !conf.github.hasOwnProperty("pullsURL")) { pullsURL = new URL("./pulls/", ghURL).href; @@ -102,6 +102,27 @@ export async function run(conf) { pullsURL = conf.github.pullsURL; } + // Validate pullsURL if it's provided + if (pullsURL) { + try { + const pullsURLObj = new URL(pullsURL); + if (pullsURLObj.origin !== "https://github.com") { + const msg = docLink`${"[github.pullsURL]"} must be HTTPS and pointing to GitHub. (${pullsURL}).`; + rejectGithubPromise(msg); + return; + } + if (!pullsURLObj.pathname.includes("/pulls")) { + const msg = docLink`${"[github.pullsURL]"} must point to pull requests. (${pullsURL}).`; + rejectGithubPromise(msg); + return; + } + } catch { + const msg = docLink`${"[github.pullsURL]"} is not a valid URL. (${pullsURL}).`; + rejectGithubPromise(msg); + return; + } + } + let commitHistoryURL; if (typeof conf.github === "object" && !conf.github.hasOwnProperty("commitHistoryURL")) { commitHistoryURL = new URL(`./commits/${branch}`, ghURL.href).href; @@ -109,6 +130,27 @@ export async function run(conf) { commitHistoryURL = conf.github.commitHistoryURL; } + // Validate commitHistoryURL if it's provided + if (commitHistoryURL) { + try { + const commitURLObj = new URL(commitHistoryURL); + if (commitURLObj.origin !== "https://github.com") { + const msg = docLink`${"[github.commitHistoryURL]"} must be HTTPS and pointing to GitHub. (${commitHistoryURL}).`; + rejectGithubPromise(msg); + return; + } + if (!commitURLObj.pathname.includes("/commit")) { + const msg = docLink`${"[github.commitHistoryURL]"} must point to commits. (${commitHistoryURL}).`; + rejectGithubPromise(msg); + return; + } + } catch { + const msg = docLink`${"[github.commitHistoryURL]"} is not a valid URL. (${commitHistoryURL}).`; + rejectGithubPromise(msg); + return; + } + } + const newProps = { edDraftURI: `https://${org.toLowerCase()}.github.io/${repo}/`, githubToken: undefined,