diff --git a/actions/setup/js/generate_history_link.cjs b/actions/setup/js/generate_history_link.cjs index eb5700990db..1e6a5df086d 100644 --- a/actions/setup/js/generate_history_link.cjs +++ b/actions/setup/js/generate_history_link.cjs @@ -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(); } diff --git a/actions/setup/js/generate_history_link.test.cjs b/actions/setup/js/generate_history_link.test.cjs index 442f7483392..05cffc6f0c8 100644 --- a/actions/setup/js/generate_history_link.test.cjs +++ b/actions/setup/js/generate_history_link.test.cjs @@ -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", + }); + + 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",