2.6 KiB
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):
BuildExecutorservice; one build at a time (aReentrantLockor single-thread executor replaces the legacy flock file).startBuild(branch, commit)runs asynchronously and returns immediately; exposecurrentBuild(): RunningBuild?.- Execution sequence per build:
- Record
PENDING, thenRUNNINGviaBuildResultRepository; publish each transition to Gitea (non-fatal on failure). - Run the branch's
cleanCommand, thenbuildCommand(from the mergedbranchesconfig) viaProcessBuilderwith the branch name in the environment asbranch. - Stream stdout/stderr to the configured log files in a working/staging directory, plus a combined live log file.
- 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).
- Record
- Cancellation:
cancel()flag checked by a monitor; destroy the process tree (ProcessHandle.descendants(), TERM-wait-KILL like legacyterminate_process_tree); recordCANCELLED. - 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
ProcessBuilderonly, but keep aBuildRunnerinterface 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 ktlintFormatthen./gradlew buildis green.- While a test build sleeps, the repository reports
RUNNING— proven by a test.