ceremony/lib/issue_references.sh

29 lines
1.3 KiB
Bash
Raw Permalink Normal View History

fix(refs-not-closing): gather over REST, so the guard produces verdicts here The action's entire gather was one GraphQL query asking GitHub for its own parse of the closing keywords. Forgejo serves no GraphQL at all — /api/graphql 404s here and a forgejo-runner job arrives with GITHUB_GRAPHQL_URL empty — so there was nothing to translate it to. It is re-expressed, as #188 re-expressed its own two GraphQL sites, over two reads both backends serve plus this repo's own parser. The graph was called authoritative for including "closing keywords and sidebar links". Those halves resolve differently here: Forgejo has no sidebar-link concept, so nothing is lost there, but it DOES honour closing keywords in commit messages. A body-only port would miss a PR that closes an issue from a commit subject — exactly the contradiction this action exists to catch — so the closing set unions the body and every commit message. The hasNextPage refusal is relocated, not dropped: --paginate carries the forgejo backend's x-total-count completeness proof, and a short gather refuses rather than returning a partial verdict. lib/issue_references.sh extracts the LOCAL/CROSS classifier from issueflow-reconcile's executable. closes_references.sh's header recorded that dependency in prose; a composite action cannot source a reconciler to borrow one function, because sourcing a reconciler runs one. refs-guard.yml's github-only gate is removed in the same change. A portable action behind that gate is a guard that passes by never running. The contract test drives the boundary on BOTH backends with stubs at the transport. Mutations: body-only parse reds 4 cases, dropping --paginate reds the partial-gather case, ignoring a failed read reds 9. Refs #199
2026-08-05 17:11:19 +00:00
#!/usr/bin/env bash
# lib/issue_references.sh — the LOCAL / CROSS reference classifier (#61).
#
# Sourced, never executed: no set -e/-u — the sourcing script owns its shell
# options, as lib/closes_references.sh and lib/forge.sh do.
#
# WHY IT LIVES HERE. It was defined inside actions/issueflow-reconcile's
# executable, and lib/closes_references.sh's header recorded the resulting
# wart in prose: "DEPENDENCY: issue_references, from issueflow-reconcile.sh".
# That was tolerable while the reconciler was its only caller. #199 makes
# actions/refs-not-closing a second one, and a composite action cannot source
# another action's program to borrow one function — sourcing a reconciler
# runs a reconciler.
#
# So the dependency the comment described is now a file, and both callers
# source it the same way. Nothing about the classifier changed.
#
# A qualified reference belongs to another repository. The whole token is
# classified BEFORE any number is extracted, so `rig#112` can never be read
# as local `#112` — which is the entire point of the function.
issue_references() { # text on stdin -> LOCAL/CROSS<TAB>reference
{ grep -Eo '([[:alnum:]_.-]+/)?[[:alnum:]_.-]+#[0-9]+|#[0-9]+' || true; } \
| awk '
index($0, "#") == 1 { print "LOCAL\t" substr($0, 2); next }
{ print "CROSS\t" $0 }
'
}