krz/hutch-stats

Server-side utility for calculating contributions for sourcehut users.

clone: git clone https://gitbay.org/krz/hutch-stats.git

ef33a663928825f0c5b51d31c5e3f376ac0bf1b0

verified · cmc

author: Christian Cleberg <hello@cleberg.net> · 2026-08-22T20:02:18Z

Run the tests in CI

The service had no workflows: 46 tests that ran only when someone remembered.
Six dependency bumps were merged in one sitting with nothing verifying them.

Installs with uv, since uv.lock is committed and is what dependabot updates, so
CI has to resolve through it rather than pip-installing whatever is newest.

--locked rather than --frozen: --frozen installs from the lockfile without
consulting pyproject.toml, so a manifest that has drifted past its lock installs
happily and CI stays green. --locked fails instead. Checked both ways against a
deliberately drifted constraint before picking.
 .github/workflows/test.yml | 35 +++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
new file mode 100644
index 0000000..cd33053
--- /dev/null
+++ b/.github/workflows/test.yml
@@ -0,0 +1,35 @@
+name: Test
+
+# This service had no CI at all: 46 tests under tests/ that ran only when
+# someone remembered to. Six dependency bumps were merged in one sitting with
+# nothing verifying them, which is the failure this exists to prevent.
+on:
+  pull_request:
+  push:
+    branches: [main]
+
+permissions:
+  contents: read
+
+jobs:
+  test:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v7
+
+      # uv is how the project is actually developed — uv.lock is committed and
+      # is what dependabot updates, so CI must resolve through it rather than
+      # pip-installing whatever is newest.
+      - uses: astral-sh/setup-uv@v10
+        with:
+          enable-cache: true
+
+      # --locked, not --frozen. --frozen installs from the lockfile without
+      # looking at pyproject.toml, so a manifest that has drifted past its lock
+      # installs happily; --locked fails instead. Verified both ways against a
+      # deliberately drifted constraint.
+      - name: Install
+        run: uv sync --extra dev --locked
+
+      - name: Tests
+        run: uv run pytest -q