tooling: block fork PRs to upstream + fix web typecheck CI#63
Conversation
- pr-target-guard + gh wrapper + hapi-pr-create-fork (post-tiann#971) - web devDeps: remark-stringify, vfile, @types/mdast for remark-repair-tables Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fc4eba3216
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| pr_target_upstream_block_reason() { | ||
| local repo="$1" | ||
| shift | ||
| [[ "$repo" != "tiann/hapi" ]] && return 1 |
There was a problem hiding this comment.
Normalize host-qualified upstream repo targets
The gh manual documents --repo <[HOST/]OWNER/REPO>, so gh pr create --repo github.com/tiann/hapi ... is a valid way to target the same upstream repo. In that case pr_target_extract_repo_flag returns github.com/tiann/hapi, this exact comparison treats it as non-upstream, and fork-only diffs are allowed through despite targeting tiann/hapi. Normalize/strip the optional host before deciding whether to block.
Useful? React with 👍 / 👎.
| cp -a "$DEST" "${DEST}.prev" | ||
| echo "Backed up previous wrapper → ${DEST}.prev" | ||
| fi | ||
|
|
There was a problem hiding this comment.
Replace symlink destinations instead of following them
When ~/.local/bin/gh already exists as a symlink, this cp follows the symlink and writes the wrapper into the symlink target rather than replacing the link itself. On machines where gh is symlinked to a real binary or dotfiles-managed wrapper, running the installer can corrupt that target or fail before installing the guard; remove the destination first or copy with remove-destination semantics.
Useful? React with 👍 / 👎.
|
|
||
| REAL_GH="${HAPI_REAL_GH:-/usr/bin/gh}" | ||
|
|
||
| if [[ "${1:-}" == "pr" && "${2:-}" == "create" ]]; then |
There was a problem hiding this comment.
Intercept gh aliases and inherited flags
The gh manual lists gh pr new as an alias for create and -R/--repo as an inherited parent option, so valid invocations like gh --repo tiann/hapi pr create ... or gh pr new ... never enter this block. When an agent uses either form from the HAPI mirror, both the checklist and fork-only upstream block are skipped, leaving the accidental upstream PR path open; normalize the args before matching the subcommand/alias.
Useful? React with 👍 / 👎.
| branch="$(git -C "$PR_TARGET_GUARD_ROOT" rev-parse --abbrev-ref HEAD 2>/dev/null || true)" | ||
| paths="$(pr_target_fork_only_paths_in_diff "upstream/main...HEAD" | sort -u)" |
There was a problem hiding this comment.
Inspect the requested head branch for fork-only PRs
The gh manual documents --head <branch> as selecting the branch for the PR, but the guard always checks the current checkout and HEAD. If an agent runs gh pr create --repo tiann/hapi --head tooling/foo ... from another branch, the tooling/* branch name and fork-only diff on the requested head are not evaluated, so the upstream block can be bypassed even though the PR being created is for the infra branch. Parse --head and diff/check that branch instead of the current checkout when it is supplied.
Useful? React with 👍 / 👎.
Summary
gh repo viewin the HAPI mirror defaults totiann/hapi, so baregh pr createopened a cross-repo upstream PR for fork-only tooling. Addedlib/pr-target-guard.sh, canonicalgh-wrapper.sh(install viainstall-gh-wrapper.sh), andhapi-pr-create-forkdefaulting toheavygee/hapi:main.webtypecheck failed onremark-repair-tables(fix(web): mechanical repair of GFM tables with off-by-one separator rows tiann/hapi#902 merge) — missing explicit devDeps (remark-stringify,vfile,@types/mdast). ForkmainTest workflow has been red since before PR tooling: mechanical soup dist guards (#921/#962 class) #62.Test plan
bash scripts/tooling/pr-target-guard.test.shcd web && bun typecheckscripts/tooling/install-gh-wrapper.shon each machine (updates~/.local/bin/gh)Issues
Ref postmortem tiann#971 (closed 2026-06-24).