Files
t3bootstrap-upgrade-skills/redmine-issue-workflow/SKILL.md
T
melnicenkoandClaude Opus 5 d91dd97795 Redmine-Skill: Rollen ohne Annahme ueber den Bedienenden
Die Skill wird von mehreren Personen genutzt, deshalb kann bei Ilja
nicht "(the user)" stehen - wer sie bedient, ist offen. Stattdessen ein
Hinweis, dass jede der genannten Personen gerade am Werk sein kann und
ein Ticket nicht deshalb ihres ist, weil sie danach fragt.

Ilja ausserdem als Senior-Entwickler gefuehrt.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-07 15:53:37 +02:00

98 lines
6.6 KiB
Markdown

---
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.3"
---
# 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)
- `<REDMINE_URL>` — e.g. `https://redmine.example.com`.
- `<PROJECT_SLUG>` — the project identifier (used as `project_id`), e.g. `ivv`. (Numeric id also works.)
- `<API_KEY_FILE>` — 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 …)`.
- `<ISSUE_ID>` / `<JOURNAL_ID>` — the ticket / journal-note ids.
## Auth (every call)
```bash
curl -s -H "X-Redmine-API-Key: $(cat <API_KEY_FILE>)" "<REDMINE_URL>/…"
```
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=<PROJECT_SLUG>&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/<ISSUE_ID>.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 <API_KEY_FILE>)" -H "Content-Type: application/json" \
-d '{"issue":{"notes":"…","status_id":<N>,"done_ratio":<0-100>}}' \
"<REDMINE_URL>/issues/<ISSUE_ID>.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/<JOURNAL_ID>.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 `<ol><li>`).
- 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.
Two or three sentences is the norm: what is done, where to check it. No commit hashes, no file names,
no before/after measurements — the customer did not ask how, only whether.
- **No icons, emoji or decorative symbols in ticket text** (no ✅/✔/→/⚠, no bullets made of glyphs).
Plain sentences, plus Textile markup where it carries meaning (strike-through, bold). Team rule.
- **Never set or change `assigned_to_id`.** Post the note and the status, leave the assignee alone —
reassigning is the user's call and a wrong one pulls a colleague into a ticket that isn't theirs.
Note that `status_id` and `done_ratio` are fine to set; only ownership is off limits.
- 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.
## Who does what — the same team across all TYPO3 projects
The assignee tells you what KIND of work a ticket is. These roles hold across projects, so read them
before deciding whether a ticket is yours to act on. Any of them may be the one operating you — don't
assume which, and don't assume a ticket is theirs just because they are asking about it.
- **Ilja** — **senior developer**. Code, templates, SCSS, TypoScript, deployments.
- **Sven** — **senior developer** and maintainer of the shared WapplerSystems extensions
(`address`, `ws_slider`, `hero-item`, …). Coordinate with him before cutting a tag on one of those.
- **Ranju** — **junior developer**. Also on the development side, so a ticket assigned to her is
technical, not editorial.
- **Corinna** — **design and the bulk of editorial work**. Content tickets (texts, images, page
structure) are hers.
- **Eva** — **project management**, plus light editorial changes. Typically the one who maintains a
Sammelticket's item list and re-assigns tickets.
Consequences:
- **A ticket assigned to Corinna or Eva is editorial — don't silently do the work.** Report what you
found if it helps, but leave the change to them.
- **CSS and code are yours even when the ticket is assigned to someone else.** Tickets often mix the
two: split them by the NATURE of each item, not by the assignee, do the technical half, and say
plainly which half you left alone and why.
- This is also why the assignee must never be changed by you (above): it encodes the routing.
## Attachments
`GET /attachments/download/<id>/<name>` needs the **exact** filename (a placeholder → 404 HTML). Reliable:
`GET /attachments/<id>.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.