fix(release): build valid create-tree request in cleanup step#10
Merged
Conversation
The 'Cleanup staging and determine tag target' step failed with
'unexpected end of JSON input'. The else-branch sent a bare JSON array
to POST /git/trees (which requires {"tree":[...]}), and the if-branch
illegally combined 'gh api --input -' with '-f base_tree='. Both also
rebuilt the whole top-level tree by hand via string concatenation.
Replace both branches with a single base_tree + null-deletion path:
collect blob paths under .release/<version>/, build a proper request
body with jq, and POST it. base_tree inherits everything else, so other
.release/* dirs are preserved and the emptied dir drops automatically.
Signed-commit creation and main fast-forward are unchanged.
Collaborator
✅ Heimdall Review Status
|
0xRAG
approved these changes
Jun 3, 2026
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.
What changed? Why?
The release workflow failed at the
Cleanup staging and determine tag targetstep with:Root cause
For a release where
.release/<version>/is the only staging dir, the step took theelsebranch and sent a bare JSON array toPOST /git/trees:NEW_TREE_SHA=$(echo "${TREE_JSON}" | gh api ".../git/trees" --input - --jq ".sha")That endpoint requires an object
{"tree":[...]}, not a bare[...]. GitHub rejected the body, andgh api --jq ".sha"then ranjqover an empty/error response →unexpected end of JSON input.The other branch (when additional
.release/*dirs exist) was also broken: it combinedgh api --input -with-f base_tree=..., whichgh apirefuses (a stdin body is mutually exclusive with-f/-Ffields). Both branches additionally rebuilt the entire top-level tree by hand via string concatenation — fragile around file modes, executable bits, LFS pointers, and paths with spaces.Fix
Replace both branches with a single
base_tree+ null-deletion path:.release/<version>/withgit ls-tree -r --name-only.jq:{base_tree, tree:[{path,mode,type,sha:null}, ...]}.--input -(no-fmixing).sha:nulldeletes each blob;base_treeinherits everything else, so any other.release/*dirs are preserved automatically and the emptied.release/<version>/(plus.release/itself if it was the only version) drops out — git has no empty trees.Signed-commit creation (
POST /git/commits, author/committer omitted → GitHub-signed) and themainfast-forward are unchanged. Cleanup remains hard-fail: any API error still aborts before tagging.Net: +33 / −83 lines; deletes the brittle dual-branch string concatenation.
Verification
bash -non the extracted step body — syntax OK.jqpipeline emits valid{base_tree, tree:[...]}JSON withsha:nullpreserved, including paths containing spaces.Checklist
README) has been updated.type=routine
risk=low
impact=sev5