Visitar URL original
`gh issue artifact` stack 2/12: Attach one set of files to several Markdown documents by BagToad · Pull Request #14565 · cli/cli · GitHub
Skip to content

gh issue artifact stack 2/12: Attach one set of files to several Markdown documents - #14565

Open
BagToad wants to merge 1 commit into
bagtoad/artifact-attach-relative-pathsfrom
bagtoad/artifact-attach-documents
Open

BagToad wants to merge 1 commit into
bagtoad/artifact-attach-relative-pathsfrom
bagtoad/artifact-attach-documents

Conversation

@BagToad

@BagToad BagToad commented Oct 1, 2026 •

Copy link
Copy Markdown
Member

Part of the pull request stack tracked in #14563.

This adds the --attach behavior for several documents from the gh issue artifact create design in #14525, ahead of the command itself.

Description

--attach uploads a local image or video. If the Markdown already references the file, gh replaces that reference with the uploaded URL. Otherwise it appends the file to the Markdown.

Today this works on one body at a time. UploadAndAttach takes one Markdown string and one set of files. gh issue artifact create, later in this stack, creates one artifact from each Markdown file, and --attach applies to all of them:

gh issue artifact create 142 signin-plan.md barista-notes.md --attach signin-flow.png

Calling UploadAndAttach once per file would upload signin-flow.png twice. It would also append the image to any file that doesn't reference it.

The new UploadAndAttachDocuments takes several documents and one set of files:

  • It checks every document before the first upload. With several documents, a file that no document references is an error that names the file, and nothing is uploaded. There is no one body to append it to.
  • It uploads each file once, in order, and stops at the first failure, like UploadAndAttach. Every document that references a file gets that file's URL.
  • Each document resolves its references against its own directory first and the working directory second, the rule from the previous pull request in this stack.
  • Each document gets its own result: its Markdown, which of its files uploaded, and the upload error if one of its files failed or was never tried. create will use this to decide whether to save each artifact.

With one document, it behaves exactly like UploadAndAttach, including appending unreferenced files. No command calls it with several documents until gh issue artifact create.

How did you test this change?

I recorded a small program, not part of this pull request, passing Markdown files to UploadAndAttachDocuments in bagtoad/issue-artifacts-demo, then gh issue create --attach. The video covers a shared upload, each document's own folder, an unreferenced file, a failed upload and a single document, but not video attachments or the other five --attach commands.

recording.mp4

Open chapters and agent notes

Key points

UploadAndAttach now runs through the new code, as its one-document case:

// One document owns every file, so what it doesn't reference is appended
results, err := u.UploadAndAttachDocuments(ctx, []Document{{Markdown: md, Dir: markdownDir}}, assets)
if len(results) == 0 {
	// Refused before any upload, with md unchanged
	return md, UploadResult{}, err
}
  • One path keeps the upload order, the failure contract and the append rule from drifting apart. The six existing --attach commands and their tests don't change.
  • A document's attachments are the files it references, or every file when it is the only document. Each document fills in URLs only for its own attachments. A file a document references in a place gh can't rewrite, such as a reference definition continued onto the next line of a blockquote, is appended to that document, as UploadAndAttach already does. That way no upload is left unlinked.
  • An unreferenced file is reported as *UnreferencedError, with every such path as typed, in attach order. Its own message is no document references ./latte-art.png, and create can reword it the way [Design] gh issue artifact create #14525 shows. With no documents at all, every file is refused the same way.
  • A document's Err is the error that stopped the uploads, whenever it left one of that document's files without a URL. A document whose files all uploaded has no error, even if a later file fails. A caller saves a document when its Err is nil or its Uploaded isn't empty. create will save each artifact by that rule.
  • Uploaded lists the document's files rather than counting them, so a caller can name what reached the server. UploadResult keeps its count for the existing commands.

Notes for reviewers

Start with UploadAndAttachDocuments. Then read newAttachableDocuments, which makes every check before the first upload, and attach, which builds each document's result. The new table test has a row for each rule, and the existing TestUploaderUploadAndAttach table covers the one-document case.

Authorship and follow-up

Who wrote this:

  • A human wrote it.
  • An agent wrote it under close human direction.
  • An agent wrote it independently, and no human has guided the implementation beyond the initial prompt.

Who answers review comments:

  • @BagToad will read and reply directly. Name the account.
  • An agent will draft replies and @BagToad will read them before they are posted.
  • Nobody has explicitly committed to replying.

A command that takes several Markdown files, such as the planned
`gh issue artifact create`, needs --attach to work across all of them.
UploadAndAttachDocuments uploads each file once, in order, stopping at
the first failure, and gives every document that references a file the
same URL. Each document resolves its references against its own
directory and gets its own result, so the command can decide whether
to save it.

With several documents, a file that no document references has no body
to be appended to. It is refused before anything uploads, with an
error that names it. With one document, unreferenced files are still
appended, and UploadAndAttach now runs through the same code with one
document.
@BagToad
BagToad requested a review from a team as a code owner October 1, 2026 16:58
@BagToad
BagToad requested review from babakks and removed request for a team October 1, 2026 16:58
@BagToad
BagToad added this pull request to stack #14573 October 1, 2026 16:59
@BagToad BagToad changed the title gh issue artifact stack 2/10: Attach one set of files to several Markdown documents gh issue artifact stack 2/11: Attach one set of files to several Markdown documents Oct 2, 2026

@babakks babakks left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for putting this together, @BagToad! 🎉

The shared upload flow is thoughtfully structured, and the partial failure behavior is especially well covered by the tests. I left two minor comments about clarifying the per document error contract and preallocating the collected errors. This looks good to me overall.

Comment thread internal/attachments/attach.go
Comment thread internal/attachments/attach.go
@BagToad BagToad changed the title gh issue artifact stack 2/11: Attach one set of files to several Markdown documents gh issue artifact stack 2/12: Attach one set of files to several Markdown documents Oct 9, 2026

This branch has not been deployed

No deployments
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