Skip to content
8 changes: 6 additions & 2 deletions actions/setup/js/generate_history_link.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,15 @@ function generateHistoryUrl({ owner, repo, itemType, workflowCallId, workflowId,
throw new Error(`Invalid server URL: ${server}`);
}
})();
url.searchParams.set("q", queryParts.join(" "));
const encodedQuery = encodeURIComponent(queryParts.join(" "))
.replace(/[!'()*]/g, char => `%${char.charCodeAt(0).toString(16).toUpperCase()}`)
.replaceAll("%20", "+");

// Set the type parameter based on itemType for correct GitHub search filtering
const searchTypeMap = { issue: "issues", pull_request: "pullrequests", discussion: "discussions", comment: "issues", discussion_comment: "discussions" };
url.searchParams.set("type", searchTypeMap[itemType] ?? "issues");
const searchType = searchTypeMap[itemType] ?? "issues";

url.search = `q=${encodedQuery}&type=${searchType}`;

return url.toString();
}
Expand Down
26 changes: 26 additions & 0 deletions actions/setup/js/generate_history_link.test.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,32 @@ describe("generate_history_link.cjs", () => {
expect(url).toContain("gh-aw-workflow-call-id%3A+caller%2Frepo%2FWorkflowName");
});

it("should percent-encode both marker delimiter quotes for markdown-safe links", () => {
const url = generateHistoryUrl({
owner: "elastic",
repo: "docs-eng-team",
itemType: "issue",
workflowCallId: "elastic/docs-eng-team/gh-aw-issue-auto-triage",
serverUrl: "https://github.com",
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[/tdd] The negative assertion only guards against one specific raw-quote pattern; if the query structure changes, a raw " could sneak back in undetected.

💡 Stronger guard

Replace the narrow not.toContain with a blanket assertion that no unencoded quote survives:

expect(url).not.toContain('"');

This directly enforces the invariant the fix is meant to provide, regardless of where in the query a raw quote might appear.

@copilot please address this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Implemented in c55026b: strengthened the test to assert expect(url).not.toContain('"'), so any raw quote in the generated URL now fails the test.


expect(url).toContain("%22gh-aw-workflow-call-id%3A+elastic%2Fdocs-eng-team%2Fgh-aw-issue-auto-triage%22");
expect(url).not.toContain('"');
});

it("should percent-encode marker parentheses to preserve markdown-safe link targets", () => {
const url = generateHistoryUrl({
owner: "elastic",
repo: "docs-eng-team",
itemType: "issue",
workflowId: "triage(workflow)",
serverUrl: "https://github.com",
});

expect(url).toContain("gh-aw-workflow-id%3A+triage%28workflow%29");
expect(url).not.toContain("triage(workflow)");
});

it("should include workflow-id marker in search query when used", () => {
const url = generateHistoryUrl({
owner: "testowner",
Expand Down
Loading