- Rust 96.1%
- Just 3.9%
| .forgejo/workflows | ||
| src | ||
| .gitignore | ||
| AGENTS.md | ||
| Cargo.lock | ||
| Cargo.toml | ||
| justfile | ||
| README.md | ||
| rusty-hook.toml | ||
forgejo-cli
A CLI for interacting with Forgejo's full REST API.
Covers every endpoint under /api/v1/ — issues, PRs, reviews, comments,
repos, branches, CI/Actions, secrets, variables, organizations, teams, users,
notifications, packages, admin, and instance metadata.
Built as a single static Rust binary. No runtime dependencies.
Install
# From source
git clone https://forge.jacquin.app/charles/forgejo-cli
cd forgejo-cli
cargo build --release
cp target/release/forgejo-cli /usr/local/bin/forge
Pre-built binaries are planned — see releases.
Configuration
Environment variables:
| Variable | Default | Purpose |
|---|---|---|
FORGEJO_URL |
https://forge.jacquin.app |
Forgejo instance base URL |
FORGEJO_TOKEN |
(empty) | API token (required for mutations) |
FORGE_REPO |
(empty) | owner/name — skip --owner/--repo (priority over git remote) |
FORGEJO_ACCESS_TOKEN is accepted as an alias for FORGEJO_TOKEN.
Token scopes
For full API coverage, create a token with all scopes in Settings → Applications → Access Tokens.
Quick start
# Instance info (no token needed for public endpoints)
forge instance version
# Authenticated usage — inside a git clone (zero config)
export FORGEJO_TOKEN=your-token-here
cd my-project # has origin remote on forge.jacquin.app
forge issue list # auto-detects repo from git remote
forge pr list
# With FORGE_REPO (agent dispatch mode)
export FORGE_REPO=charles/claude-hooks
forge issue list # uses FORGE_REPO regardless of cwd
# Cross-repo (explicit flags always win)
forge issue list --owner other --repo project
Output
All commands output JSON by default. Use --output text for compact output.
forge issue get 42 | jq '.title'
forge pr list --limit 5 | jq '.[].number'
Command groups
forge issue <subcommand> # Issues, labels, dependencies, reactions, pins
forge pr <subcommand> # PRs, reviews, merge, diff, files
forge comment <subcommand> # Comments by id (get/edit/delete)
forge repo <subcommand> # Repos, branches, files, releases, webhooks, tags
forge action <subcommand> # CI runs, jobs, logs, secrets, variables
forge org <subcommand> # Organizations, teams, members, webhooks
forge team <subcommand> # Team CRUD, members, repos
forge user <subcommand> # Current user, profile, keys, tokens
forge notify <subcommand> # Notifications
forge package <subcommand> # Packages
forge admin <subcommand> # Admin: cron, users, runners, hooks
forge instance <subcommand> # Version, nodeinfo, markdown, templates
Use forge <group> --help to see all subcommands.
Architecture
forgejo-cli
├── clap CLI parsing (derive macros)
├── reqwest HTTP client (JSON, streaming pagination)
├── serde_json Dynamic JSON (no generated types from OpenAPI spec)
└── anyhow Error handling
The CLI uses dynamic serde_json::Value instead of the forgejo-api crate's
generated types. This avoids coupling to a specific Forgejo version's OpenAPI
spec and means the CLI works with any Forgejo version that preserves the
/api/v1/ URL structure.
Building
just build-release # ~3 MB static binary
just check # fast type check
just test # run tests
just qa # format + lint + test (run before commits)
just setup # first-time: install tools, hooks, build
Pre-commit hooks auto-format and lint staged files on every commit.
License
MIT OR Apache-2.0