101 lines
4.9 KiB
Markdown
101 lines
4.9 KiB
Markdown
# Issue tracker: Gitea (self-hosted)
|
|
|
|
Issues and specs for this repo live as issues on Gitea
|
|
(`https://git.crkc.xyz/Apps/ImageApi`). Use the `tea` CLI for all operations.
|
|
|
|
## Conventions
|
|
|
|
- **Create an issue**: `tea issues create --title "..." --description-file -`
|
|
(read the body from a heredoc on stdin), or `--description "..."` for a
|
|
one-liner. Add labels at creation with `--labels "..."` (the labels
|
|
must already exist — see below).
|
|
- **Read an issue**: `tea issues <index> --comments`. Use
|
|
`tea issues list -f index,title,body,labels,comments -o json` for
|
|
machine-readable output.
|
|
- **List issues**: `tea issues list --state open` (default state is open)
|
|
with appropriate `--labels` / `--keyword` filters.
|
|
- **Comment on an issue**: `tea comments add <index> "..."` (alias:
|
|
`tea comments <index> "..."`).
|
|
- **Apply / remove labels**: `tea issues edit <index> --add-labels "..."` /
|
|
`--remove-labels "..."`.
|
|
- **Labels must exist first.** Neither `issues create --labels` nor
|
|
`issues edit --add-labels` creates a missing label: an unknown name is
|
|
**silently dropped** — the command succeeds and the issue ends up
|
|
unlabelled (verified against this server, tea 0.16). Check with
|
|
`tea labels list`; create with
|
|
`tea labels create --name "..." --color "#rrggbb" --description "..."`,
|
|
then apply. After labelling, confirm it stuck (`tea issues <index>`).
|
|
The triage labels (`triage-labels.md`) and the `wayfinder:*` labels
|
|
below all exist; any new label must be created before first use.
|
|
- **Close**: `tea issues close <index>`. It does not accept a closing
|
|
comment, so post the explanation first with
|
|
`tea comments add <index> "..."`, then close.
|
|
- **Raw API access** (for anything the `tea` subcommands don't cover):
|
|
`tea api <endpoint>` makes an authenticated request to the Gitea API
|
|
(prefixes `/api/v1/` when the path doesn't start with `/api/`).
|
|
Placeholders `{owner}` and `{repo}` are replaced from the current repo
|
|
context. Use `-F` for typed fields (numbers, booleans) and `-d` for raw
|
|
JSON bodies.
|
|
|
|
Infer the repo from the `git remote` (`-R` lets `tea` discover the Gitea
|
|
login from the remote); `tea` does this automatically when run inside a
|
|
clone. Confirm the acting user with `tea whoami`.
|
|
|
|
Unlike GitHub, Gitea numbers issues and pull requests separately, so a bare
|
|
`#42` is unambiguous once you know which surface it refers to.
|
|
|
|
## Pull requests as a triage surface
|
|
|
|
**PRs as a request surface: no.** _(Set to `yes` if this repo treats
|
|
external PRs as feature requests; `/triage` reads this flag.)_
|
|
|
|
When set to `yes`, PRs run through the same labels and states as issues,
|
|
using the `tea pulls` equivalents (`tea pulls list/view/edit`,
|
|
`tea pulls close`, plus `tea comments` which covers PRs). Keep only PRs
|
|
from outside collaborators (drop the repo owner and team members) when
|
|
listing external PRs for triage.
|
|
|
|
## When a skill says "publish to the issue tracker"
|
|
|
|
Create a Gitea issue.
|
|
|
|
## When a skill says "fetch the relevant ticket"
|
|
|
|
Run `tea issues <index> --comments`.
|
|
|
|
## Wayfinding operations
|
|
|
|
Used by `/wayfinder`. The **map** is a single issue with **child** issues
|
|
as tickets.
|
|
|
|
- **Map**: a single issue labelled `wayfinder:map`, holding the
|
|
Notes / Decisions-so-far / Fog body.
|
|
`tea issues create --title "..." --labels wayfinder:map --description-file -`.
|
|
- **Child ticket**: an issue carrying `Part of #<map>` at the top of its
|
|
description, labelled `wayfinder:<type>` (`research`/`prototype`/
|
|
`grilling`/`task`). Once claimed, the ticket is assigned to the driving
|
|
dev.
|
|
- **Blocking**: Gitea's **native issue dependencies** (enabled on this
|
|
server), the canonical, UI-visible representation. Add an edge with
|
|
`tea api --method POST repos/{owner}/{repo}/issues/<child>/dependencies -d '{"index": <blocker-index>, "owner": "<owner>", "repo": "<repo>"}'`
|
|
(201 on success). Gotchas, verified against Gitea 1.27:
|
|
- The route is `.../dependencies` — there is **no** `blocked_by`
|
|
subpath (that 404s).
|
|
- The JSON body **must** name the blocker's repo (`owner` + `repo`);
|
|
omitting them yields a misleading `404 repository does not exist`
|
|
even though the child's path is correct.
|
|
- `index` is the visible `#number`, not an internal database id.
|
|
Verify with `tea api repos/{owner}/{repo}/issues/<child>/dependencies`
|
|
(lists blockers); remove with `--method DELETE` and the same body.
|
|
Where dependencies aren't available, fall back to a
|
|
`Blocked by: #<n>, #<n>` line at the top of the child description.
|
|
A ticket is unblocked when every blocker is closed.
|
|
- **Frontier query**: list the map's open children (issues whose
|
|
description carries `Part of #<map>`), drop any with an open blocker
|
|
(dependency or `Blocked by` line) or an assignee; first in map order wins.
|
|
- **Claim**: `tea issues edit <n> --add-assignees <username>` (the
|
|
session's first write; `<username>` from `tea whoami`).
|
|
- **Resolve**: `tea comments add <n> "<answer>"`, then
|
|
`tea issues close <n>`, then append a context pointer (gist + link) to
|
|
the map's Decisions-so-far.
|