Project setup#

pw_ghish: GitHub CLI-like interface for Gerrit code reviews and CI checks

Warning

NOT READY FOR EXTERNAL PROJECTS: pw_ghish is currently experimental for upstream Pigweed and is not ready for adoption outside Pigweed yet. Several Pigweed-specific assumptions still exist in the codebase while multi-project abstractions are being completed. See Status & roadmap for current status and planned work to decouple project policies.

This page documents the build targets, repository wrapper pattern, and ProjectProfile architecture used to configure gh-ish for Gerrit and LUCI repositories.

Note

Looking to configure your personal AI coding assistant (Antigravity/Jetski, Claude Code, Codex, Cursor, or OpenCode) or install local pre-run tool hooks? See Agent setup.

Building and distributing gh-ish#

gh-ish is written in standard Go without external C library dependencies. It can be built and distributed using Bazel, Go toolchains, or pre-built binary packages.

Building with Bazel#

If your project uses Bazel, compile the binary target directly:

$ bazelisk build //pw_ghish:gh-ish

The compiled executable is placed in bazel-bin/pw_ghish/gh-ish_/gh-ish.

Building with standard Go#

You can compile and install gh-ish using the Go toolchain:

# Compile binary from source:
$ go build -o gh-ish ./pw_ghish/cmd/main.go

# Or install directly into $GOPATH/bin:
$ go install pigweed.dev/pw_ghish/cmd@latest

Distributing via CIPD or package managers#

For large multi-repo projects (such as Fuchsia or Chromium), gh-ish can be packaged as a CIPD (Chrome Infrastructure Package Deployer) package or added to host toolchains so developers and CI bots have it pre-installed on their $PATH.

Creating a repository wrapper#

Rather than requiring every developer and AI coding agent to manually install and update a global binary, we recommend placing a wrapper script named gh at the root of your repository (e.g. ./gh).

Why use a repository wrapper?#

  1. No global installation step: Contributors and coding agents can run ./gh pr list or ./gh pr status directly from a fresh checkout.

  2. Commit-pinned consistency: The wrapper builds or downloads the version of the tool matching the repository’s current commit.

  3. Local binary caching: The wrapper builds the binary once per commit and caches it in a local output directory (e.g. out/gh/) for subsequent runs.

  4. Standard CLI entry point: Coding agents can invoke ./gh from the checkout root using standard GitHub CLI subcommands.

Example wrapper implementation#

Here is an example wrapper script that builds and caches the binary:

#!/usr/bin/env bash
set -euo pipefail

REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
CACHE_DIR="${REPO_ROOT}/out/gh"
COMMIT_HASH="$(git -C "${REPO_ROOT}" rev-parse HEAD 2>/dev/null || echo "latest")"
CACHED_BIN="${CACHE_DIR}/gh-ish-${COMMIT_HASH}"

if [[ ! -x "${CACHED_BIN}" ]]; then
  mkdir -p "${CACHE_DIR}"
  # Build using Bazel or Go:
  bazelisk build --noshow_progress //pw_ghish:gh-ish
  cp -f "${REPO_ROOT}/bazel-bin/pw_ghish/gh-ish_/gh-ish" "${CACHED_BIN}"
  chmod +x "${CACHED_BIN}"
fi

exec "${CACHED_BIN}" "$@"

Project Profile Architecture#

Every Gerrit project has unique review conventions: differing label names (such as Code-Review vs. Commit-Queue vs. Auto-Submit), varying presubmit gates, and dedicated LUCI build buckets.

pw_ghish abstracts these differences through Project Profiles.

Built-in profiles#

pw_ghish includes built-in profiles for common Google open-source projects:

Profile

Gerrit Host Match

Commit-Queue

Code-Review

Try Bucket

pigweed

pigweed-review.googlesource.com

Commit-Queue+2

Code-Review+2

pigweed/try

fuchsia

fuchsia-review.googlesource.com

Commit-Queue+2

Code-Review+2

fuchsia/try

generic

(fallback)

(none)

Code-Review+2

(custom)

Auto-submit labels (such as Pigweed-Auto-Submit or Auto-Submit) do not need to be configured in a profile: --auto queries Gerrit for the change’s or project’s labels and votes the matching auto-submit label automatically.

Automatic profile detection#

pw_ghish automatically selects the appropriate profile by inspecting:

  1. The Git remote URL (e.g. origin) for the repository.

  2. The Gerrit review host hostname.

  3. The Git config setting ghish.profile.

Explicit profile override#

You can force a specific profile on any command using the --profile flag:

$ gh-ish pr list --profile fuchsia
$ gh-ish pr status --profile pigweed

Profile names are strictly validated. Passing an invalid profile name halts with an error listing all available profiles.

Adding a new project profile#

To add a profile for your project, implement the ProjectProfile interface in pw_ghish/profile.go (or embed genericProfile for default behavior) and register it with RegisterProfile:

type myProjectProfile struct {
    genericProfile
}

func (p *myProjectProfile) Name() string {
    return "myproject"
}

func (p *myProjectProfile) DefaultGerritHost() string {
    return "https://myproject-review.googlesource.com/a"
}

func (p *myProjectProfile) CQLabel() (LabelVote, bool) {
    return LabelVote{Name: "Commit-Queue", Value: 2}, true
}

func (p *myProjectProfile) BuildbucketProject() string {
    return "myproject"
}

func init() {
    RegisterProfile(&myProjectProfile{})
}

Add a test case in pw_ghish/profile_test.go verifying detection and behavior.

Authentication and Credential Setup#

./gh auth status checks credentials across Gerrit, LUCI Buildbucket, and Google Issue Tracker (Buganizer), supporting both googler (internal + public builders required) and community (public builders + .gitcookies or anonymous reads) authentication modes.

For full details on authentication modes, credential lookup order, and environment variables (GH_ISH_AUTH_MODE, GH_ISH_AUTH_METHOD, GERRIT_TOKEN, LUCI_TOKEN), see Authentication (gh auth).

LUCI CI and Buildbucket Integration#

Projects using LUCI (such as Chromium, Fuchsia, Pigweed, and Android) can use Buildbucket integration for check inspection and reruns:

pRPC checks querying#

pw_ghish pr checks queries cr-buildbucket.appspot.com via pRPC to fetch builder statuses, durations, and build URLs.

Terminal log inspection#

gh-ish run view --log-failed queries Buildbucket step summaries and step log URLs to retrieve the tail of failed build steps in the terminal:

# Inspect step execution tree for a specific builder:
$ gh-ish run view -j myproject-linux-dbg

# Print failure summaries and step log snippets for failed builders:
$ gh-ish run view --log-failed

Builder reruns#

gh-ish run rerun automatically constructs and executes bb add commands targeting your profile’s try bucket:

# Rerun all failed builders on the current change:
$ gh-ish run rerun --failed

# Rerun a specific builder:
$ gh-ish run rerun -j myproject-linux-dbg

# Preview the generated bb command without executing:
$ gh-ish run rerun --failed --dry-run