gitshark

Clone repository

git clone https://gitshark.de/git/workaround/Gitshark.git
git clone git@gitshark.de:workaround/Gitshark.git

← Issues

Make the REST API Gitea-compatible (single API, enables Renovate) #20

Make /api/v1 Gitea-compatible (single API)

Problem

We want automated dependency updates (Renovate) on our own git-shark-hosted code. Renovate has no git-shark platform driver. Supported platforms: github, gitlab, bitbucket, gitea/forgejo, azure, gerrit, codecommit, local.

The GitHub-mirror route is a dead end: the mirror is a one-way backup push (git-shark → GitHub, overwrites), so PRs Renovate opens on GitHub never flow back and get clobbered on the next sync. git-shark is the source of truth.

Decision: migrate, don't add a parallel API

Rather than run a Gitea-compatible shim alongside the existing bespoke /api/v1, migrate /api/v1 to be Gitea-native and drop the bespoke shapes.

Rationale

  • No consumers yet. The REST API has no external users, so this is a rename/reshape, not a breaking change. Now is the cheapest possible moment.
  • One schema, not two. Avoids a permanent path-collision problem (native GET /api/v1/repos/{owner}/{name} and the Gitea equivalent share a path but want different JSON).
  • Broad ecosystem compat, not just Renovate. A Gitea-native API also works with tea CLI, act_runner, and other Gitea tooling/bots.
  • Net effort ≈ the same as a separate shim, better result.

MCP tools keep working against the same domain services (see caveat below).


Spike: how big is the gap?

Small-to-medium. git-shark already has ~80% of the machinery. Renovate's Gitea client clones/pushes repos via the git CLI and uses REST only for PR/issue/label/status metadata — so most file access needs no API.

Already present (reuse, no change)

  • PAT auth (gs_-prefixed tokens, SHA-256 stored) works on git smart-HTTP (GitBasicAuthFilter, password = token) and REST (ApiTokenAuthFilter, Authorization: Bearer). Renovate pushes branches over HTTPS with the token → works today, zero change.
  • /api/v1 JSON REST backed by domain services (MergeRequestService, IssueService, GitRepositoryService, GitBrowseService). Migration is a reshape of the resource/DTO layer, not new domain logic.
  • MergeRequest entity maps cleanly to a Gitea pull request: number, title, description, sourceBranch, targetBranch, status {OPEN, MERGED, CLOSED}, mergedAt, assignee, reviewer.

Gap table (Gitea contract → git-shark today → work)

Gitea endpoint git-shark today Work
GET /version none stub; return a version matching implemented features
GET /user /api/v1/user exists reshape to {id, login, email, full_name} — easy
GET /repos/{o}/{r} /api/v1/repos/{owner}/{name} exists reshape + add default_branch (from git), archived/empty/mirror, clone_url, merge flags — medium
GET /repos/{o}/{r}/branches/{b} UI-only, no REST new: read git ref via GitBrowseService{name, commit.id, protected} — medium
pulls (create/get/list, GET pulls/{base}/{head}, POST .../merge) MR create/get/list/merge/close exist under /merge-requests/{number} rename merge-requestspulls, reshape; find-by-branch = filter list — medium
PATCH pulls/{index} (title/body/state) no REST update (UI only) wire MR update into API — medium
GET /repos/{o}/{r}/contents/{path} UI raw only small git-backed endpoint; Renovate mostly clones — low
GET labels, PUT/DELETE issue labels no Label model stub GET[]; skip if labels config empty — low
POST /statuses/{sha}, GET /commits/{b}/statuses no status store (CI runners exist, unwired) stub empty combined status → Renovate proceeds — low
Issues + comments (dependency dashboard) Issue exists but status enum {PLANNED, IN_DEVELOPMENT, DONE} ≠ open/closed; issue-comments MCP-only defer — set dependencyDashboard: false — medium-large if wanted
Authorization: token <PAT> scheme only Bearer/Basic parsed add token scheme to ApiTokenAuthFilter — trivial
autodiscover (/repos/search, /orgs/{o}/repos) list exists defer — pin repos in repositories: config — optional

(Authoritative endpoint list taken from Renovate's Gitea platform client: gitea-helper.ts + index.ts.)


Plan

MVP — Renovate opens / updates / merges dependency PRs

  • Add token <PAT> scheme to ApiTokenAuthFilter.
  • Reshape existing /api/v1 resources + DTOs to the Gitea contract: GET /version, GET /user, GET /repos/{o}/{r}, GET /repos/{o}/{r}/branches/{b}, full pulls (create/get/list/find-by-branch/patch/merge), GET labels[], commit-status stubs.
  • Rename merge-requests resource path → pulls; expose per-repo number as the Gitea index and add an int64 id.
  • Wire an MR update path (title/description/state) into the API.
  • Config: pin repos in repositories:, set dependencyDashboard: false.
  • Estimate: ~4–6 dev-days incl. test-first + a real Renovate LOG_LEVEL=debug integration run.

Phase 2

  • Dependency dashboard (Issue open/closed mapping + issue-comment REST endpoints).
  • Real Label model.
  • Wire CI runner status into the commit-status API.
  • Estimate: +3–5 dev-days.

Risks / caveats

  1. MCP shares DTOs. MCP tools return ApiModels DTOs directly (shared with REST). Reshaping REST → Gitea shape changes MCP output too. Two handlings: (a) accept it — Gitea-shaped JSON is fine, arguably richer, for MCP's AI-agent consumers (zero extra work); (b) decouple — give MCP its own thin DTOs (small). Recommend (a) now, decouple only if it chafes.
  2. Vocab split. The Gitea contract says "pull request"; the domain/UI say "merge request". Keep the domain naming (MergeRequest*) internal and only speak Gitea at the wire. Cosmetic but permanent.
  3. JSON fidelity. Renovate deserializes exact Gitea field names; a mismatch fails silently. Validate against a real Renovate debug run, not just unit tests.
  4. Version string. Report the version that matches what is implemented: >= 1.24.0 unlocks delete_branch_after_merge; >= 1.14.0 makes Renovate call requested_reviewers — report lower until those are implemented so Renovate does not call unimplemented endpoints.
  5. Surrogate id. Gitea needs an int64 id; git-shark uses UUID PK + per-repo number. Expose number as the index and add a stable int id.

Docs to update on implementation

  • docs/admins/ — the reshaped /api/v1 contract, config/reverse-proxy notes, Renovate setup, the GITSHARK_* config-reference table if any new property is added.
  • docs/maintainers/ — Gitea-compatibility scope, component map, "works today / still needed" lists.
  • docs/users/ — how to enable Renovate against a git-shark repo.
  • Root README.md — feature list.

Acceptance

  • A real Renovate run (platform: "gitea", endpoint: https://gitshark.de/api/v1) against a git-shark repo opens a dependency-update PR, updates it on a new version, and merges it — end to end.

Comments 0

No comments yet.

Log in to comment.

Keyboard shortcuts

?Show this help
g hGo home
EscClose dialog