feat(forge): GitLab pipelines, jobs, job logs and labels #148

Merged
deadstyle merged 6 commits from feature/139-gitlab-runs into develop 2026-10-12 09:21:08 -05:00
Owner

Refs #139 (parent #137)

Summary

The GitLab adapter implements RunLister, LogReader and Labeler: box [3] lists pipelines (newest 100, with ref/sha filters), a pipeline shows its jobs with their stage, job logs stream, and labels can be read and replaced. architecture.md's GitLab rows and ADR 0018 are updated (unverified: no live GitLab used).

Decisions

  • Runs read one page of 100, newest first, as ADR 0017's runs exception. duration is used when the list carries it (GitLab 19.4+); older servers leave it blank rather than spend one request per pipeline.
  • Job and pipeline status reuse #138's pipeline fold. Retried and trigger jobs are left out; Attempt is 1.
  • Job logs stream raw bytes outside any cache, and the token is dropped on any redirect off the API origin (Go forwards PRIVATE-TOKEN on every hop). #143 makes that guard client-wide.
  • SetLabels maps IDs to names through the label list and refuses an unknown ID, so GitLab never auto-creates a label; label names are comma-joined (GitLab label titles can't contain commas). Colours are hex without #, as the gitea adapter hands them; a CSS colour name maps to the default.

Test plan

  • go test -race ./...: 13 packages ok; build passes; lint with CI's golangci-lint v2.14.0: 0 issues (before the develop sync; CI re-checks after).
  • Tests written red-first from the AC, then a mutation check: each covered behaviour broken in a throwaway worktree turns its test red on the assertion (one test rewritten so a paging mutation fails instead of hanging).

🤖 Generated with Claude Code

Refs #139 (parent #137) ## Summary The GitLab adapter implements `RunLister`, `LogReader` and `Labeler`: box `[3]` lists pipelines (newest 100, with `ref`/`sha` filters), a pipeline shows its jobs with their stage, job logs stream, and labels can be read and replaced. architecture.md's GitLab rows and ADR 0018 are updated (unverified: no live GitLab used). ## Decisions - Runs read one page of 100, newest first, as ADR 0017's runs exception. `duration` is used when the list carries it (GitLab 19.4+); older servers leave it blank rather than spend one request per pipeline. - Job and pipeline status reuse #138's pipeline fold. Retried and trigger jobs are left out; `Attempt` is 1. - Job logs stream raw bytes outside any cache, and the token is dropped on any redirect off the API origin (Go forwards `PRIVATE-TOKEN` on every hop). #143 makes that guard client-wide. - `SetLabels` maps IDs to names through the label list and refuses an unknown ID, so GitLab never auto-creates a label; label names are comma-joined (GitLab label titles can't contain commas). Colours are hex without `#`, as the gitea adapter hands them; a CSS colour name maps to the default. ## Test plan - `go test -race ./...`: 13 packages ok; build passes; lint with CI's golangci-lint v2.14.0: 0 issues (before the develop sync; CI re-checks after). - Tests written red-first from the AC, then a mutation check: each covered behaviour broken in a throwaway worktree turns its test red on the assertion (one test rewritten so a paging mutation fails instead of hanging). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Refs #139

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Refs #139

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Refs #139

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Refs #139

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Refs #139

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
chore: merge develop into feature/139-gitlab-runs
All checks were successful
ci / check (pull_request) Successful in 1m22s
4dc8ff8e52
deadstyle merged commit eb460a9a02 into develop 2026-10-12 09:21:08 -05:00
deadstyle deleted branch feature/139-gitlab-runs 2026-10-12 09:21:08 -05:00
Sign in to join this conversation.
No description provided.