Files
werkator/docs/plan/04-build-executor.md
T

2.6 KiB

Step 04: Build Executor

Prerequisites: steps 01, 02, 03. Read README.md and 00-legacy-analysis.md first.

Goal

Asynchronous build execution with log capture, cancellation, and immediately visible status transitions. This step fixes the legacy defect that nothing could observe status changes while a build ran.

Design

Create package de.hoennig.gittally.build (extends step 01):

  • BuildExecutor service; one build at a time (a ReentrantLock or single-thread executor replaces the legacy flock file).
  • startBuild(branch, commit) runs asynchronously and returns immediately; expose currentBuild(): RunningBuild?.
  • Execution sequence per build:
    1. Record PENDING, then RUNNING via BuildResultRepository; publish each transition to Gitea (non-fatal on failure).
    2. Run the branch's cleanCommand, then buildCommand (from the merged branches config) via ProcessBuilder with the branch name in the environment as branch.
    3. Stream stdout/stderr to the configured log files in a working/staging directory, plus a combined live log file.
    4. On exit: record SUCCESS/FAILED, publish status, hand the staging directory to the artifact store (step 05 interface; use a stub interface now if 05 is not done).
  • Cancellation: cancel() flag checked by a monitor; destroy the process tree (ProcessHandle.descendants(), TERM-wait-KILL like legacy terminate_process_tree); record CANCELLED.
  • Status transitions must be readable at any time via the repository — no in-memory-only state.

Emit a Spring ApplicationEvent on every status transition so the UI (step 08) can later push updates without polling internals.

Out of Scope

  • Docker execution (step 11); native ProcessBuilder only, but keep a BuildRunner interface so Docker can plug in.
  • Scheduling and branch selection (step 06).
  • Artifact index HTML (step 05/08).

Config

Uses existing branches.<name>.buildCommand/cleanCommand/stdoutLog/stderrLog. Consider builds.timeout only if trivial; otherwise defer.

Tests

  • Fake commands (sh -c 'echo ok', failing command, sleeping command) in temp dirs.
  • Status sequence assertions: pending → running → success/failed/cancelled, each persisted before/after execution.
  • Cancellation kills a sleeping process tree and records CANCELLED.
  • Log files contain captured output; live log grows during the build (poll in test).
  • Gitea publishing mocked with MockK; a Gitea failure must not fail the build.

Acceptance Criteria

  • ./gradlew ktlintFormat then ./gradlew build is green.
  • While a test build sleeps, the repository reports RUNNING — proven by a test.