diff --git a/redmine-issue-workflow/SKILL.md b/redmine-issue-workflow/SKILL.md new file mode 100644 index 0000000..946a177 --- /dev/null +++ b/redmine-issue-workflow/SKILL.md @@ -0,0 +1,67 @@ +--- +name: redmine-issue-workflow +description: "Read and update issues on a self-hosted Redmine via its REST API from the CLI — list/read tickets, add notes, change status, edit an existing journal note in place, and download attachments. Use when a project tracks its work/bugs in Redmine and you need to look up 'the next fixes', check a ticket's details, mark work done, or maintain a collection ('Sammelticket') ticket. Covers: API-key auth via header (never inline the secret), the issues/journals/attachments endpoints, Textile (NOT Markdown) formatting, localized statuses, and the posting-style rules (keep customer-visible notes minimal — strike through or 'erledigt', don't write the bug's cause; don't post unless asked)." +metadata: + author: Wappler + version: "1.0" +--- + +# Redmine issue workflow (REST API, CLI) + +Read and update a self-hosted **Redmine** project's issues over its REST API from the shell. Redmine +is where the team tracks bugs / "next fixes"; you look tickets up, and — only when asked — mark work done. + +## Placeholders (keep the concrete values in project memory, not here) +- `` — e.g. `https://redmine.example.com`. +- `` — the project identifier (used as `project_id`), e.g. `ivv`. (Numeric id also works.) +- `` — a **chmod 600** file holding the per-user REST API key (from Redmine → *My account + → API access key*). **Never inline the key** — always read it in the header via `$(cat …)`. +- `` / `` — the ticket / journal-note ids. + +## Auth (every call) +```bash +curl -s -H "X-Redmine-API-Key: $(cat )" "/…" +``` +Keeps the secret out of the command line (auto-mode/secret guards block a literal key). + +## Read +- **Open issues (the "next fixes"):** + `GET /issues.json?project_id=&status_id=open&sort=priority:desc&limit=100` + (`status_id=open` = all non-closed; `sort=updated_on:desc` to see the newest activity.) +- **One issue with its notes:** `GET /issues/.json?include=journals,attachments`. +- Pipe JSON through `python3 -c "import sys,json;…"` to print `id / status / subject / assignee / notes`. +- **Statuses may be localized.** A German instance uses: **Fehler** = bug (open), **Gewünscht** = + wishlist/requested, **Empfohlen** = recommended, **Abnahme** = ready for customer sign-off. Confirm the + instance's own status names via `GET /issue_statuses.json` before setting one by id. + +## Update (only when the user asks — see posting style) +- **Add a note / change status / progress** on an issue: + ```bash + curl -s -X PUT -H "X-Redmine-API-Key: $(cat )" -H "Content-Type: application/json" \ + -d '{"issue":{"notes":"…","status_id":,"done_ratio":<0-100>}}' \ + "/issues/.json" # → 204 No Content on success + ``` +- **Edit an EXISTING journal note in place** (e.g. a collection ticket's item list that one person keeps + appending to): `PUT /journals/.json` with `{"journal":{"notes":"…"}}` → 204. Get the + journal id from the issue's `include=journals`. +- **Collection / "Sammelticket" pattern:** one ticket stays open and holds a numbered item list (often in + a single journal note). As items are done, **strike them through** and the ticket stays open for more. + +## Formatting — Textile, NOT Markdown +Redmine renders **Textile** by default. Consequences: +- Strike-through = `-text-` (Markdown `~~…~~` does nothing). +- A leading `#` is an **ordered-list** item, not a heading (Markdown `#` headings render as `
  1. `). +- Bold `*text*`, italic `_text_`, inline code `@code@`. + +## Posting style (team rules — important) +- **Don't post unless asked.** The user often does the Redmine updates themselves; offer/confirm first. +- **Keep customer-visible notes minimal. Do NOT write out the bug's cause / technical explanation** in the + ticket. To mark something done, **strike the item through** (`-…-`) or just write **"erledigt"** beside + it, where appropriate. The detailed root-cause/fix belongs in your own notes/memory, not the ticket. +- Before posting a status change, prefer to draft the (short, German if the project is German) note and + confirm the target status with the user. + +## Attachments +`GET /attachments/download//` needs the **exact** filename (a placeholder → 404 HTML). Reliable: +`GET /attachments/.json` → read `content_url` → `curl -L` THAT with the API-key header. Attached +"screenshots" are often browser print-to-PDF files — readable directly once downloaded.