002 — tp issue list: open issues on the release remote's Forgejo (#22)
Status: shipped (v0.2.0)
Why
Story 001 is the whole tp issue command. Its hard part
is not any one subcommand but the plumbing under all of them: finding the
forge, owner, repo and token from the release remote, and talking to the
Forgejo issues API. Listing open issues is the smallest read that exercises
all of it, and it is useful on its own — "what's open here?" is the first
question before picking the next story. Shipping it first proves the
plumbing before the write subcommands build on it, and keeps 001 to one
release.
What changes
- New command
tp issue list: open issues of the current repo, one line each,#N title, ascending by number. No issues prints nothing and exits 0. - The forge, owner, repo and token come from the release remote exactly as
tp releasefinds them:release_remote(defaultorigin), itsforge/token_envoverrides intask-plus.yml, tokens fetched through the configured secrets provider. No new configuration. - Forgejo/Gitea API only:
GET /api/v1/repos/{owner}/{repo}/issues?state=open&type=issues, following pages until one comes back short. internal/forgegains the issue list call;internal/cligains theissuedispatch withlistas its only subcommand. Docs pagedocs/issue.md; README command table row.
Acceptance
Forge resolution, given release_remote names remote R:
| R's URL | forge: override |
Outcome |
|---|---|---|
https://host/owner/repo.git |
none, detected forgejo | API at https://host/api/v1/repos/owner/repo |
git@host:owner/repo.git |
none, detected forgejo | same |
ssh://git@host/owner/repo.git |
none, detected forgejo | same |
alias:owner/repo.git (ssh alias, no dots) |
none | error: "cannot derive forge host from ssh alias; use the canonical name in the remote" |
| any | github |
error: "tp issue: issues live on the Forgejo origin, not GitHub" |
| any | none |
error: no forge |
| not recognisable as a forge host | none | error: "set forge: forgejo on the remote in task-plus.yml" |
| any | gitlab |
error: only Forgejo/Gitea issues are supported |
ssh://git@host:2222/owner/repo.git |
forgejo | API at https://host/... (the ssh port is dropped) |
Token, for a resolved Forgejo host:
token_env set |
variable present in env | secrets provider | Outcome |
|---|---|---|---|
| yes | yes | any | used |
| yes | no | bitwarden, unlocked | fetched, used |
| yes | no | bitwarden, no session | error naming tp unlock |
| yes | no | none | error naming the variable |
| no | — | — | request sent unauthenticated |
Listing, with a resolved forge:
| API response | Prints | Exit |
|---|---|---|
| open issues on one page | #N title per issue, ascending |
0 |
| more open issues than one page | every issue across all pages | 0 |
| a pull request among the results | excluded (type=issues) |
0 |
| no open issues | nothing | 0 |
| 404 (missing repo, or private without a token) | error with status and the API's message | 1 |
| other non-2xx | error with status and the API's message | 1 |
| 401 whose message echoes the token | the token replaced by <redacted> |
1 |
Out of scope
closed/allstates,show,create,edit,comment,close,reopen, and-json— the rest of story 001.- Labels, milestones, assignees, and filtering.
- Issues across several repos.
Decisions
None: the forge resolution is tp release's, reused. Two gaps were filled
while building: a remote on a host tp cannot recognise (git.bytestone.uk
has no "forgejo" in its name) needs forge: forgejo, as it does for
tp release; and Forgejo's 401 message quotes the rejected token, so API
errors redact it.
Done when
- tests express the three acceptance tables and pass (forge resolution
and token chain as unit tests; listing against an
httptestserver) - spec updated (
docs/issue.md, README command table) - ADR written if a fork was resolved
- roadmap ticked and stamped; changelog entry
- issue closed with a link to the release