* renaming from gitTally to Werkator * Rename GitTally to Werkator `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> * Move the pre-rename state directory at the first start The configuration is found under either name, the state is not: build history, control token, auto-build slots and worktrees live at one fixed path. An installation that updates without moving `.git/gittally` would not fail — it would come up with an empty history and a fresh control token, quietly. So the first start moves it instead of the release notes asking for it. Only when the old directory exists and the new one does not. Where both exist nothing is touched and a warning names the leftover: which of the two is the live state is not something to guess. A failed move is an error in the log, never an abort — a CI must not hang on it. The worktrees are dropped rather than moved, since they point at their old path in both directions; `GitWorktreeWorkspaces` prunes the stale admin entry and recreates each on its branch's next build. A generated systemd unit moves with the directory and leaves its symlink dangling, which is warned about — the running service is unaffected, the next start is not. Runs from `CliRunner`, before any command resolves a path under the directory, and so before the second context of `server` exists. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Document PR#1: the rename to Werkator Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Drop the legacy env-to-YAML conversion from the setup tool The old bash script configured itself through `GITTALLY_*` environment variables. The blanket rename rewrote those literals, so the converter was looking for `WERKATOR_*` — a spelling no host has ever written. Fed a real legacy file it would have found nothing and written an almost empty configuration, without an error, which is the same silent failure this rename is otherwise careful to avoid. The conversion has served its purpose with the vm2176 to vm4006 migration, so it goes instead of being repaired. What remains is the setup of a new instance: the preconditions, the credential prompt, and the machine configuration written mode 600 — now carrying the host's public URL as well, since that is host-specific too. Everything the repository builds comes from `init` and its templates. It also stops emitting a legacy `branches:` section, which step 18 is about to reject outright. `docs/plan/00-legacy-analysis.md` and `13-nginx-tls.md` get the real `GITTALLY_*` spelling back: they record what the old script read. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Describe this repository's build with a build definition Its own `.werkator.yml` still used the deprecated `branches` section with an `autoBuild` schedule that was switched off. That section is read only while nothing defines a build at all, and step 18 rejects it by name — so this repository would have blocked the precondition of that step, which asks that no configuration still in play carries it. Nothing about the build changes: `builds.default` with `trigger.onPush` is a build of every new commit on every branch, which is what the branch section said. `config:print --full` resolves the definition completely and logs no deprecation warning any more. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Stop documenting the pre-rename fallback for users Exactly one repository is configured with the old names, and it is migrated by hand in the same move as this release. The fallback is therefore a transition of days, not a feature anyone reading the release notes or the configuration reference has to plan around. Removed from `releases.html` and `docs/configuration.md`. The mechanism itself is unchanged and stays described where it is worked on: in `ConfigFiles`, in `StateDirMigration`, and in the migration plan. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Bring the PR-doc to its final state The `statusContext` question is answered and marked as decided rather than left standing: it is the one value a human reads as a label, and it stays lowercase because Gitea matches it and the client reads it back, which makes it a value. Also records that the pre-rename fallback is deliberately absent from the release notes and the configuration reference. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Release v1.0.0: Werkator The release after 0.9.21 is 1.0.0, because a product that changes its name is better off counting from one under it. The release note says as much, so the jump is not read as a claim about maturity — plan steps 14, 17 and 18 are still open. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Correct the PR-doc about the version It claimed the PR carries no version bump, which the release commit made untrue, and records why the number is 1.0.0 instead of 0.9.22. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Point the legacy references at the history `legacy/gitTally` was removed from the tree with the rename, but the README still described it as a reference kept in the repository, and the plan told an executing session to read parts of it — including step 14, which is open. The README section is gone; `docs/plan/README.md`, step 14 and the legacy analysis now say where the script actually is (`git show 7f55068^:legacy/gitTally`). Executed steps and ADR 0004 keep their wording: they record what was true when they ran. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Retarget the links in the historic PR-docs The package rename moved every file the older PR-docs link to, leaving 60 dead links. Only the link targets are rewritten, never the visible text and never a statement: those documents record what was true when they were written, GitTally in the prose included. A snapshot may be outdated; it should still be navigable. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Add the v1.0.0 deployment procedure for vm4006 Measured, not estimated: the state directory is 878 MB, of which 878 MB are the nine build worktrees. What cannot be recreated is 84 KB, so the snapshot before an in-place switch is instant and the rollback is one sequence of moves. Records the three expected non-failures — a cold Gradle volume, one image rebuild, containers left under the old label — and that `gitea.statusContext` needs no attention because it comes from the watched repository's committed configuration. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Rename the machine configuration along with its directory Found by the deployment to vm4006: the move renames the directory and leaves the file inside it alone, so the machine configuration ended up at `.git/werkator/.gittally.yml` — a pair of names the lookup did not expect, because it pairs directory and file name. The instance resolved empty credentials, no public URL and none of the host's build definitions, and said nothing about it. That is the exact failure this change exists to prevent, produced by the change itself. `StateDirMigration` now renames the configuration with the directory, unless one under the current name is already there. `ConfigFiles` carries `.git/werkator/.gittally.yml` as a third candidate as well, for a directory somebody moved by hand, where the migration never runs and so can rename nothing. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Let init see a configuration under its previous name `init --systemd` runs `init`, and its "already exists" check knew only the current name. On the one repository still carrying `.gittally.yml` it therefore wrote a fresh template `.werkator.yml` beside it — and since the current name wins, that repository would have built the template's `./gradlew test` instead of what its own configuration says. Found on vm4006, where the file was created in the watched working tree and removed again by hand. Both checks now ask `ConfigFiles`, so init decides existence by the same rule the loader uses to read. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Record the v1.0.0 deployment to vm4006 Deployed from the branch as the final test of PR#1, and it did what a final test is for: it found two silent-failure defects before the service was started, both fixed and redeployed in the same window. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Drop the control token left under the old localStorage key The key is named after the product, so the rename left every browser with a token under `gittally.controlToken`, which nothing reads any more and which "forget token" can no longer reach. It is a write-scope token in a browser store, not a password, but a secret nobody owns is worth one line to remove. Removed on load. The token on the server is unchanged, so re-entering it once per browser is all the rename costs. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
320 lines
22 KiB
HTML
320 lines
22 KiB
HTML
<!doctype html>
|
|
<html xmlns:th="http://www.thymeleaf.org" lang="en">
|
|
<head th:replace="~{fragments :: head(${pageTitle})}"></head>
|
|
<body>
|
|
<main>
|
|
<h1 th:replace="~{fragments :: header(${pageTitle})}"></h1>
|
|
<div th:replace="~{fragments :: nav(${view})}"></div>
|
|
<div class="panel release-notes">
|
|
|
|
<h2>v1.0.0 <span class="muted">— 2026-08-31</span></h2>
|
|
<ul>
|
|
<li>GitTally is now <strong>Werkator</strong>. The old name already belongs to another
|
|
product in the git space, so the rename is a precaution and nothing more: what the
|
|
build system does, how it is configured, and how it reports to Gitea are unchanged.
|
|
In prose it is Werkator, everywhere a machine reads the name it is
|
|
<code>werkator</code>. The version marks the new name rather than a claim about
|
|
maturity: the release after <code>0.9.21</code> is <code>1.0.0</code>, because a
|
|
product that changes its name is better off counting from one under it.</li>
|
|
<li>The rename reaches the file names an installation depends on. The committed
|
|
configuration is <code>.werkator.yml</code>, the machine-specific one
|
|
<code>.git/werkator/.werkator.yml</code>, and all state — build results, artifacts,
|
|
worktrees, the control token — lives under <code>.git/werkator/</code>.</li>
|
|
<li>The default Gitea check context is <code>werkator</code>. Where the old name is
|
|
pinned in a branch protection rule, the rule has to be updated with it, or a pull
|
|
request waits forever for a check nobody posts any more. Statuses already written
|
|
keep their old context, so a commit built before and after the change shows
|
|
both.</li>
|
|
</ul>
|
|
|
|
<h2>v0.9.21 <span class="muted">— 2026-08-30</span></h2>
|
|
<ul>
|
|
<li>An origin the watcher cannot reach is now visible in the web UI: a banner above the
|
|
table says that the list below is not updating, since when, and why. Until now the
|
|
page kept showing its last known state, calm and plausible, while GitTally had not
|
|
been able to fetch for an hour — the failure lived in the log alone. The banner is
|
|
deliberately separate from the live indicator: that one says whether your browser
|
|
reaches the server, this one whether the server reaches origin.</li>
|
|
<li>A lasting fetch failure is logged when its message changes instead of on every poll
|
|
cycle, and the recovery is logged once. One wrong token used to write several hundred
|
|
identical warnings an hour. An invalid <code>atTimes</code> slot is likewise reported
|
|
once per slot.</li>
|
|
</ul>
|
|
|
|
<h2>v0.9.20 <span class="muted">— 2026-08-29</span></h2>
|
|
<ul>
|
|
<li>A build definition is now split in two: a <code>trigger</code> block says when the
|
|
build runs and for which branches (<code>onPush</code>, <code>atTimes</code>,
|
|
<code>branches</code>, <code>activeWithin</code>), everything beside it says what
|
|
the build does. Only the second half is inherited from <code>builds.default</code>,
|
|
and making that structural means a selector added later cannot become inheritable
|
|
by accident. A definition still writing those keys flat is refused by name — a
|
|
trigger nobody reads any more is a build that silently stops running.</li>
|
|
<li>A branch pattern prefixed with <code>!</code> excludes instead of selecting, and an
|
|
exclusion wins whatever the order: <code>branches: ["*", "!master"]</code> is every
|
|
branch but master. That lets one branch have a build of its own without being built
|
|
by the default one as well — previously the only way to avoid the double build was
|
|
to give up the second definition's push trigger.</li>
|
|
<li>A build may report under its own Gitea check with <code>statusContext</code>; empty
|
|
keeps the repository-wide <code>gitea.statusContext</code>. Two builds of one commit
|
|
used to overwrite each other's result there, so a second build over the same branch
|
|
— a quick check next to a long one — was not readable in Gitea.</li>
|
|
<li><strong>Fixed:</strong> a branch whose builds all belong to named definitions showed
|
|
an empty row in the branches view, reading as "never built" right next to its actual
|
|
builds.</li>
|
|
</ul>
|
|
|
|
<h2>v0.9.19 <span class="muted">— 2026-08-29</span></h2>
|
|
<ul>
|
|
<li>A build definition now describes its build completely: <code>requirePullRequest</code>
|
|
and the whole <code>docker</code> section, the sandbox policy included, live in
|
|
<code>builds.<name></code>. <code>builds.default</code> is the base every other
|
|
definition inherits its settings from — never its trigger, because
|
|
<code>onPush</code>, <code>atTimes</code>, <code>branches</code>, and
|
|
<code>activeWithin</code> say when and where that one build runs.</li>
|
|
<li>The per-branch <code>branches</code> section 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 leftover <code>builds.maxConcurrent</code> is not one
|
|
— <code>branches</code> is ignored completely and a warning names it. Either or,
|
|
never both: two half-answers to what a build runs would pull against each other.</li>
|
|
<li><code>requirePullRequest</code>, <code>docker.enabled</code>, and
|
|
<code>docker.network</code> stay 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's
|
|
<code>builds.default</code> — it cannot reach a native build by defining a new
|
|
job.</li>
|
|
<li><strong>Fixed:</strong> the archived artifact directories came from the plain branch
|
|
settings, so a build definition adding its own <code>artifactDirs</code> — a
|
|
release job storing <code>build/libs</code>, say — never had them stored.</li>
|
|
<li><strong>Fixed:</strong> 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.</li>
|
|
</ul>
|
|
|
|
<h2>v0.9.18 <span class="muted">— 2026-08-29</span></h2>
|
|
<ul>
|
|
<li>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:
|
|
<code>gitTally: { version: { since: "0.9.18", below: "2.0" } }</code>.
|
|
<code>since</code> is 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. <code>below</code> is a
|
|
release marker and only warns, so an unmaintained value can never stop a build.</li>
|
|
<li>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 <code>gittally init</code> writes the current version into the config it
|
|
generates.</li>
|
|
</ul>
|
|
|
|
<h2>v0.9.17 <span class="muted">— 2026-08-29</span></h2>
|
|
<ul>
|
|
<li><strong>Fixed:</strong> 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.</li>
|
|
</ul>
|
|
|
|
<h2>v0.9.16 <span class="muted">— 2026-08-29</span></h2>
|
|
<ul>
|
|
<li>A scheduled build can run hourly: <code>atTimes: ["??:05"]</code> stands for that
|
|
minute of every hour. Each hour is its own slot, so it triggers once per hour —
|
|
mixing it with fixed <code>HH:MM</code> times works, the latest due slot wins.
|
|
Only the hour may be a wildcard; anything else is skipped with a warning.</li>
|
|
<li><strong>Fixed:</strong> 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 <code>.gittally.yml</code> overrides 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.</li>
|
|
</ul>
|
|
|
|
<h2>v0.9.15 <span class="muted">— 2026-08-29</span></h2>
|
|
<ul>
|
|
<li>The <code>.gittally.yml</code> committed on a branch now takes precedence for the
|
|
<code>builds</code> section 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.</li>
|
|
<li>Pinned to the server side are only the keys that do not describe the branch's build:
|
|
secrets (<code>git</code>), the host and repository sections (<code>server</code>,
|
|
<code>gitea</code>, <code>executor</code>, <code>watcher</code>), the container sandbox
|
|
policy (<code>docker.enabled</code>, <code>docker.network</code>), and the
|
|
<code>requirePullRequest</code> gate.</li>
|
|
<li><strong>Changed:</strong> the build concurrency limit moved from
|
|
<code>builds.maxConcurrent</code> to <code>executor.maxConcurrent</code> (default 1,
|
|
no compatibility alias) — the <code>builds</code> section now holds build definitions
|
|
only. A leftover <code>builds.maxConcurrent</code> key is ignored with a warning
|
|
instead of failing the configuration, so an installation keeps running until its
|
|
committed config can be updated.</li>
|
|
</ul>
|
|
|
|
<h2>v0.9.14 <span class="muted">— 2026-08-28</span></h2>
|
|
<ul>
|
|
<li>Named build definitions (ADR 0007): the <code>builds</code> section of
|
|
<code>.gittally.yml</code> now defines jobs with <code>onPush</code>/<code>atTimes</code>
|
|
triggers, branch selectors (name globs, <code>activeWithin</code> age filter), and
|
|
overrides of the branch settings — e.g. a nightly <code>pitest</code> build running a
|
|
fuller check than the quick on-push builds. A named build records under its own
|
|
<code><branch>@<build></code> pool with its own branches-view row, retention
|
|
count, and permanent latest-green artifact link.</li>
|
|
<li>Restart, <code>gittally retry</code>, and the startup recovery re-run a build under its
|
|
recorded definition, resolving the settings from the current configuration.</li>
|
|
<li><strong>Changed:</strong> the v0.9.13 per-slot <code>buildCommand</code>/<code>name</code>
|
|
syntax in <code>autoBuild.times</code> is gone again — use a build definition instead.
|
|
<code>branches.*.autoBuild</code> with plain times keeps working but is deprecated.</li>
|
|
</ul>
|
|
|
|
<h2>v0.9.13 <span class="muted">— 2026-08-28</span></h2>
|
|
<ul>
|
|
<li>A scheduled auto-build slot (<code>autoBuild.times</code> entry) can carry its own
|
|
<code>buildCommand</code>, 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.</li>
|
|
<li>A slot can also carry a <code>name</code> (e.g. <code>master@nightly</code>): 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
|
|
(<code>/branches/master_nightly/…</code>) — the branch's regular builds no longer
|
|
displace the nightly build and its artifacts.</li>
|
|
</ul>
|
|
|
|
<h2>v0.9.12 <span class="muted">— 2026-08-26</span></h2>
|
|
<ul>
|
|
<li>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.</li>
|
|
<li>Triggering a build that is already queued or running for the same commit no longer
|
|
stacks a duplicate — an impatient double-click on <em>restart</em> now hits the
|
|
existing build. Re-running a finished build is unaffected.</li>
|
|
</ul>
|
|
|
|
<h2>v0.9.11 <span class="muted">— 2026-08-14</span></h2>
|
|
<ul>
|
|
<li>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
|
|
<code>watcher.fastForwardLocalRefs: false</code>.</li>
|
|
<li>On the artifact index of a failed build, the logs that actually contain the build tool's
|
|
failure line carry a <span class="status status-failed">failed</span> badge — with stdout
|
|
and stderr stored separately, that points straight at the log worth opening. Logs of a
|
|
green build are not scanned.</li>
|
|
</ul>
|
|
|
|
<h2>v0.9.10 <span class="muted">— 2026-08-11</span></h2>
|
|
<ul>
|
|
<li>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
|
|
<code>.git/gittally/control-token</code> on the host) and keeps it in the browser.</li>
|
|
</ul>
|
|
|
|
<h2>v0.9.9 <span class="muted">— 2026-08-11</span></h2>
|
|
<ul>
|
|
<li><strong>Changed default:</strong> <code>server.bindAddress</code> is now <code>127.0.0.1</code>
|
|
instead of <code>0.0.0.0</code>, because neither the UI nor the API authenticates read access.
|
|
Existing <code>.gittally.yml</code> files keep whatever they set; with the managed nginx
|
|
container, <code>0.0.0.0</code> has to be set explicitly.</li>
|
|
<li>The control token is accepted in the <code>X-GitTally-Token</code> header only — the
|
|
<code>token</code> query parameter is gone, as URLs end up in access logs and browser history.</li>
|
|
<li><code>config:print</code> masks <code>git.token</code>; <code>--show-secrets</code> prints it.</li>
|
|
<li>Files holding secrets (the Gitea token written by <code>init</code>, the control token) are
|
|
created with mode <code>0600</code> right away instead of being <code>chmod</code>-ed afterwards,
|
|
the control token is compared in constant time, and git calls pass <code>--</code> before
|
|
branch names.</li>
|
|
<li>On narrow screens the page title and the repository name are stacked instead of wrapping.</li>
|
|
</ul>
|
|
|
|
<h2>v0.9.8 <span class="muted">— 2026-08-10</span></h2>
|
|
<ul>
|
|
<li>The artifact index also links report pages of directories without an <code>index.html</code>.
|
|
A directory holding a single page is linked as a directory, so Gradle's <code>--profile</code>
|
|
report keeps a stable URL although its file name carries the build timestamp.</li>
|
|
<li>The permanent <code>🔗</code> 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.</li>
|
|
<li>The <em>Current</em> tab gave way to a <code>📡</code> link in the artifacts column,
|
|
shown while a build runs.</li>
|
|
</ul>
|
|
|
|
<h2>v0.9.7 <span class="muted">— 2026-08-10</span></h2>
|
|
<ul>
|
|
<li><code>init --systemd</code> also installs a nightly Docker cleanup timer
|
|
(<code>gittally-docker-prune.timer</code>, 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.</li>
|
|
</ul>
|
|
|
|
<h2>v0.9.6 <span class="muted">— 2026-08-10</span></h2>
|
|
<ul>
|
|
<li>This release-notes page, linked from the version in the footer.</li>
|
|
<li>Mobile: the live indicator collapses to a colored state dot so it no longer squeezes the menu.</li>
|
|
<li>The system page highlights critical utilization: the current value of CPU, RAM, and disk used
|
|
turns <span class="metric-warn">orange from 80%</span> and
|
|
<span class="metric-crit">red from 90%</span> of the respective total.</li>
|
|
</ul>
|
|
|
|
<h2>v0.9.5 <span class="muted">— 2026-08-10</span></h2>
|
|
<ul>
|
|
<li>Builds killed by a server shutdown (e.g. a deployment restart) are recorded as
|
|
<span class="status status-interrupted">interrupted</span> instead of
|
|
<span class="status status-failed">failed</span>, publish a <em>pending</em> Gitea status,
|
|
and are re-enqueued when the server starts again.</li>
|
|
</ul>
|
|
|
|
<h2>v0.9.4 <span class="muted">— 2026-08-10</span></h2>
|
|
<ul>
|
|
<li>The legacy page names (<code>/index.html</code>, <code>/branches.html</code>, …) answer with
|
|
permanent redirects to the new routes, so pre-rewrite bookmarks and the redirect from the
|
|
old host keep working.</li>
|
|
</ul>
|
|
|
|
<h2>v0.9.3 <span class="muted">— 2026-08-10</span></h2>
|
|
<ul>
|
|
<li>The artifact page shows a <span class="status status-failed">n failed</span> badge behind
|
|
links to test reports that contain failures.</li>
|
|
</ul>
|
|
|
|
<h2>v0.9.2 <span class="muted">— 2026-08-10</span></h2>
|
|
<ul>
|
|
<li>Cancelling a build also terminates its auxiliary phases (Docker image build, Gradle cache
|
|
volume preparation), so the next queued build starts immediately.</li>
|
|
</ul>
|
|
|
|
<h2>v0.9.1 <span class="muted">— 2026-08-10</span></h2>
|
|
<ul>
|
|
<li>Durations no longer flicker while live-updating.</li>
|
|
<li>While a build is running or pending, the artifact link shows an hourglass (logs only,
|
|
so far) instead of the report icon.</li>
|
|
<li>Pending builds show their queue wait time in italics; running and finished builds show
|
|
the pure build time without the wait.</li>
|
|
</ul>
|
|
|
|
<h2>v0.9.0 <span class="muted">— 2026-08-10</span></h2>
|
|
<p>Port of the legacy <em>gitTally</em> bash script to Kotlin/Spring Boot — the first production
|
|
deployment of the rewrite.</p>
|
|
<ul>
|
|
<li>Dual-mode application: CLI (<code>init</code>, <code>status</code>, <code>build</code>,
|
|
<code>retry</code>, <code>config:print</code>) and HTTP server with this web UI and a JSON API.</li>
|
|
<li>Declarative YAML configuration: committed <code>.gittally.yml</code> plus machine-specific
|
|
overrides and secrets under <code>.git/gittally/</code>.</li>
|
|
<li>Builds run detached in git worktrees — the primary checkout is never used for builds.</li>
|
|
<li>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.</li>
|
|
<li>Branch watcher with auto-builds (nightly slots), a pull-request gate, and pruning of results,
|
|
artifacts, and stale worktrees.</li>
|
|
<li>Commit statuses reported to Gitea; artifact store with per-branch retention and permanent
|
|
latest-green links; system metrics page.</li>
|
|
<li>Managed nginx/TLS container (Let's Encrypt) for hosts without a reverse proxy;
|
|
<code>init --systemd</code> generates the service unit.</li>
|
|
<li>Self-contained runtime bundle (jlink-trimmed JRE + jar) for hosts without a Java runtime.</li>
|
|
</ul>
|
|
|
|
</div>
|
|
</main>
|
|
<footer th:replace="~{fragments :: footer}"></footer>
|
|
<script src="/werkator.js"></script>
|
|
</body>
|
|
</html>
|