Conversation
A Markdown file's relative links are written relative to the file, but a --body-file had to reference attached images relative to the working directory instead. References in a --body-file now resolve against the file's directory first and the working directory second, so references that matched before still match. --body and standard input still resolve against the working directory. The directory is a parameter of UploadAndAttach, so all six --attach commands resolve references the same way.
Contributor
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
The Windows drive-relative path branch lacks direct cross-platform regression coverage.
Review effort: Balanced
Findings: 1
Open (1)
What changed in this PR
Updates shared attachment handling so Markdown references from --body-file resolve relative to that file before falling back to the working directory.
Changes:
- Passes body-file directories through all six
--attachcommands. - Adds directory-aware attachment matching and tests.
- Updates command help and the
ghskill documentation.
| File | Description |
|---|---|
skills/gh/SKILL.md |
Documents reference resolution. |
pkg/cmd/pr/shared/commentable.go |
Passes body directories for comments. |
pkg/cmd/pr/shared/commentable_test.go |
Tests comment reference rewriting. |
pkg/cmd/pr/edit/edit.go |
Adds body-directory handling. |
pkg/cmd/pr/edit/edit_test.go |
Tests PR edit behavior. |
pkg/cmd/pr/create/create.go |
Adds body-directory handling. |
pkg/cmd/pr/create/create_test.go |
Tests PR creation behavior. |
pkg/cmd/pr/comment/comment.go |
Captures the body-file directory. |
pkg/cmd/pr/comment/comment_test.go |
Tests directory capture. |
pkg/cmd/issue/edit/edit.go |
Adds body-directory handling. |
pkg/cmd/issue/edit/edit_test.go |
Tests issue edit behavior. |
pkg/cmd/issue/create/create.go |
Adds body-directory handling. |
pkg/cmd/issue/create/create_test.go |
Tests issue creation behavior. |
pkg/cmd/issue/comment/comment.go |
Captures the body-file directory. |
pkg/cmd/issue/comment/comment_test.go |
Tests directory capture. |
internal/attachments/test.go |
Supports nested test assets. |
internal/attachments/references.go |
Implements directory-first matching. |
internal/attachments/references_test.go |
Covers reference-resolution scenarios. |
internal/attachments/references_fixture_test.go |
Updates the helper signature. |
internal/attachments/doc.go |
Documents the new parameter. |
internal/attachments/attach.go |
Propagates Markdown directories. |
internal/attachments/attach_test.go |
Tests uploader integration. |
💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+397
to
+400
| if path == "" || filepath.IsAbs(path) || filepath.VolumeName(path) != "" { | ||
| return false | ||
| } | ||
| return !os.IsPathSeparator(path[0]) |
gh issue artifact stack 1/10: Resolve --attach references against the body file's directorygh issue artifact stack 1/11: Resolve --attach references against the body file's directory
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Part of the pull request stack tracked in #14563.
This applies the reference rule from the
gh issue artifact createdesign in #14525 to the six commands that already have--attach.Description
--attachuploads a local image or video. If the body already references the file, gh replaces that reference with the uploaded URL. Otherwise it appends the file to the body.To match a reference to an attached file, gh compares absolute paths. Until now, every reference resolved against the working directory. That breaks a common layout: a Markdown file kept beside its images.
Running
gh issue create --body-file docs/plan.md --attach docs/signin-flow.pngfrom the project root looked for./signin-flow.pngin the root. Nothing matched, so gh left the local path in the body and appended the image at the end.A reference in a
--body-filenow resolves against that file's directory first. If that matches no attachment, it falls back to the working directory, so references that matched before still match.--bodyand standard input have no file, so they resolve against the working directory as before.The rule lives in the shared
--attachcode, sogh issue create,gh issue edit,gh issue comment,gh pr create,gh pr editandgh pr commentall follow it. Each command's help gains one sentence: "Paths in a--body-fileare relative to its directory, falling back to the working directory." Theghagent skill in this repository describes the same rule.How did you test this change?
I recorded all six commands against bagtoad/issue-artifacts-demo and read each stored body back with
gh. The video also covers the working-directory fallback, standard input and two attached files that share a name, but not absolute paths or Windows.recording.mp4
Open chapters and agent notes
Key points
Each way of reading a reference (as written, unescaped, percent-decoded) is tried beside the body file first, then in the working directory:
The file beside the body file wins. If
signin-flow.pnganddocs/signin-flow.pngare both attached,./signin-flow.pngindocs/plan.mdnow takes the one indocs/and the other is appended. Before, it took the one in the working directory. This only matters when a reference could name an attached file in either place.A reference that now matches follows the existing rules for matched references. So a video written as a reference-style image beside the body file is now refused before anything uploads, and the command exits 1. Before, that reference matched nothing, so gh appended the video, left the local path in the body and exited 0.
The directory is a required parameter of
UploadAndAttach, not an optional setting. Every caller has to say where its Markdown came from, and""means it came from no file. A new--attachcommand can't forget it.--body-file -sets no directory, since standard input has no folder:Only
--body-filesets a directory. A template's folder is never used, because template text is a starting point the user edits.The directory is the one in the path as typed. A symlinked body file resolves beside the link, not its target.
Notes for reviewers
Start with the lookup in the attachments package's
attachmentArgForDestination, then the new parameter onUploadAndAttach. The six commands only record the folder and pass it on, as ingh issue create.gh issue commentandgh pr commentshare the upload in the commentable code.gh issue artifact create#14525 show this rule for artifact documents, which later pull requests in this stack build on.Authorship and follow-up
Who wrote this:
Who answers review comments: