Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
gitlab-tracker-redmine
Optional Redmine integration plugin for gitlab-tracker.
Implements the TrackerProvider trait from gitlab-tracker-core to detect Redmine ticket references in MR titles and descriptions, and enrich the TUI with ticket details and time tracking.
Features
-
Linked ticket display in the Inspector's MR Info view — the following fields are shown when available:
Field Source ( GET /issues/{id}.json)Ticket ID + Subject id,subjectType badge tracker.name(e.g. "Bug", "Evolution")Priority badge priority.name(e.g. "Normal", "High")Status status.nameAuthor / Assignee author.name,assigned_to.nameTarget version fixed_version.nameStart date start_dateProgress bar done_ratio(0–100 %)Estimate / Spent / Remaining estimated_hours,spent_hours,remaining_hoursDirect URL built from redmine_url+ ticket IDType and Priority are rendered as coloured badges — colours are fully configurable in
redmine.yaml(see Configuration below). -
Time Log view (
P): pressPtwice to reach the Time Log view:- A progress bar comparing time spent vs. the ticket's estimate.
- The full list of time entries (date, user, activity, duration, comment) fetched live from Redmine.
- Navigating between MRs with
↑/↓while on this view automatically refreshes the entries for the newly selected ticket.
-
Log time (
L): open a popup to submit a new time entry directly to Redmine — select the activity category, enter a duration (e.g.1h30,90m,1.5h), optionally add a comment, and confirm withEnter. -
Tracker column in the main table (toggleable via
C) — shows ticket ID, status, and spent/estimated time at a glance.
Enabling at Build Time
The redmine feature flag must be explicitly passed when building or installing:
# Build from source
# Install from source
# Install from crates.io
Without the flag, this crate is not compiled and there is zero runtime overhead.
Configuration
On first launch with the feature enabled, the app interactively prompts for your Redmine URL:
🌐 No Redmine URL found in config or environment.
Leave empty to disable Redmine integration.
Redmine URL: https://redmine.my-company.com
Leaving the prompt empty silently disables the integration — no error, no impact on the rest of the dashboard.
The configuration is persisted as a YAML file:
- Linux:
~/.config/gitlab-tracker/gitlab-tracker/redmine.yaml - macOS:
~/Library/Application Support/gitlab-tracker/gitlab-tracker/redmine.yaml - Windows:
C:\Users\<User>\AppData\Roaming\gitlab-tracker\gitlab-tracker\redmine.yaml
You can also pre-configure via environment variable to skip the prompt entirely:
REDMINE_URL=https://redmine.my-company.com
redmine.yaml — full reference
# ── Connection ────────────────────────────────────────────────────────────────
# Base URL of your Redmine instance. No trailing slash.
# Can also be set via the REDMINE_URL environment variable.
redmine_url: "https://redmine.my-company.com"
# ── Ticket detection ──────────────────────────────────────────────────────────
# Regex patterns used to detect ticket IDs in MR titles and descriptions.
# Each pattern must expose the numeric ID in capture group 1.
# The first match wins; patterns are tried in order.
ticket_patterns:
- "#(\\d+)" # plain #1234
- "(?i)(?:refs|fixes|closes|resolves)\\s+#(\\d+)" # refs #1234, fixes #1234, …
- "/issues/(\\d+)" # full Redmine URL in description
# ── Badge colours ─────────────────────────────────────────────────────────────
#
# Colour both the "Type" and "Priority" badges displayed in the Inspector panel.
# Keys are matched CASE-INSENSITIVELY against the value returned by the Redmine API.
# Use "*" as a catch-all fallback for any label not listed explicitly.
#
# Accepted colour values:
# Named: red, green, yellow, blue, magenta, cyan, white, black, dark_gray, light_gray
# Hex: #rrggbb (e.g. #ff6600)
# tracker_type_colors maps the "tracker.name" field (ticket category in Redmine).
# Discover your instance's values with:
# curl -s -H "X-Redmine-API-Key: YOUR_TOKEN" \
# "https://your-redmine.com/issues/ANY_ID.json" | jq '.issue.tracker'
tracker_type_colors:
"Bug":
"Evolution":
"Support":
"*": # catch-all for unlisted types
# priority_colors maps the "priority.name" field.
# Discover your instance's values with:
# curl -s -H "X-Redmine-API-Key: YOUR_TOKEN" \
# "https://your-redmine.com/issues/ANY_ID.json" | jq '.issue.priority'
priority_colors:
"Low":
"Normal":
"High":
"Urgent":
"*": # catch-all for unlisted priorities
| Field | Required | Description |
|---|---|---|
redmine_url |
✅ | Base URL of your Redmine instance (no trailing slash) |
ticket_patterns |
✅ | Regex list to detect ticket IDs in MR titles/descriptions — capture group 1 must match the numeric ID |
tracker_type_colors |
❌ | Badge colour map for the tracker.name field. Keys are case-insensitive; "*" is a catch-all fallback. Omit the section entirely to use the default (dark_gray / white) |
priority_colors |
❌ | Badge colour map for the priority.name field. Same rules as above |
How to discover your Redmine's label values
Label names (tracker types, priorities) are instance-specific and may be in any language. Run these commands against any existing issue to see what your instance returns:
# Tracker type and priority of issue #1234 | # All priorities defined in your instance |
Estimate to Complete (ETC) — automatic update on time entry submission
When you log time via the L popup, the app automatically recomputes the Estimate to Complete (ETC) on the linked Redmine ticket and writes it back.
ETC (Estimate to Complete) is the standard project management term for the remaining effort needed to finish a task. It is sometimes labelled Remaining time or Reste à faire (RAF) in French Redmine instances.
How it works
The computation uses fields returned directly by the Redmine issue API (GET /issues/{id}.json) — no admin access required:
| Priority | Field used | Formula | Available on |
|---|---|---|---|
| 1 (preferred) | remaining_hours |
remaining_hours − new_hours |
Redmine instances with a budget/planning plugin |
| 2 (fallback) | estimated_hours + spent_hours |
estimated_hours − spent_hours − new_hours |
All standard Redmine instances |
Both strategies clamp the result to 0.0 — ETC cannot be negative.
The ETC and budget are submitted directly on the time entry (POST /time_entries.json), which is how the Redmine Budget plugin tracks them. The remaining_hours field on the issue is then automatically recalculated by the plugin — no separate write to the issue is needed. If your Redmine instance does not expose these fields, they are simply omitted from the payload — the time entry is still created successfully.
No configuration needed
The ETC update is fully automatic and requires no changes to redmine.yaml. It activates whenever the issue returns usable time fields, and degrades gracefully otherwise.
Verify your instance exposes the fields by running:
|
If remaining_hours appears in the output, Strategy 1 is used. If only estimated_hours and spent_hours appear, Strategy 2 (fallback) is used.
API Token
The Redmine personal API token follows the same secure lookup chain as the GitLab token — it is never stored in plain text:
1. REDMINE_TOKEN environment variable (if set)
2. Native OS Keyring (GNOME Keyring / macOS Keychain / Windows Credential Manager)
3. Interactive CLI prompt → saved to OS Keyring
Adding a New Tracker Plugin
To add a different tracker (Jira, Linear, …), create a new crate and implement the TrackerProvider trait from gitlab-tracker-core.
Required methods
Optional overrides (all have default no-op implementations)
// Badge colours for Type and Priority labels — read from your config file.
// Return raw (bg, fg) string pairs; the orchestrator converts them to ratatui::Color.
// Omit to use the hard-coded fallback (dark_gray / white).
// Time-tracking support:
async
async
async
Wiring in main.rs
Add a #[cfg(feature = "my-tracker")] block in gitlab-tracker/src/main.rs — the build_tracker_colors helper is already generic over any TrackerProvider, so no further changes are needed in the orchestrator:
if let Some = my_tracker_provider
The LabelColorMaps flow:
Your config file (YAML/JSON/…)
└─ label_colors() in your provider ← String pairs, no ratatui dependency
└─ build_tracker_colors() ← converts to ratatui::Color (orchestrator only)
└─ TrackerLabelColors ← passed to the Inspector renderer