actions/* + lib/* — one forge abstraction, two backends (#188) #189

Merged
andres merged 19 commits from build/188-forge-preflight into main 2026-08-04 09:52:22 +00:00
Showing only changes of commit 3885437f02 - Show all commits

View file

@ -653,12 +653,64 @@ subprocess_out="$(
subprocess_rc=$? subprocess_rc=$?
check "executable sweep transitions merged Refs work" 0 "" \ check "executable sweep transitions merged Refs work" 0 "" \
test "$subprocess_rc" -eq 0 test "$subprocess_rc" -eq 0
check "...reaches the transition through GraphQL and the issue loop" 0 "" \ check "...reaches the transition through the REST gather and the issue loop" 0 "" \
grep -qF '#40: merged Refs PR -> post-merge; claim released' <<<"$subprocess_out" grep -qF '#40: merged Refs PR -> post-merge; claim released' <<<"$subprocess_out"
check "...and performs the release edit from the executable path" 0 "" \ check "...and performs the release edit from the executable path" 0 "" \
grep -qF -- 'issue edit 40 -R owner/repo --remove-assignee builder --remove-label claimed --add-label post-merge' \ grep -qF -- 'issue edit 40 -R owner/repo --remove-assignee builder --remove-label claimed --add-label post-merge' \
"$ARRIVAL/fixtures/edits" "$ARRIVAL/fixtures/edits"
# -- the OPEN-pull gather, at main() granularity ----------------------------
# The closed/merged half above proves one REST path; this proves the other,
# which is a DIFFERENT pipeline: `.body | @base64` -> base64 -d ->
# closes_references -> OPEN_PR_ISSUES. The 27 parser cases in
# test/closes_references.test.sh cannot reach it — they test the parser, not
# the encoding and wiring around it (#188).
#
# Both directions in ONE sweep, so neither assertion can pass vacuously:
# #50 IS closed by an open PR -> the claim is KEPT, no reclaim edit
# #51 is closed by nothing -> the claim is RECLAIMED
# A break anywhere in the pipeline reclaims #50 too, and the first check
# fails. A break that reclaims nothing fails the second.
#
# `Closes #50` sits on the THIRD line of the body on purpose. jq's @tsv
# escapes a newline to a literal backslash-n, so a line-oriented parser
# reading an @tsv-encoded body sees one line and drops everything after the
# first — with the declaration on line 3, that defect reclaims #50 and this
# case goes red. On line 1 it would pass either way, which is the definition
# of a vacuous test.
printf '%s\n' \
'[{"number":500,"body":"## Summary\nSome prose about the work.\nCloses #50\n","merged_at":null}]' \
>"$ARRIVAL/fixtures/repos_owner_repo_pulls_state_open_per_page_100.json"
printf '[]\n' >"$ARRIVAL/fixtures/repos_owner_repo_pulls_state_closed_per_page_100.json"
printf '[{"number":50},{"number":51}]\n' \
>"$ARRIVAL/fixtures/repos_owner_repo_issues_state_open_per_page_100.json"
# Both claims are two hours quiet against a ONE-hour stale bound, so the
# reclaim clock has genuinely expired for whichever of them no open PR
# rescues. The clock is injected rather than real: INOW is a fixed epoch in
# 2033, so without ISSUEFLOW_NOW the subprocess reads its own wall clock,
# dates these claims in the future, and both survive on a negative age —
# which is a green test proving nothing.
for n in 50 51; do
jq -n --arg at "$(iso_at $((INOW - 7200)))" --argjson n "$n" \
'{number:$n,user:{login:"triage-one"},created_at:$at,body:"- [x] built",labels:[{name:"claimed"}],assignees:[{login:"builder"}]}' \
>"$ARRIVAL/fixtures/repos_owner_repo_issues_$n.json"
printf '[]\n' >"$ARRIVAL/fixtures/repos_owner_repo_issues_${n}_comments.json"
done
: >"$ARRIVAL/fixtures/edits"
open_pr_out="$(
env PATH="$ARRIVAL/stub:$PATH" GH_FIXTURES="$ARRIVAL/fixtures" \
CEREMONY_FORGE=github ISSUEFLOW_NOW="$INOW" ISSUEFLOW_STALE_HOURS=1 \
REPO=owner/repo LABELS_CONF="$ARRIVAL/labels.conf" \
bash "$ROOT/actions/issueflow-reconcile/issueflow-reconcile.sh" 2>&1
)"
check "the open-pull gather completes" 0 "" \
grep -qF 'issueflow: reconciled.' <<<"$open_pr_out"
check "a claim closed by an open PR survives the base64 round trip" 1 "" \
grep -qE 'issue edit 50 .*--remove-label claimed' "$ARRIVAL/fixtures/edits"
check "...while the claim no open PR closes is reclaimed in the same sweep" 0 "" \
grep -qE 'issue edit 51 .*--remove-label claimed --add-label ready' \
"$ARRIVAL/fixtures/edits"
# D2 preserved: only the deliberate stand-downs changed; a genuine failure on # D2 preserved: only the deliberate stand-downs changed; a genuine failure on
# the arrival path still kills the run loudly. # the arrival path still kills the run loudly.
: >"$ARRIVAL/fixtures/repos_owner_repo_issues_91.json.error" : >"$ARRIVAL/fixtures/repos_owner_repo_issues_91.json.error"