gh-forgejo-shim developer docs testing workflow

Testing During Development

Most changes can be tested directly from the checkout. Build a release-style archive only when you need to verify the installed gh wrapper or a GUI app such as Codex.app.

The Mental Model

There are three useful testing loops in this project. Pick the smallest one that proves the thing you changed.

Source Loop

Fastest. Run Cargo checks or invoke the native binaries with cargo run. No install needed.

Installed Wrapper Loop

Use this when testing the real ~/.local/bin/gh wrapper, release tarballs, Homebrew formula behavior, or installed entry points.

Codex.app Loop

Use this when validating GUI behavior. Refresh the installed package, restart the app when needed, and test a fresh action.

Rule of thumb: edit code, run Cargo checks repeatedly, then smoke a release-style install when you are ready to test the behavior as Codex.app or another external tool will see it.

Paths Used In Examples

Examples use $HOME so they work for any macOS user. On this machine, $HOME expands to /Users/kell. If your checkout is elsewhere, replace $HOME/dev/gh-forgejo-shim with your repo path.

cd "$HOME/dev/gh-forgejo-shim"

Rust Toolchain

The project builds with the stable Rust toolchain. Install rustfmt and clippy because CI treats formatting and warnings as release blockers.

rustup toolchain install stable --component rustfmt --component clippy
rustc --version
cargo --version

Fast Source Testing

Use this loop for normal implementation work. It exercises the Rust crate in your checkout, not an installed release artifact.

cargo fmt --all -- --check
cargo clippy --workspace --all-targets --locked -- -D warnings
cargo test --workspace --locked

Run focused tests while iterating on a specific behavior:

cargo test -p gh-forgejo-shim routing::tests::github_hosts_are_not_forgejo_hosts --locked
cargo test -p gh-forgejo-shim cli_scaffold --test cli_scaffold --locked

Run direct CLI smoke checks from the checkout with Cargo:

cargo run -p gh-forgejo-shim --bin gh-forgejo-shim -- --help
cargo run -p gh-forgejo-shim --bin gfj -- --version
cargo run -p gh-forgejo-shim --bin gfj -- doctor

Installed Runtime Smoke

Use this loop when the thing you are testing runs through installed gh, gfj, gh-forgejo-shim, or Codex.app.

scripts/package-release.sh
archive="$(find dist -maxdepth 1 -name 'gh-forgejo-shim-*.tar.gz' -print -quit)"
install_dir="$(mktemp -d)"
tar -xzf "$archive" -C "$install_dir"
"$install_dir/gfj" --version
"$install_dir/gh-forgejo-shim" --help

Install the managed wrapper into an isolated directory and verify that gh resolves to the wrapper while the wrapper targets the native binary.

shim_dir="$(mktemp -d)"
"$install_dir/gfj" install-shim --bin-dir "$shim_dir"
PATH="$shim_dir:$PATH" command -v gh
head -4 "$shim_dir/gh"
PATH="$shim_dir:$PATH" gh --version

A healthy managed wrapper starts like this:

#!/bin/sh
# managed by gh-forgejo-shim
# rollback-compatible marker: gh-forgejo-shim gh
# rust gh-forgejo-shim wrapper
exec /path/to/gh-forgejo-shim gh "$@"

Testing Codex.app Behavior

Codex.app sees the installed wrapper, not your checkout. For GUI-facing changes, install a native build, confirm the wrapper, and restart Codex.app if it was already open.

gfj install-shim --force
gfj doctor

For PR-link behavior, create a fresh pull request from Codex.app. The default gh pr create output should be shaped so Codex.app can discover a GitHub-style marker while the browser still opens the real Forgejo PR page:

https://forgejo-host/owner/repo/pulls/7#codex-pr=/pull/7

Old completed app runs will not retroactively pick up a new parser or output shape. Test with a new action after refreshing the installed shim.

Capturing Codex Probe Traces

When the app reports unavailable CLI, PR status, or branch data, capture the exact probes first. The shim only writes trace records when FJ_SHIM_TRACE is set.

export FJ_SHIM_TRACE="$PWD/codex-probe-trace.jsonl"
export FJ_SHIM_TRACE_BODY=1
gfj trace smoke
gfj trace summarize "$FJ_SHIM_TRACE"

For branch selector issues, add the temporary git recorder because those probes may bypass gh entirely:

gfj trace git-recorder create "$PWD/codex-probe-trace.jsonl"
# launch Codex with the printed PATH and FJ_SHIM_TRACE values
gfj trace git-recorder remove /path/to/printed/wrapper-dir

The trace includes command argv, cwd, route decision, host/repo, duration, exit code, output sizes, and redacted excerpts when body tracing is enabled. gh auth token output is never copied into excerpts.

Before Commit

A good pre-commit pass for code changes is:

cargo fmt --all -- --check
cargo clippy --workspace --all-targets --locked -- -D warnings
cargo test --workspace --locked
git diff --check

For documentation-only changes, still run a whitespace check on the touched files:

git diff --check -- docs/dev/testing.html

If you changed turn documents under docs/turns/, also follow the repository turn-document checks from AGENTS.md.

Common Failure Modes