Skip to content
Merged
21 changes: 14 additions & 7 deletions src/core/custom-elements/rs-changelog.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
* Optionally, a `path` parameter can be provided to filter commits to only
* those that affected a specific file or folder (useful for monorepos).
*
* Optionally, a `repo` parameter can be provided (e.g., "owner/repo") to
* fetch commits from a specific repository, overriding the default repository
* from respecConfig.github.
*
* @typedef {{message: string, hash: string}} Commit
*/
import { github } from "../github.js";
Expand All @@ -22,6 +26,7 @@ export const element = class ChangelogElement extends HTMLElement {
this.props = {
from: this.getAttribute("from"),
to: this.getAttribute("to") || "HEAD",
repo: this.getAttribute("repo"),
path: this.getAttribute("path"),
/** @type {(commit: Commit) => boolean} */
filter:
Expand All @@ -32,12 +37,12 @@ export const element = class ChangelogElement extends HTMLElement {
}

connectedCallback() {
const { from, to, filter, path } = this.props;
const { from, to, filter, repo, path } = this.props;
html.bind(this)`
<ul>
${{
any: fetchCommits(from, to, filter, path)
.then(commits => toHTML(commits))
any: fetchCommits(from, to, filter, repo, path)
.then(commits => toHTML(commits, repo))
.catch(error =>
showError(error.message, name, { elements: [this], cause: error })
)
Expand All @@ -51,15 +56,16 @@ export const element = class ChangelogElement extends HTMLElement {
}
};

async function fetchCommits(from, to, filter, path) {
async function fetchCommits(from, to, filter, repo, path) {
/** @type {Commit[]} */
let commits;
try {
const gh = await github;
if (!gh) {
throw new Error("`respecConfig.github` is not set");
}
const url = new URL("commits", `${gh.apiBase}/${gh.fullName}/`);
const fullName = repo || gh.fullName;
const url = new URL("commits", `${gh.apiBase}/${fullName}/`);
url.searchParams.set("from", from);
url.searchParams.set("to", to);
if (path) {
Expand All @@ -84,8 +90,9 @@ async function fetchCommits(from, to, filter, path) {
return commits;
}

async function toHTML(commits) {
const { repoURL } = await github;
async function toHTML(commits, repo) {
const gh = await github;
const repoURL = repo ? `https://github.com/${repo}/` : gh.repoURL;
return commits.map(commit => {
const [message, prNumber = null] = commit.message.split(/\(#(\d+)\)/, 2);
const commitURL = `${repoURL}commit/${commit.hash}`;
Expand Down
10 changes: 10 additions & 0 deletions tests/data/github/corp/repo/commits
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[
{
"hash": "80aad0a",
"message": "Editorial: Add privacy notice regarding <var> usage (#869)"
},
{
"hash": "276f4ba",
"message": "fix: ReSpec fixes"
}
]
16 changes: 16 additions & 0 deletions tests/spec/core/custom-elements/rs-changelog-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,20 @@ describe("Core - Custom Elements - <rs-changelog>", () => {
expect(commitLink.href).toBe("https://github.com/org/repo/commit/276f4ba");
expect(prLink.href).toBe("https://github.com/org/repo/pull/869");
});

it("uses custom repo parameter to override config", async () => {
const body = `<rs-changelog from="CR2" to="HEAD" repo="corp/repo"></rs-changelog>`;
const ops = makeStandardOps(conf, body);
const doc = await makeRSDoc(ops);

const commits = doc.querySelectorAll("rs-changelog li");
expect(commits).toHaveSize(2);
const firstCommit = commits[0];
// Verify links point to the custom repo, not the config repo
const links = firstCommit.querySelectorAll("a");
expect(links).toHaveSize(2);
const [commitLink, prLink] = links;
expect(commitLink.href).toBe("https://github.com/corp/repo/commit/80aad0a");
expect(prLink.href).toBe("https://github.com/corp/repo/pull/869");
});
});