`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>
3.0 KiB
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:
GiteaClientusing Spring'sRestClient.publishStatus(sha, state, description, targetUrl)→POST /api/v1/repos/{owner}/{repo}/statuses/{sha}with headerAuthorization: token <git.token>; body fieldsstate,context,description,target_url.readStatus(sha)→GET /api/v1/repos/{owner}/{repo}/commits/{sha}/statuses?sort=recentupdate; pick the newest entry matchinggitea.statusContext.resolveUsername()→GET /api/v1/user(used as fallback forgit.account).- State mapping in both directions (
BuildStatus↔ Giteasuccess|failure|pending|error), as in the legacy analysis. isEnabled()— true only whengitea.baseUrl,gitea.owner,gitea.repo, andgit.tokenare 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 ktlintFormatthen./gradlew buildis 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-webas a dependency;RestClientlives there andspring-boot-starteralone does not provide it. publishStatustakes aBuildStatusand maps it internally instead of a raw Gitea state string. The forward mapping never produceserrorbecause theBuildStatusenum is exhaustive; legacy emittederroronly for unknown status strings.readStatusreturns a sealedGiteaStatusResult(Found/None/Disabled/Error) so callers get explicit non-fatal error states instead of exceptions.resolveUsernameonly requiresgitea.baseUrlandgit.token; legacy gated it on the full status-enabled check including owner/repo, which the/api/v1/userendpoint does not need.- Responses are read as strings and parsed with a dedicated Jackson
ObjectMapperinstead 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.*andgit.tokenalready exist inWerkatorConfig, theinittemplates, anddocs/configuration.md.