5.6 KiB
Legacy werkator Analysis
Condensed analysis of legacy/werkator (bash, ~6000 lines) as input for the rewrite.
Line numbers refer to the legacy script at the time of analysis (version 0.7.8).
What the Legacy System Does
A single bash daemon per repository that:
- Polls
originfor changed local branches and recent new origin branches. - Checks out and builds each changed branch (natively or in Docker), one at a time.
- Records results and publishes commit statuses to Gitea.
- Archives build logs and report directories as browsable artifacts.
- Serves a static-HTML web UI via an embedded Python HTTP server.
- Optionally manages an nginx+certbot Docker container for HTTPS.
- Installs itself as a systemd user service.
Persistent State (formats to replace)
All state lives in files; there is no database.
| File | Format | Content |
|---|---|---|
.git/git-watch-origin-and-test/build-results.tsv |
TSV | branch, commit, status, timestamp, duration(MM:SS), artifact_key |
.git/git-watch-origin-and-test/auto-builds.tsv |
TSV | branch, date, time_slot — prevents double auto-builds |
.git/git-watch-origin-and-test/build.lock |
flock file | build mutex, holder found via fuser/lsof |
.git/git-watch-origin-and-test/cancel-* |
touch/token files | cancellation request/token/accepted handshake |
$TMPDIR/git-watch-origin-and-test/<repo_key>/ |
HTML + files | artifact root: generated pages, per-build artifact dirs |
<artifact_root>/system.json + system_state.dat |
JSON + text | system metrics snapshot and aggregation state |
Build statuses: pending, running, success, failed, interrupted, cancelled (legacy alias passed → success).
Artifact key naming: sanitized branch + 12-char SHA256 prefix, plus sanitized timestamp + hash for per-build dirs.
External Interactions
Git (always via CLI): rev-parse, for-each-ref, fetch, switch, reset --hard, show -s --format=%cI, rev-list.
HTTPS git auth uses a generated GIT_ASKPASS script feeding username + Gitea token.
Gitea API:
POST /api/v1/repos/{owner}/{repo}/statuses/{sha}— publish status; payloadstate,context,description,target_url.GET /api/v1/repos/{owner}/{repo}/commits/{sha}/statuses?sort=recentupdate— read statuses, filtered bycontext.GET /api/v1/user— resolve username from token.- State mapping: success→success; failed/interrupted/cancelled→failure; pending/running→pending.
Web control endpoints (Python handler):
GET /control/status?commit=<sha>&local_status=<s>— proxy Gitea status for a commit.POST /control/cancel— cancel running build (CSRF-token protected).POST /control/restart— append a new pending result row.POST /control/delete— remove a result row and patch HTML files via regex.
Root Causes of the Known Bugs
Stuck loading animation (UI):
- Status cells start as
status-loadingand each row fetches/control/statuswith a 15s timeout; failures leave the spinner forever (no error state). - Page auto-refresh re-fetches the page HTML and diffs
#build-rows; HTML is regenerated server-side by regex-patching files, which fails silently when structure drifts. - "Current" and "System" nav views exist, but the page generator only implements
latest/branches/history, so some views fall through.
No status changes observable during a build (control loop):
- The main loop (lines ~4944–4966) is synchronous:
checkout_and_buildblocks until the build ends; only then is origin re-scanned. retry_origin_change_check()is an uninterruptible internal retry loop with 10s sleeps.- The console spinner is cosmetic and runs independently of actual progress.
Behavior Worth Preserving
- Startup recovery: mark stale
runningbuilds asinterrupted; restart restartable builds; optional retry of failed builds. - New-branch age filter (
newBranchMaxAge) to avoid building stale branches. - Auto-build time slots (UTC HH:MM) per branch with per-day/slot dedup.
- Retention per branch by count or age, pruning both results and artifact dirs.
- Per-branch build/clean command, artifact dirs, and log file names (now via
branches:YAML config). - Cancellation with token handshake; process-tree termination (TERM, wait, KILL).
- Build log capture: stdout/stderr to files plus a live "current build" log.
- Gitea status published on every transition with
target_urlpointing at the artifact page.
Not Ported (decided)
- nginx + certbot/Let's Encrypt container management — replaced by deployment documentation (step 12). Revised by ADR 0005: it IS needed for Hostsharing container hosts and returns as an opt-in feature (step 13).
- Self-install (
--install), self-update script generation — replaced by jar deployment plus systemd docs (step 12). - Legacy
HSADMIN_NG_*environment fallbacks and env-file config — replaced by YAML config (done). - Regex-based in-place HTML patching — replaced by server-rendered pages/JSON endpoints.
- Static HTML artifact index generation with embedded 900-line JavaScript — replaced by templates.
.aliasessourcing (line 731), impressum footer link handling stays optional/simple.
Orphaned or Dubious Legacy Config
Verify need before porting any of these:
werkator_BUILD_DOCKER_PREFLIGHT_COMMAND,werkator_BUILD_DOCKER_JAVA_TOOL_OPTIONS— highly hsadmin-ng-specific defaults.werkator_ARTIFACT_NGINX_*,werkator_ARTIFACT_LETSENCRYPT_EMAIL— dropped with nginx management; revived asserver.nginx.*by step 13 (ADR 0005).werkator_IMPRESSUM_URL— keep as optional simple footer link if wanted.werkator_INSTALL_DIR— dropped with self-install.