Skip to content

Commit 08b7b0c

Browse files
authored
🐱 [just] v4.0 adds PR update recipes (#44)
* 🐱 [just] v4.0 adds PR update recipes * update list of just recipes in docs * simplify bash strict modes * try guard against no PR * standardize check for being on a PR * initialize variable in awk to 0 * new check gets exit number 103 * update release notes for v4.0
1 parent db31533 commit 08b7b0c

File tree

3 files changed

+177
-5
lines changed

3 files changed

+177
-5
lines changed

.github/CONTRIBUTING.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,10 @@ Available recipes:
6666
[Process]
6767
branch branchname # start a new branch
6868
merge # merge PR and return to starting point
69-
pr # PR create 3.8
69+
pr # PR create v4.0
7070
pr_checks # watch GHAs then check for Copilot suggestions
71+
pr_update # update the Done section of PR description with current commits
72+
pr_verify # add or append to Verify section from stdin
7173
prweb # view PR in web browser
7274
release rel_version # make a release
7375
sync # escape from branch, back to starting point

.just/RELEASE_NOTES.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,36 @@ This file tracks the evolution of the Git/GitHub workflow automation module.
44

55
## November 2025 - The Polish Updates
66

7+
### v4.0 - PR Description Management (#44)
8+
9+
Added two new recipes for managing pull request descriptions dynamically:
10+
11+
- **`pr_update`** - Updates the "Done" section of the PR description with the
12+
current list of commits from the branch. Extracts commits using `git cherry`,
13+
preserves other sections (Meta, Verify, etc.), and updates the PR body via
14+
`gh pr edit`. Useful when you add commits after PR creation and want to keep
15+
the description in sync.
16+
17+
- **`pr_verify`** - Adds or appends content to a "Verify" section in the PR
18+
description. Reads from stdin, timestamps each entry, and formats as a code
19+
block. If no Verify section exists, creates one before the Meta section. If
20+
one exists, appends new timestamped entries. Perfect for logging test results
21+
or verification steps.
22+
23+
Both recipes include a new sanity check (`_on_a_pull_request`) that verifies
24+
you're on a branch with an active pull request before attempting updates. This
25+
prevents cryptic errors when running these commands outside of PR context.
26+
27+
Other improvements in this release:
28+
29+
- Simplified bash strict mode settings (removed `-x` tracing flag)
30+
- Standardized PR existence checks across recipes
31+
- Better error handling with exit code 103 for missing PRs
32+
- Initialize awk variables properly to avoid undefined behavior
33+
- Updated documentation to show new recipes
34+
35+
**Related PRs:** [#44](https://github.com/fini-net/template-repo/pull/44)
36+
737
### v3.9 - Shellcheck Error Fixes (#40)
838

939
Before adding the shellcheck tooling in v3.8bis, we knew there were a bunch of

.just/gh-process.just

Lines changed: 144 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,11 @@ sync:
1313
git pull
1414
git status --porcelain # stp
1515

16-
# PR create v3.9
16+
# PR create v4.0
1717
[group('Process')]
1818
pr: _has_commits && pr_checks
1919
#!/usr/bin/env bash
20-
set -euxo pipefail # strict mode
21-
set +x # leave tracing off...
20+
set -euo pipefail # strict mode
2221

2322
# handle optional pre-pr hook (for things like hugo)
2423
if [[ -e ".just/pr-hook.just" ]]; then
@@ -122,6 +121,18 @@ _main_branch:
122121
exit 102
123122
fi
124123

124+
# error if not on a branch with a pull request
125+
[group('sanity check')]
126+
[no-cd]
127+
_on_a_pull_request: _on_a_branch
128+
#!/bin/bash
129+
set -euo pipefail # strict mode
130+
131+
if \! gh pr view &>/dev/null; then
132+
echo "No PR found for current branch"
133+
exit 103
134+
fi
135+
125136
# print UTC date in ISO format
126137
[group('Utility')]
127138
[no-cd]
@@ -135,7 +146,7 @@ release rel_version:
135146

136147
# watch GHAs then check for Copilot suggestions
137148
[group('Process')]
138-
pr_checks:
149+
pr_checks: _on_a_pull_request
139150
#!/usr/bin/env bash
140151

141152
gh pr checks --watch -i 5
@@ -177,3 +188,132 @@ pr_checks:
177188
# did Claude comment?
178189
echo -e "\n\n🟧🟠🔶🔸 Claude:"
179190
gh pr view --json comments --jq '[.comments[] | select(.author.login == "claude")] | last | .body'
191+
192+
# update the Done section of PR description with current commits
193+
[group('Process')]
194+
pr_update: _on_a_pull_request
195+
#!/usr/bin/env bash
196+
set -euo pipefail # strict mode
197+
198+
CURRENT_BRANCH="$(git rev-parse --abbrev-ref HEAD)"
199+
200+
# get current PR body
201+
bodyfile=$(mktemp /tmp/justfile.XXXXXX)
202+
gh pr view --json body --jq '.body' > "$bodyfile"
203+
204+
# create new Done section
205+
new_done_section=$(mktemp /tmp/justfile.XXXXXX)
206+
{
207+
echo "## Done"
208+
echo ""
209+
git cherry -v "{{ release_branch }}" "$CURRENT_BRANCH" | sed -e 's/^[+] [0-9a-f]* /- /'
210+
echo ""
211+
} > "$new_done_section"
212+
213+
# extract everything after Done section (preserve other sections)
214+
other_sections=$(mktemp /tmp/justfile.XXXXXX)
215+
awk '/^## Done/,/^## / {if (/^## / && !/^## Done/) {found=1}} found {print}' "$bodyfile" > "$other_sections"
216+
217+
# if no other sections found after Done, preserve everything after Done
218+
if [ ! -s "$other_sections" ]; then
219+
# look for content after the Done section's commit list
220+
awk 'BEGIN {in_done=0; after_done=0; empty_count=0}
221+
/^## Done/ {in_done=1; next}
222+
in_done && /^$/ {empty_count++; if (empty_count >= 2) after_done=1; next}
223+
in_done && /^- / {next}
224+
after_done {print}' "$bodyfile" > "$other_sections"
225+
fi
226+
227+
# combine new Done section with preserved sections
228+
updated_body=$(mktemp /tmp/justfile.XXXXXX)
229+
cat "$new_done_section" "$other_sections" > "$updated_body"
230+
231+
echo ''
232+
cat "$updated_body"
233+
echo ''
234+
235+
# update PR body
236+
gh pr edit --body-file "$updated_body"
237+
238+
# cleanup
239+
rm "$bodyfile" "$new_done_section" "$other_sections" "$updated_body"
240+
241+
# add or append to Verify section from stdin
242+
[group('Process')]
243+
pr_verify: _on_a_pull_request
244+
#!/usr/bin/env bash
245+
set -euo pipefail # strict mode
246+
247+
# read stdin into a temp file
248+
stdin_content=$(mktemp /tmp/justfile.XXXXXX)
249+
cat > "$stdin_content"
250+
251+
# get current PR body
252+
bodyfile=$(mktemp /tmp/justfile.XXXXXX)
253+
gh pr view --json body --jq '.body' > "$bodyfile"
254+
255+
# get current datetime
256+
DATETIME=$(date '+%Y-%m-%d %H:%M:%S %Z')
257+
258+
# check if Verify section exists
259+
if grep -q '^## Verify' "$bodyfile"; then
260+
# append to existing Verify section
261+
updated_body=$(mktemp /tmp/justfile.XXXXXX)
262+
awk -v datetime="$DATETIME" '
263+
/^## Verify/ {
264+
in_verify=1
265+
print
266+
next
267+
}
268+
/^## / && in_verify {
269+
# found next section, insert content before it
270+
print ""
271+
print "### " datetime
272+
print ""
273+
print "```"
274+
system("cat '"$stdin_content"'")
275+
print "```"
276+
print ""
277+
in_verify=0
278+
}
279+
{ print }
280+
END {
281+
# if still in verify section at end, append content
282+
if (in_verify) {
283+
print ""
284+
print "### " datetime
285+
print ""
286+
print "```"
287+
system("cat '"$stdin_content"'")
288+
print "```"
289+
}
290+
}
291+
' "$bodyfile" > "$updated_body"
292+
else
293+
# create new Verify section before Meta section
294+
updated_body=$(mktemp /tmp/justfile.XXXXXX)
295+
awk -v datetime="$DATETIME" '
296+
/^## Meta/ {
297+
# insert Verify section before Meta
298+
print "## Verify"
299+
print ""
300+
print "### " datetime
301+
print ""
302+
print "```"
303+
system("cat '"$stdin_content"'")
304+
print "```"
305+
print ""
306+
}
307+
{ print }
308+
' "$bodyfile" > "$updated_body"
309+
fi
310+
311+
echo ''
312+
cat "$updated_body"
313+
echo ''
314+
315+
# update PR body
316+
gh pr edit --body-file "$updated_body"
317+
318+
# cleanup
319+
rm "$stdin_content" "$bodyfile" "$updated_body"

0 commit comments

Comments
 (0)