Files
agent-tools/README.md
T
unkin-agent 05594113a2
ci/woodpecker/pr/build Pipeline was successful
ci/woodpecker/pr/test Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful
Fix non-zero exit on error and debounce transient mergeable=false
agentpr/watchpr already propagated command errors to a non-zero exit, but
that behaviour had no regression coverage and the root command was not
constructible outside main(). watchpr also fired a spurious conflict alert
because Gitea computes mergeability asynchronously and can briefly report
mergeable=false right after a push. The docs additionally printed the
AppRole role_id literal UUID.

- Extract newRootCmd() in both cmd/agentpr and cmd/watchpr so main() only
  runs Execute and exits non-zero on error; add tests asserting Execute
  returns an error for a bad PR ref / malformed --repo / no args.
- Debounce mergeability loss in MeaningfulChange: only alert when
  mergeable=false persists across two consecutive polls (both prev and cur
  false, still open); update the table test for one-poll-false (benign),
  false-persisting (alert), and recovered false->true (benign).
- Refer to AGENT_APPROLE_ROLE_ID by env var in README.md/AGENTS.md without
  printing the literal role_id; keep the code default and env override.
2026-08-12 22:17:10 +10:00

87 lines
2.8 KiB
Markdown

# agent-tools
Two small Gitea-automation CLIs, shipped together in one RPM (`agent-tools`).
Both act as the **`unkin-agent`** user by minting a scoped Gitea token from
Vault, so automated PRs and comments are attributed to the agent — not to
whoever happens to run the command.
- **`agentpr`** — create pull requests and post PR comments as `unkin-agent`.
- **`watchpr`** — poll one or more PRs and exit when one changes in a way worth
acting on.
## How it gets a token
On first use each tool performs a Vault AppRole login (`role_id` only, no
`secret_id`), then reads `gitea/creds/unkin-agent` to obtain a short-lived Gitea
token, cached in-process for the run.
Everything is configured by environment variables, all with defaults:
| Variable | Default | Purpose |
|---|---|---|
| `VAULT_ADDR` | `https://vault.service.consul:8200` | Vault/OpenBao address |
| `AGENT_APPROLE_ROLE_ID` | built-in default | AppRole role_id (overridable) |
| `GITEA_URL` | `https://git.unkin.net` | Gitea base URL |
| `AGENT_LOGIN` | `unkin-agent` | login whose comments `watchpr` ignores |
## agentpr
```bash
# Verify identity (should print: unkin-agent)
agentpr whoami
# Open a PR
agentpr pr create --repo unkin/argocd-apps \
--base main --head benvin/my-change \
--title "Add woodpecker SA" --body "Adds the ServiceAccount ..."
# prints: #<number> <html_url>
# Comment on a PR
agentpr pr comment --repo unkin/argocd-apps --pr 42 --body "Rebased, CI green."
agentpr --version
agentpr --help
```
Non-zero exit on any API error.
## watchpr
Poll PRs and exit (reporting what changed) when a tracked PR **merges/closes**,
gets a **new comment from someone other than the agent**, its **CI fails**
(failure/error), or it **loses mergeability** (a conflict appears). Benign
transitions — CI `pending``success`, the agent's own comments — are ignored.
```bash
# Watch until something meaningful happens (default interval 60s)
watchpr unkin/argocd-apps#42
# Multiple PRs, custom interval; refs accept #N or :N
watchpr --interval 30s unkin/argocd-apps#42 unkin/terraform-vault:98
# One-shot: print current state and exit 0 (great for scripts)
watchpr --once unkin/argocd-apps#42
watchpr --once --json unkin/argocd-apps#42
```
On a meaningful change `watchpr` prints the reason and the PR's current state,
then exits 0. Use `--json` for machine-readable output.
## Build & package
```bash
make build # -> dist/agentpr, dist/watchpr
make test # go test -race ./...
make rpm # build + package dist/agent-tools-<version>-1.x86_64.rpm
```
Release is tag-driven (`v*`) via Woodpecker: builds the RPM, `PUT`s it to the
artifactapi `rpm-internal` yum repo, and cuts a Gitea release with
cross-compiled binaries attached.
### Version bump
```bash
make patch # or: make minor / make major — tags vX.Y.Z and pushes the tag
```