Files
werkregie/doc/prs/2026-10-14-PR#78-merge-stats.md
claude-code 14f72372cd
werkator build succeeded after 00:56
werkator/deploy build succeeded after 00:24
The merges per day, week and month of the configured authors (#78)
Co-authored-by: claude-code <claude-code@javagil.de>
2026-10-14 19:58:19 +02:00

8.5 KiB

PR#78: The Merges per Day, Week and Month of the Configured Authors

WARNING: This document describes only the change applied in this PR. It may already be outdated once the next PR is merged. Historic PR documentation is not maintained along with new PRs; treat it as a snapshot.

Problem

The human wants to see how many pull requests reach the default branch per day, week and month: those of the human and those of claude-code, on git.javagil.de and on dev.hostsharing.net.

The dashboard reads only the open pull requests and the last 50 activities of the token user; it keeps no history of merges. Gitea has the data: its issue search finds the closed pull requests of an author (created_by), each with merged and merged_at, and the pull request itself names its base branch and the default branch of its repository.

Non-Goals

  • No pull requests of all authors; only the configured ones count.
  • No other measures, e.g. the time from opening to merge.
  • No storage of its own; Gitea holds the history.
  • No merges in the public demo; see Follow-up PRs.

Specification

Feature: the merges per day, week and month of the configured authors

Scenario#78.01: a merge of a configured author counts on its day

… so that the human sees how many pull requests reach the default branch.

  • Given a Gitea with mergeAuthors: [mi, claude-code] and a pull request of claude-code, merged into the default branch today
  • When the human opens the dashboard
  • Then the merge chart of that Gitea counts it today for claude-code
Verified by

Scenario#78.02: the authors stack in each bar

… so that the human sees the share of each author.

  • Given a Gitea with mergeAuthors: [mi, claude-code], and on one day 2 merges of mi and 3 of claude-code
  • When the human opens the dashboard
  • Then the bar of that day stacks 2 for mi on 3 for claude-code, each in its own colour, and the legend names the authors
Verified by

Scenario#78.03: the human switches between days, weeks and months

… so that the human sees the pace over a short and a long time.

  • Given the merge chart, showing the last 30 days
  • When the human selects "Wochen"
  • Then the chart shows the last 12 weeks, from Monday to Sunday, and keeps this choice on the next visit
Verified by

Scenario#78.04: only a merge into the default branch counts

… so that a stacked pull request does not count twice.

  • Given a pull request of a configured author, merged into the branch of another pull request
  • When the human opens the dashboard
  • Then the merge chart does not count it
Verified by

Scenario#78.05: a closed pull request without a merge does not count

… so that the chart counts delivered work only.

  • Given a pull request of a configured author, closed without a merge
  • When the human opens the dashboard
  • Then the merge chart does not count it
Verified by

Scenario#78.06: without mergeAuthors the token user counts

… so that an existing configuration shows the merges of its user without a change.

  • Given a Gitea without mergeAuthors, with the token of hsh-michaelhoennig
  • When the human opens the dashboard
  • Then the merge chart of that Gitea counts the merges of hsh-michaelhoennig
Verified by

Solution

  • GiteaConfig.mergeAuthors: the logins whose merges count; without it the token user, an empty list shows no chart.
  • Each 10 minutes, GiteaSource searches the closed pull requests of each author, updated since the start of the oldest month shown, and keeps those with a merged_at in that range; MergeHistoryTest "a merge before the oldest period does not count, though the pull request was updated later". It runs in a thread of its own, so that the first read after a start does not hold up the open pull requests. For each of them it asks the pull request once whether its base is the default branch of its repository, and keeps the answer, as a merged pull request no longer changes.
  • The snapshot carries the time of each merge in seconds since the epoch; the page counts them by the days, weeks from Monday and months of the browser's time zone. The server would need journal.zone from Main.kt, whose old methods are above a Mutation-CRAP of 15 and would fail the gate of this branch; the human chose the time zone of the browser. The search starts a day before the first of the oldest month in UTC, so that a zone ahead of UTC gets its first day too.
  • The page shows a tile per Gitea next to the review costs: a bar per period, the authors stacked, a switch between 30 days, 12 weeks and 12 months.
  • Each merged pull request is asked once, so the first read after a start costs a request per merge; the search reads at most 20 pages of 50 per author. MergeHistoryTest "the search reads page after page until one is not full" and "each merged pull request is asked once for its base, a failed answer again" verify both.
  • Version 0.49.0.

Manual Check

On 2026-10-14, a local dashboard with mergeAuthors: [mi, claude-code] for git.javagil.de and without mergeAuthors for dev.hostsharing.net counted:

Gitea Author 12 months 30 days
git.javagil.de mi 188 127
git.javagil.de claude-code 247 247
dev.hostsharing.net hsh-michaelhoennig 122 53

The tile showed the bars stacked by author in desktop width, and in phone width in the dark theme; the switch to months stayed after a reload.

Open Questions

  • In which time zone do the days begin? In the browser's; see Solution.

Additional Changes

Follow-up PRs

  • The demo data get merges, so that the public demo shows the chart. Demo.kt stays unchanged: its method snapshot is above a Mutation-CRAP of 15.
  • A test framework for the JavaScript of index.html, e.g. for the counting by day, week and month of mergeSeries. werkregie has none yet; it is a new technology and needs the consent of the human.