Skip to content

Ignore symlinked pull request templates#164

Open
skarim wants to merge 1 commit into
mainfrom
skarim/reject-symlink-templates
Open

Ignore symlinked pull request templates#164
skarim wants to merge 1 commit into
mainfrom
skarim/reject-symlink-templates

Conversation

@skarim

@skarim skarim commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator

gh stack submit and gh stack link prefill a new PR's body from the repository's pull request template. Template discovery in internal/pr read each candidate path with os.ReadFile, which follows symlinks. A template that is a symlink — for example .github/pull_request_template.md pointing to a file outside the repository — was therefore read through to its target, and that file's contents were used as the PR body.

This reuses cli/cli's githubtemplate package (already a dependency) for template discovery instead of the hand-rolled path list. It's the same code gh pr create uses, and it skips symlinked templates, so only regular template files inside the repository are read. FindTemplate keeps the same signature, so the submit and link callers are unchanged.

Behavior

  • A pull request template that is a symlink is ignored; submit / link fall back to the default PR body (commit message + footer) as if no template were present.
  • Two changes come with reusing githubtemplate:
    • YAML front-matter is stripped from the template, matching gh pr create.
    • Template filename matching is slightly broader — hyphenated (pull-request-template.md) and non-.md variants are now recognized.

Changes

internal/pr/template.go:

  • FindTemplate now delegates to githubtemplate.FindLegacy + githubtemplate.ExtractContents (trimmed), replacing the manual candidate-path list and os.ReadFile loop. Symlinked templates are skipped.

Testing

internal/pr/template_test.go:

  • Existing discovery tests still pass; adds a symlinked-template case (ignored), a front-matter-stripping case, and a hyphenated-filename case.

cmd/submit_test.go / cmd/link_test.go:

  • Adds gh stack submit --auto and gh stack link cases confirming a symlinked template is not read into the created PR body and the default footer body is used instead.

Stack created with GitHub Stacks CLIGive Feedback 💬

Template discovery in internal/pr read candidate template paths with
os.ReadFile, which follows symlinks. A pull request template that is a
symlink (for example .github/pull_request_template.md pointing to a file
outside the repository) would therefore be read through to its target, and
that target's contents would be used as the PR body by `gh stack submit`
and `gh stack link`.

Reuse cli/cli's githubtemplate package (already a dependency) for template
discovery instead of the hand-rolled path list. It is the same code
`gh pr create` uses, and it ignores symlinked templates, so only regular
template files inside the repository are read. FindTemplate keeps the same
signature, so the submit and link callers are unchanged.

Two behavior changes come with the switch:
- YAML front-matter is stripped from the template, matching `gh pr create`.
- Template filename matching is slightly broader; hyphenated and non-.md
  variants are now recognized.

Add tests for FindTemplate and for the `gh stack submit --auto` and
`gh stack link` PR-creation flows to confirm symlinked templates are not
followed.
Copilot AI review requested due to automatic review settings July 8, 2026 23:20

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

This PR fixes a subtle information-disclosure / correctness issue in PR template discovery. gh stack submit and gh stack link prefill a new PR body from the repository's pull request template; the previous implementation in internal/pr/template.go read candidate paths with os.ReadFile, which follows symlinks — so a symlinked pull_request_template.md pointing outside the repo would be read through to its target. The fix reuses cli/cli's githubtemplate package (the same code gh pr create uses), which ignores symlinked templates while keeping FindTemplate's signature intact.

Changes:

  • Replaced the manual candidate-path list + os.ReadFile loop with githubtemplate.FindLegacy + githubtemplate.ExtractContents (trimmed), so symlinked templates are skipped.
  • Side effects of the reuse: YAML front-matter is now stripped (matching gh pr create), and filename matching is broadened to hyphenated/non-.md variants.
  • Added tests for symlink-ignoring, front-matter stripping, and hyphenated names at the unit level, plus end-to-end coverage in submit and link.
Show a summary per file
File Description
internal/pr/template.go Delegates FindTemplate to githubtemplate.FindLegacy/ExtractContents, dropping the symlink-following os.ReadFile loop.
internal/pr/template_test.go Adds unit tests for symlink-ignored, front-matter-stripped, and hyphenated-name templates.
cmd/submit_test.go Adds submit --auto test confirming a symlinked template is not read into the PR body (footer fallback used).
cmd/link_test.go Adds link test confirming a symlinked template is not read into the PR body (footer fallback used).

Review details

  • Files reviewed: 4/4 changed files
  • Comments generated: 0
  • Review effort level: Medium

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants