v0.9.19 — 2026-08-29
- A build definition now describes its build completely:
requirePullRequestand the wholedockersection, the sandbox policy included, live inbuilds.<name>.builds.defaultis the base every other definition inherits its settings from — never its trigger, becauseonPush,atTimes,branches, andactiveWithinsay when and where that one build runs. - The per-branch
branchessection is thereby superseded and will be removed. It is still read, but only while nothing defines a build at all: as soon as one real definition exists — a leftoverbuilds.maxConcurrentis not one —branchesis ignored completely and a warning names it. Either or, never both: two half-answers to what a build runs would pull against each other. requirePullRequest,docker.enabled, anddocker.networkstay pinned to the host, wherever a branch writes them. Since the inheritance is applied after all configuration layers are merged, a build a branch invents and the host has never heard of still inherits the host'sbuilds.default— it cannot reach a native build by defining a new job.- Fixed: the archived artifact directories came from the plain branch
settings, so a build definition adding its own
artifactDirs— a release job storingbuild/libs, say — never had them stored. - Fixed: the build definitions of a branch were cached by its head commit alone, so an edited machine or project configuration only took effect once that branch moved. On a quiet branch, a new scheduled job never started at all.
v0.9.18 — 2026-08-29
- A configuration file can declare which GitTally it is written for, so a version
that renames or drops a key says so instead of silently ignoring what it no longer
understands:
gitTally: { version: { since: "0.9.18", below: "2.0" } }.sinceis enforced — both against a GitTally that is too old and against a file written before the version in which the configuration format last changed incompatibly, which GitTally knows about itself.belowis a release marker and only warns, so an unmaintained value can never stop a build. - The reach follows the file: the machine and project configuration abort the start
naming the file and the way back, an incompatible configuration committed on a
branch fails only that branch's builds. A file that declares nothing keeps working,
and
gittally initwrites the current version into the config it generates.
v0.9.17 — 2026-08-29
- Fixed: a page left in the background — a phone tab switched away from for an hour — kept showing the state it was left in, with the durations of running builds counting up client-side although the builds had long finished. A returning page now fetches the current state immediately, whether the browser reports the return as a visibility change, a focus, or a restore from its cache.
v0.9.16 — 2026-08-29
- A scheduled build can run hourly:
atTimes: ["??:05"]stands for that minute of every hour. Each hour is its own slot, so it triggers once per hour — mixing it with fixedHH:MMtimes works, the latest due slot wins. Only the hour may be a wildcard; anything else is skipped with a warning. - Fixed: the artifact page showed the build command of the plain
branch configuration — for a build of a named definition, or on a branch whose
committed
.gittally.ymloverrides the command, that was a command the build never ran. It now shows what this build actually runs, resolved from the branch configuration committed at the build's own commit plus its definition.
v0.9.15 — 2026-08-29
- The
.gittally.ymlcommitted on a branch now takes precedence for thebuildssection as well — a branch can define its own build definitions and override those from the project config. The watcher reads each origin branch's committed configuration, so a new build definition takes effect by committing it on a branch, without touching any other branch's builds. A branch's definitions apply to that branch alone. - Pinned to the server side are only the keys that do not describe the branch's build:
secrets (
git), the host and repository sections (server,gitea,executor,watcher), the container sandbox policy (docker.enabled,docker.network), and therequirePullRequestgate. - Changed: the build concurrency limit moved from
builds.maxConcurrenttoexecutor.maxConcurrent(default 1, no compatibility alias) — thebuildssection now holds build definitions only. A leftoverbuilds.maxConcurrentkey is ignored with a warning instead of failing the configuration, so an installation keeps running until its committed config can be updated.
v0.9.14 — 2026-08-28
- Named build definitions (ADR 0007): the
buildssection of.gittally.ymlnow defines jobs withonPush/atTimestriggers, branch selectors (name globs,activeWithinage filter), and overrides of the branch settings — e.g. a nightlypitestbuild running a fuller check than the quick on-push builds. A named build records under its own<branch>@<build>pool with its own branches-view row, retention count, and permanent latest-green artifact link. - Restart,
gittally retry, and the startup recovery re-run a build under its recorded definition, resolving the settings from the current configuration. - Changed: the v0.9.13 per-slot
buildCommand/namesyntax inautoBuild.timesis gone again — use a build definition instead.branches.*.autoBuildwith plain times keeps working but is deprecated.
v0.9.13 — 2026-08-28
- A scheduled auto-build slot (
autoBuild.timesentry) can carry its ownbuildCommand, so a nightly slot runs a fuller check than the quick on-commit builds of the same branch. Restart, retry, and the startup recovery repeat a build with the command it originally ran. - A slot can also carry a
name(e.g.master@nightly): its builds then get their own row in the branches view, their own history and retention pool, and their own permanent latest-green artifact link (/branches/master_nightly/…) — the branch's regular builds no longer displace the nightly build and its artifacts.
v0.9.12 — 2026-08-26
- A build whose branch is deleted from origin mid-build (the usual fate of a merged branch) no longer vanishes from the UI and history while it is still queued or running — previously the queue looked stuck although a build was executing.
- Triggering a build that is already queued or running for the same commit no longer stacks a duplicate — an impatient double-click on restart now hits the existing build. Re-running a finished build is unaffected.
v0.9.11 — 2026-08-14
- At the end of each poll cycle, the local branch refs of the watched repository are
fast-forwarded to their state on origin, so build steps that compare a branch with its
origin counterpart no longer fail once origin moved on. Only fast-forwards are applied —
a branch that diverged from origin or is ahead of it stays untouched. Switched off with
watcher.fastForwardLocalRefs: false. - On the artifact index of a failed build, the logs that actually contain the build tool's failure line carry a failed badge — with stdout and stderr stored separately, that points straight at the log worth opening. Logs of a green build are not scanned.
v0.9.10 — 2026-08-11
- The control token is no longer embedded in the pages — reading them is unauthenticated,
so anyone could have picked it out of the HTML. Viewing stays public; the first click on
a restart/cancel/delete button asks for the token once (it is in
.git/gittally/control-tokenon the host) and keeps it in the browser.
v0.9.9 — 2026-08-11
- Changed default:
server.bindAddressis now127.0.0.1instead of0.0.0.0, because neither the UI nor the API authenticates read access. Existing.gittally.ymlfiles keep whatever they set; with the managed nginx container,0.0.0.0has to be set explicitly. - The control token is accepted in the
X-GitTally-Tokenheader only — thetokenquery parameter is gone, as URLs end up in access logs and browser history. config:printmasksgit.token;--show-secretsprints it.- Files holding secrets (the Gitea token written by
init, the control token) are created with mode0600right away instead of beingchmod-ed afterwards, the control token is compared in constant time, and git calls pass--before branch names. - On narrow screens the page title and the repository name are stacked instead of wrapping.
v0.9.8 — 2026-08-10
- The artifact index also links report pages of directories without an
index.html. A directory holding a single page is linked as a directory, so Gradle's--profilereport keeps a stable URL although its file name carries the build timestamp. - The permanent
🔗link now appears on the build it resolves to — the branch's latest green build — instead of on every build of that branch, and on all build tables. - The Current tab gave way to a
📡link in the artifacts column, shown while a build runs.
v0.9.7 — 2026-08-10
init --systemdalso installs a nightly Docker cleanup timer (gittally-docker-prune.timer, 02:00 host time): stopped containers and unused images are pruned before the auto builds — like the legacy host, but the per-repository Gradle cache volumes survive.
v0.9.6 — 2026-08-10
- This release-notes page, linked from the version in the footer.
- Mobile: the live indicator collapses to a colored state dot so it no longer squeezes the menu.
- The system page highlights critical utilization: the current value of CPU, RAM, and disk used turns orange from 80% and red from 90% of the respective total.
v0.9.5 — 2026-08-10
- Builds killed by a server shutdown (e.g. a deployment restart) are recorded as interrupted instead of failed, publish a pending Gitea status, and are re-enqueued when the server starts again.
v0.9.4 — 2026-08-10
- The legacy page names (
/index.html,/branches.html, …) answer with permanent redirects to the new routes, so pre-rewrite bookmarks and the redirect from the old host keep working.
v0.9.3 — 2026-08-10
- The artifact page shows a n failed badge behind links to test reports that contain failures.
v0.9.2 — 2026-08-10
- Cancelling a build also terminates its auxiliary phases (Docker image build, Gradle cache volume preparation), so the next queued build starts immediately.
v0.9.1 — 2026-08-10
- Durations no longer flicker while live-updating.
- While a build is running or pending, the artifact link shows an hourglass (logs only, so far) instead of the report icon.
- Pending builds show their queue wait time in italics; running and finished builds show the pure build time without the wait.
v0.9.0 — 2026-08-10
Port of the legacy gitTally bash script to Kotlin/Spring Boot — the first production deployment of the rewrite.
- Dual-mode application: CLI (
init,status,build,retry,config:print) and HTTP server with this web UI and a JSON API. - Declarative YAML configuration: committed
.gittally.ymlplus machine-specific overrides and secrets under.git/gittally/. - Builds run detached in git worktrees — the primary checkout is never used for builds.
- Docker build containers with automatic image rebuilds and a per-repository Gradle cache volume; works under rootless Docker daemons; git metadata is available read-only inside the container.
- Branch watcher with auto-builds (nightly slots), a pull-request gate, and pruning of results, artifacts, and stale worktrees.
- Commit statuses reported to Gitea; artifact store with per-branch retention and permanent latest-green links; system metrics page.
- Managed nginx/TLS container (Let's Encrypt) for hosts without a reverse proxy;
init --systemdgenerates the service unit. - Self-contained runtime bundle (jlink-trimmed JRE + jar) for hosts without a Java runtime.