Files
werkator/docs/plan/03-gitea-client.md
mhoennigandClaude Opus 5 35f06ec1ec Rename GitTally to Werkator
`gitTally` is the name of another product in the git space, so the
rename is a precaution; nothing about what the build system does changes.

The name follows one rule: `Werkator` where it is prose, capitalized
where it is a Kotlin type and its file, lowercase everywhere a machine
reads it — the command, packages, paths, configuration keys and values,
the Gitea check context. Environment variables keep their convention and
are uppercase throughout.

Every configuration file is still found under its pre-rename name
(`ConfigFiles`): `.gittally.yml` at the repository root, in a build
worktree and as committed on a branch, `.git/gittally/.gittally.yml` for
the machine layer. The current name wins where both exist, and the old
file is then ignored rather than merged — two files side by side are a
half-done rename, not a layering. Without the fallback an installation
that updated without renaming would not fail: a configuration that is
not found leaves every setting at its default, so it would come up
looking healthy while having forgotten its credentials and its builds.

`docs/werkator-migrationsplan.md` lists what the fallback does not
cover and has to be moved by hand — above all the state directory
`.git/werkator/`, which holds the build history, the control token and
the worktrees, and has no fallback of its own.

`docs/migration-from-legacy.md` is deleted with this: it mapped the
legacy script's environment variables, and every host it addressed has
long since moved to the YAML configuration.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-30 19:39:55 +02:00

3.0 KiB

Step 03: Gitea Client

Prerequisites: step 01 (for BuildStatus). Read README.md and 00-legacy-analysis.md first.

Goal

A tested client for the Gitea commit-status API.

Design

Create package de.hoennig.werkator.gitea:

  • GiteaClient using Spring's RestClient.
  • publishStatus(sha, state, description, targetUrl)POST /api/v1/repos/{owner}/{repo}/statuses/{sha} with header Authorization: token <git.token>; body fields state, context, description, target_url.
  • readStatus(sha)GET /api/v1/repos/{owner}/{repo}/commits/{sha}/statuses?sort=recentupdate; pick the newest entry matching gitea.statusContext.
  • resolveUsername()GET /api/v1/user (used as fallback for git.account).
  • State mapping in both directions (BuildStatus ↔ Gitea success|failure|pending|error), as in the legacy analysis.
  • isEnabled() — true only when gitea.baseUrl, gitea.owner, gitea.repo, and git.token are configured. All callers must treat a disabled or failing client as non-fatal (log and continue); the legacy behaved the same but failed silently.

Configuration comes from WerkatorConfig (gitea.*, git.token).

Out of Scope

  • No callers yet; the build executor (step 04) wires status publishing.
  • No webhook receiving; Werkator remains poll-based.

Tests

WireMock (already a test dependency, see WireMockSmokeTest):

  • Publish: correct URL, auth header, JSON body per status.
  • Read: filtering by context, newest-first, empty result, malformed JSON → error status, HTTP 4xx/5xx → non-fatal error result.
  • State-mapping unit tests.

Acceptance Criteria

  • ./gradlew ktlintFormat then ./gradlew build is green.
  • No call path throws when Gitea is unconfigured or down.

Execution Notes (2026-07-07)

Implemented as designed; deviations and decisions:

  • Added org.springframework:spring-web as a dependency; RestClient lives there and spring-boot-starter alone does not provide it.
  • publishStatus takes a BuildStatus and maps it internally instead of a raw Gitea state string. The forward mapping never produces error because the BuildStatus enum is exhaustive; legacy emitted error only for unknown status strings.
  • readStatus returns a sealed GiteaStatusResult (Found/None/Disabled/Error) so callers get explicit non-fatal error states instead of exceptions.
  • resolveUsername only requires gitea.baseUrl and git.token; legacy gated it on the full status-enabled check including owner/repo, which the /api/v1/user endpoint does not need.
  • Responses are read as strings and parsed with a dedicated Jackson ObjectMapper instead of RestClient message converters, keeping malformed-JSON handling explicit and independent of converter auto-detection.
  • The legacy "Build status deleted" description marker is not ported; it belongs to the result-delete feature of later steps.
  • No config changes were needed: gitea.* and git.token already exist in WerkatorConfig, the init templates, and docs/configuration.md.