Skip to content

Encode history-link query quotes to prevent footer markdown link breakage - #53978

Merged
pelikhan merged 9 commits into
mainfrom
copilot/fix-footer-related-runs-link
Aug 20, 2026
Merged

Encode history-link query quotes to prevent footer markdown link breakage#53978
pelikhan merged 9 commits into
mainfrom
copilot/fix-footer-related-runs-link

Conversation

Copilot AI commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

The footer’s related-runs link could render as raw markdown because the search query contained an unencoded opening " in the URL. GitHub markdown parsing then misread the link destination/title boundary and dropped link rendering.

  • History URL construction

    • Updated actions/setup/js/generate_history_link.cjs to build q with explicit percent-encoding and + space normalization.
    • This guarantees phrase delimiters around workflow markers are emitted as %22...%22 (no raw quote characters in the markdown link target).
  • Regression coverage

    • Added a focused test in actions/setup/js/generate_history_link.test.cjs asserting:
      • encoded wrapper %22gh-aw-workflow-call-id...%22 is present
      • raw +"gh-aw-workflow-call-id is absent
const encodedQuery = encodeURIComponent(queryParts.join(" ")).replaceAll("%20", "+");
url.search = `q=${encodedQuery}&type=${searchType}`;

Run: https://github.com/github/gh-aw/actions/runs/32326521694> Generated by 👨‍🍳 PR Sous Chef · gpt54 · 11.9 AIC · ⌖ 8.15 AIC · ⊞ 9.3K ·

Comment /souschef to run again


Generated by 👨‍🍳 PR Sous Chef · gpt54 · 8.85 AIC · ⌖ 9.55 AIC · ⊞ 9.3K ·
Comment /souschef to run again


Generated by 👨‍🍳 PR Sous Chef · gpt54 · 19.7 AIC · ⌖ 6.17 AIC · ⊞ 6K ·
Comment /souschef to run again

Copilot AI and others added 2 commits August 19, 2026 11:50
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix footer related runs link rendering issue Encode history-link query quotes to prevent footer markdown link breakage Aug 19, 2026
Copilot AI requested a review from pelikhan August 19, 2026 11:52
@pelikhan
pelikhan marked this pull request as ready for review August 19, 2026 11:53
Copilot AI balanced review requested due to automatic review settings August 19, 2026 11:53

Copilot AI left a comment

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.

Pull request overview

Encodes history-link search queries to prevent Markdown parsing failures.

Changes:

  • Explicitly percent-encodes search queries with + space normalization.
  • Adds regression coverage for encoded marker quotes.
Show a summary per file
File Description
actions/setup/js/generate_history_link.cjs Updates history URL serialization.
actions/setup/js/generate_history_link.test.cjs Tests quote encoding.

Review details

💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

  • Files reviewed: 2/2 changed files
  • Comments generated: 1
  • Review effort level: Balanced

}
})();
url.searchParams.set("q", queryParts.join(" "));
const encodedQuery = encodeURIComponent(queryParts.join(" ")).replaceAll("%20", "+");

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.

Addressed in 0c1e1ca: query encoding now additionally RFC3986-encodes characters left by encodeURIComponent (including parentheses), preserving markdown-safe link targets.

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot This PR looks close, but it still needs a maintainer-facing finish pass.

  • Please refresh the branch if needed.
  • Run the pr-finisher skill and leave a concise maintainer-visible handoff comment summarizing validation and any remaining risks.

Generated by 👨🍳 PR Sous Chef

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 14 AIC · ⌖ 8.19 AIC · ⊞ 9.3K ·
Comment /souschef to run again

@github-actions

github-actions Bot commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

PR Code Quality Reviewer completed the code quality review.

🔎 Code quality review by PR Code Quality Reviewer

@github-actions

github-actions Bot commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

🧠 Matt Pocock Skills Reviewer has completed the skills-based review. ✅

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer

@github-actions

github-actions Bot commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Test Quality Sentinel completed test quality analysis.

Test Quality Sentinel skipped because pre-fetch PR data was unavailable: unable to fetch test file diff

🧪 Test quality analysis by Test Quality Sentinel

@github-actions

github-actions Bot commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Ponytail Reviewer completed successfully!

Lean already. Ship.

Generated by Ponytail Reviewer for #53978

@github-actions

github-actions Bot commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Design Decision Gate 🏗️ completed the design decision gate check.

No ADR enforcement needed: PR #53978 does not have the 'implementation' label and has 0 new lines of code in business logic directories (threshold: 100).

🏗️ ADR gate enforced by Design Decision Gate 🏗️

@github-actions github-actions Bot left a comment

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.

The fix is correct and well-scoped. Switching from url.searchParams.set() to manual url.search assignment with encodeURIComponent ensures double-quote characters are encoded as %22, preventing markdown footer link breakage.

  • searchType values are hardcoded strings — no injection risk.
  • encodedQuery is already percent-encoded; no double-encoding occurs.
  • New test clearly documents and validates the expected encoding behaviour.

LGTM

🧵 Reviewed using Impeccable skills by Impeccable Skills Reviewer · sonnet46 · 21.2 AIC · ⌖ 8.8 AIC · ⊞ 5.7K

@github-actions

Copy link
Copy Markdown
Contributor

Comment Memory

reviewed_at: 2026-08-19T00:00:00Z
review_event: REQUEST_CHANGES
top_themes:
  - query-encoding regression
  - history search correctness
files_reviewed:
  - actions/setup/js/generate_history_link.cjs
  - actions/setup/js/generate_history_link.test.cjs
comment_count: 1

Note

This comment is managed by comment memory.

It stores persistent context for this thread in the code block at the top of this comment.
Edit only the text inside the backtick fences; workflow metadata and the footer are regenerated automatically.

Learn more about comment memory

🔎 Code quality review by PR Code Quality Reviewer · gpt54 · 5.47 AIC · ⌖ 6.92 AIC · ⊞ 7K ·
Comment /review to run again

@github-actions github-actions Bot left a comment

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.

Request changes

The quote-encoding fix is directionally right, but the implementation regresses the existing query encoding rules and can break history searches for workflow IDs containing parentheses.

Blocking theme
  • Replacing URLSearchParams with encodeURIComponent(...).replaceAll("%20", "+") is not behavior-preserving.
  • ( and ) are no longer escaped, while workflow IDs come from filenames and can legally include those characters.
  • That means some generated history links will stop matching the exact quoted marker they were supposed to search for.

🔎 Code quality review by PR Code Quality Reviewer · gpt54 · 5.47 AIC · ⌖ 6.92 AIC · ⊞ 7K
Comment /review to run again

}
})();
url.searchParams.set("q", queryParts.join(" "));
const encodedQuery = encodeURIComponent(queryParts.join(" ")).replaceAll("%20", "+");

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.

This manual encoding changes the query semantics: encodeURIComponent leaves ( and ) unescaped, so workflow IDs derived from filenames like build (nightly).md will produce a different q= than URLSearchParams did and can stop matching the exact quoted marker in GitHub search.

💡 Keep the markdown-safe quote fix without regressing other characters

The previous implementation was correctly delegating query-string encoding to URLSearchParams; the only broken part was the raw " delimiter in the final markdown link target. A safer fix is to keep searchParams for encoding and then post-process only the quote characters in the serialized URL, or explicitly encode with the same rules as form-urlencoding instead of encodeURIComponent.

url.searchParams.set("q", queryParts.join(" "));
url.searchParams.set("type", searchType);

// If markdown safety still requires it, normalize only raw quotes in the final URL
return url.toString().replaceAll('"', '%22');

That preserves the established encoding behavior for parentheses and any other characters GitHub search expects while still removing the raw quotes that break markdown rendering.

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.

Addressed by 0c1e1ca (RFC3986 encoding step) and validated by the parentheses regression test in actions/setup/js/generate_history_link.test.cjs.

@github-actions github-actions Bot mentioned this pull request Aug 19, 2026

@github-actions github-actions Bot left a comment

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.

Skills-Based Review 🧠

Applied /diagnosing-bugs and /tdd — the fix is correct and well-targeted; one minor test coverage suggestion.

📋 Key Themes & Highlights

Key Themes

  • Root cause properly addressed: switching from URLSearchParams.set() to manual encodeURIComponent() ensures quote characters are encoded as %22 rather than left raw in the URL, which was causing GitHub Markdown to misparse the link destination boundary.
  • Regression test present: the new test asserts both the positive case (%22...%22 wrapper is present) and a negative case (raw +"gh-aw-workflow-call-id is absent). One suggestion: the negative assertion is narrowly scoped (see inline comment).
  • Existing concern (already raised): encodeURIComponent leaves ( and ) unencoded, unlike URLSearchParams. If workflow IDs can contain parentheses, this could produce a different kind of markdown breakage.

Positive Highlights

  • ✅ Minimal, surgical change — only the URL construction lines are touched
  • ✅ Regression test added alongside the fix
  • ✅ PR description clearly explains the root cause and the encoding contract

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · sonnet46 · 26.3 AIC · ⌖ 9.95 AIC · ⊞ 7.8K
Comment /matt to run again

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.

Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>

Copilot AI commented Aug 19, 2026

Copy link
Copy Markdown
Contributor Author

@copilot This PR looks close, but it still needs a maintainer-facing finish pass.

  • Please refresh the branch if needed....

Implemented in 0c1e1ca.

Maintainer handoff:

  • Branch was already current with main (no refresh needed).
  • Addressed the remaining encoding gap by RFC3986-encoding characters left by encodeURIComponent ([!'()*]) before %20 -> +, and added a regression test for workflow IDs containing parentheses.
  • Validation: npm run test:js -- generate_history_link.test.cjs --no-file-parallelism passed (35/35).
  • CI/log check: inspected workflow runs via MCP and fetched logs for run 32250318499; no failed jobs there.

Remaining risk:

  • make agent-report-progress / make agent-report-progress-no-test currently fail in this environment at JavaScript lint due to pre-existing TypeScript config/runtime mismatch (TS2688 missing node types and TS5108 moduleResolution=node10 removed), so full local lint gate is not green here.
  • CI for the new HEAD is stale until a maintainer re-triggers workflows.

@github-actions

Copy link
Copy Markdown
Contributor

PR Triage

  • Category: bug
  • Risk: low
  • Priority score: 39 / 100 (impact 15 + urgency 10 + quality 14)
  • Recommended action: batch_review

Batch: B1-small-fixes-refactors

Tiny fix (add:32/del:2) encoding query quotes in footer links. Good candidate for grouped review with other small B1 fixes.

Automated triage by PR Triage Agent.

Generated by 🔧 PR Triage Agent · auto · 57.1 AIC · ⌖ 2.88 AIC · ⊞ 8.3K ·

@pelikhan

Copy link
Copy Markdown
Collaborator

@copilot merge main and lint js

Copilot AI and others added 2 commits August 20, 2026 02:06
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
…fix-footer-related-runs-link

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>

Copilot AI commented Aug 20, 2026

Copy link
Copy Markdown
Contributor Author

@copilot merge main and lint js

Done in 981c30c.

  • Merged latest origin/main into this branch after unshallow + explicit fetch.
  • Ran JS lint with make lint-cjs (passes: 0 errors, warnings only).
  • Re-ran targeted JS test: actions/setup/js generate_history_link.test.cjs (35/35 passing).

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot Sous-chef triage: please investigate this PR and move it toward merge readiness. Refresh the branch if needed, review any unresolved feedback, and run the pr-finisher skill before your next update.

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 11.9 AIC · ⌖ 8.15 AIC · ⊞ 9.3K ·
Comment /souschef to run again

Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>

Copilot AI commented Aug 20, 2026

Copy link
Copy Markdown
Contributor Author

@copilot Sous-chef triage: please investigate this PR and move it toward merge readiness. Refresh the branch if needed, review any unresolved feedback, and run the pr-finisher skill before your next...

Done in c55026b.

  • pr-finisher + copilot-review skills were run.
  • Branch is current with origin/main (ahead 12, behind 0), so no refresh merge was needed.
  • Addressed remaining in-scope unresolved feedback by strengthening the regression guard in /home/runner/work/gh-aw/gh-aw/actions/setup/js/generate_history_link.test.cjs to assert no raw quotes remain in the generated URL.
  • Replied to all in-scope open review comments from trusted automation.

Validation run:

  • make fmt
  • make lint
  • make test-unit
  • make test
  • make recompile
  • BASE_REF=origin/main make agent-report-progress

CI snapshot:

  • Reviewed PR workflow runs via MCP (actions_list + get_job_logs); latest PR CJS run 32323934077 is successful and reports no failed jobs.

Remaining risk / handoff:

  • CI on the current agent-pushed HEAD is stale until a maintainer re-triggers workflows.

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot quick triage for this PR:

Unresolved review threads:

Please refresh the branch if needed, address the items above, and then run the pr-finisher skill.

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 8.85 AIC · ⌖ 9.55 AIC · ⊞ 9.3K ·
Comment /souschef to run again

Copilot AI commented Aug 20, 2026

Copy link
Copy Markdown
Contributor Author

@copilot quick triage for this PR:

Unresolved review threads:...

Triage pass complete.

  • Branch refresh: not needed (copilot/fix-footer-related-runs-link is ahead/behind 13/0 vs origin/main).
  • Linked threads:
    • #discussion_r3812733790 already addressed by 0c1e1ca (RFC3986 post-encoding of encodeURIComponent leftovers).
    • #discussion_r3812802119 already addressed by 0c1e1ca (same fix + regression coverage).
    • #discussion_r3812809050 already addressed by c55026b (expect(url).not.toContain('"') guard).

Validation run in this pass:

  • make fmt
  • make lint
  • make test-unit
  • make test ❌ (pre-existing unrelated failure in pkg/cli completion tests: write |1: file already closed, e.g. TestCompletionCommand_Bash/Zsh/Fish/PowerShell...)

CI/log triage via MCP:

  • Reviewed branch workflow runs with actions_list.
  • Pulled failed-job logs for run 32257302132; failure was lint-js Prettier drift (eslint-factory/src/rules/no-exec-interpolated-command.test.ts), which is not present on current HEAD and was addressed by subsequent commits.

No additional code changes were required in this pass.

@github-actions

Copy link
Copy Markdown
Contributor

PR Triage

Category: bug | Risk: low | Priority: low (score 37/100)
Score breakdown: impact 12 + urgency 10 + quality 15
Recommended action: batch_review
Batch: B1-small-fixes-refactors
Fixes footer markdown link breakage from unencoded quotes in history-link URLs. A prior approval was dismissed after a follow-up push — needs fresh review.

Generated by 🔧 PR Triage Agent · auto · 62.9 AIC · ⌖ 7.05 AIC · ⊞ 8.3K ·

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot Please do a maintainer-facing finish pass on this PR.

  • Confirm the current head is still merge-ready for the latest branch state.
  • Refresh the branch if GitHub offers one.
  • Run the pr-finisher skill and leave a concise handoff comment with validation status and any remaining merge risks.

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 8.85 AIC · ⌖ 9.4 AIC · ⊞ 9.3K ·
Comment /souschef to run again

Copilot AI commented Aug 20, 2026

Copy link
Copy Markdown
Contributor Author

@copilot Please do a maintainer-facing finish pass on this PR.

  • Confirm the current head is still merge-ready for the latest branch state....

Finish pass completed on current HEAD def27e2.

  • Branch refresh: not needed (copilot/fix-footer-related-runs-link is ahead of origin/main, not behind).
  • Local validation on this branch state:
    • make fmt
    • make lint
    • make test-unit
    • make test
    • make recompile
  • CI triage via MCP:
    • Reviewed recent runs for this PR branch (actions_list).
    • Checked failed-job logs (get_job_logs) for latest CJS run 32336718114 (no failed jobs reported) and last explicit failure run 32257302132 (historical lint-js prettier drift).

Remaining merge risks:

  • GitHub currently reports PR as blocked with unresolved review threads still marked open in UI.
  • CI on the latest head remains maintainer-unverified until workflows are re-triggered by a human push/dispatch/close-reopen.

@github-actions

Copy link
Copy Markdown
Contributor

PR Triage

Category: bug · Risk: low · Score: 35/100 · Action: defer
Batch: B1-small-fixes-refactors

Small fix, CI passing, but flagged needs-rework in a prior triage pass — verify before promoting.

Automated triage — see the triage report issue for full context.

Generated by 🔧 PR Triage Agent · auto · 67 AIC · ⌖ 10.2 AIC · ⊞ 8.3K ·

@pelikhan
pelikhan merged commit 423b54a into main Aug 20, 2026
10 checks passed
@pelikhan
pelikhan deleted the copilot/fix-footer-related-runs-link branch August 20, 2026 15:38
@github-actions

Copy link
Copy Markdown
Contributor

🎉 This pull request is included in a new release.

Release: v0.87.2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Footer 'related runs' link leaks as raw markdown due to unencoded double-quote in search URL

4 participants