Source Loop
Fastest. Run Cargo checks or invoke the native binaries with cargo run. No install needed.
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.
There are three useful testing loops in this project. Pick the smallest one that proves the thing you changed.
Fastest. Run Cargo checks or invoke the native binaries with cargo run. No install needed.
Use this when testing the real ~/.local/bin/gh wrapper, release tarballs, Homebrew formula behavior, or installed entry points.
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.
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"
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
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
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 "$@"
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.
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.
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.
gh: check command -v gh and ensure ~/.local/bin is before the real GitHub CLI in PATH.gh: run gfj install-gui-path, then restart the GUI app.gfj config list and run gfj doctor.FJ_SHIM_HOSTS= for that process.