--- name: gitlab-dashboard description: Refresh the GitLab Dashboard note in the Obsidian vault — fetches open MRs, review requests, pipeline statuses, assigned issues, and upcoming milestone deadlines, then formats everything as a structured Obsidian note. --- # GitLab Dashboard Update `VAULT/GitLab Dashboard.md` (where `VAULT` is the `vault.root` path from `config.yaml`) with a fresh snapshot of the user's GitLab activity. ## Configuration All paths come from `config.yaml` at the repo root. Read it at the start of every run. - **Vault file:** `vault.root` + `vault.gitlab_dashboard_file` from config.yaml - **Provider dispatch:** `providers/_dispatch.sh` at the repo root - **Username:** `user.forge_username` (or legacy `user.gitlab_username`) from config.yaml ## Steps ### Step 1: Run the forge provider dispatch ```bash providers/_dispatch.sh forge --dashboard ``` The dispatch outputs a single JSON object to stdout, merged from all active forge providers. Capture it. If the dispatch exits non-zero or returns an object with `"error"` at the top level, report the error and stop — do not write a partial dashboard. ### Step 2: Parse the JSON The JSON has this shape: ```json { "generated_at": "2026-04-01T14:30:00", "my_mrs": [ { "iid": 123, "title": "Add deployment config", "project": "acme/acme-plugin", "web_url": "https://gitlab.example.com/...", "pipeline_status": "passed", "updated_at": "2026-03-30T10:00:00Z", "target_branch": "main" } ], "reviewing": [ { "iid": 456, "title": "Fix parser edge case", "project": "phoenix/pipeline", "web_url": "https://gitlab.example.com/...", "author": "jsmith", "updated_at": "2026-03-31T08:00:00Z" } ], "issues": [ { "iid": 78, "title": "Update deployment docs", "project": "acme/acme-plugin", "web_url": "https://gitlab.example.com/...", "due_date": "2026-04-15", "milestone": "v4.2", "labels": ["Priority::High"] } ], "milestones": [ { "title": "v4.2", "project": "acme/acme-server", "due_date": "2026-04-13", "web_url": "https://gitlab.example.com/..." } ] } ``` ### Step 3: Format the dashboard note Build the note content according to the format below. Follow these rules exactly: **Timestamps:** Format `generated_at` as `YYYY-MM-DD HH:MM` (local time, no seconds, no timezone). **Relative times:** For `updated_at` fields, compute relative to the current time: - < 1 hour → "N minutes ago" - < 24 hours → "N hours ago" - 1 day → "1 day ago" - N days → "N days ago" - > 14 days → the date as `YYYY-MM-DD` **Pipeline status icons:** Map `pipeline_status` values: - `passed` → `✅ passed` - `failed` → `❌ failed` - `running` → `⏳ running` - `pending` → `⏸ pending` - `canceled` → `⬜ canceled` - `skipped` → `⬜ skipped` - empty / null / `"none"` → `—` **MR links:** Format as `[!IID Title](url)` — exclamation mark, no space before IID. **Issue links:** Format as `[#IID Title](url)` — hash, no space before IID. **Empty sections:** If a section has no data, show a single line: `_None_` **Issues and Reviews as Tasks queries:** The "My Issues" and "Reviewing" sections use **Obsidian Tasks plugin query blocks** that reference items in `To Do.md`. This means checking off an item in the dashboard updates `To Do.md` directly — no manual sync needed. Group issues by project tag (`#project/acme`, `#project/phoenix`, etc.). Items without a project tag go under "Other". Filter out MR items (description includes `MR:`) from the issues section. For "Reviewing", show all items whose description starts with `Review MR:`. **Milestones:** Sort by `due_date` ascending. Only include milestones with `due_date` within the next 14 days from today. ### Step 4: Write the dashboard note Write the formatted content to the vault file (path from config.yaml). Overwrite the file completely — do not append or merge. ## Dashboard Format ```markdown # GitLab Dashboard > Last updated: YYYY-MM-DD HH:MM ## My Merge Requests | MR | Project | Branch | Pipeline | Updated | |----|---------|--------|----------|---------| | [!123 Add deployment config](url) | acme/acme-plugin | main | ✅ passed | 2 days ago | ## Reviewing ` ` `tasks not done path regex matches /^To Do/ description includes Review MR: description includes #source/gitlab sort by due ` ` ` ## My Issues ### ACME ` ` `tasks not done path regex matches /^To Do/ description includes #project/acme description includes #source/gitlab description does not include MR: sort by due ` ` ` ### Phoenix ` ` `tasks not done path regex matches /^To Do/ description includes #project/phoenix description includes #source/gitlab description does not include MR: sort by due ` ` ` ### Other ` ` `tasks not done path regex matches /^To Do/ description includes #source/gitlab description does not include #project/acme description does not include #project/phoenix description does not include #project/atlas description does not include MR: sort by due ` ` ` ## Upcoming Milestones | Milestone | Project | Due | |-----------|---------|-----| | v4.2 | acme/acme-server | 2026-04-13 | ``` ## Stale MRs After writing the main dashboard sections, add a "Stale MRs" section that flags: **Your MRs awaiting review (no activity in 3+ days):** - Check each MR in the "My Merge Requests" section - If `updated_at` is more than 3 days ago, flag it with a reminder to ping the reviewer **MRs waiting on your review (no activity in 3+ days):** - Check each MR in the "Reviewing" section - If `updated_at` is more than 3 days ago, flag it as needing your attention Format: ``` ## Stale MRs > [!warning] N MRs with no activity in 3+ days > **Waiting on others:** > - [!123 Title](url) — no activity since Mar 20 — consider pinging reviewer > **Waiting on you:** > - [!456 Title](url) — no activity since Mar 15 — needs your review ``` If no MRs are stale, omit this section. ## Safety Rules - **Read-only:** Never create, close, or modify any GitLab resource - **No partial writes:** If the script fails, do not write a degraded dashboard - **Graceful auth failure:** If glab is not authenticated, report the error clearly - **Vault file only:** Only write to the configured vault file path — nowhere else