[Git][qa/jenkins.debian.net][master] rdn: add regression tracker

Holger Levsen (@holger) gitlab at salsa.debian.org
Thu Oct 8 15:04:56 BST 2026



Holger Levsen pushed to branch master at Debian QA / jenkins.debian.net


Commits:
3ca8b4d0 by Jochen Sprickerhof at 2026-10-08T16:04:49+02:00
rdn: add regression tracker

(cherry picked from commit 455f107c78df194f63b627eb01faa618c99f456f)
Signed-off-by: Holger Levsen <holger at layer-acht.org>

- - - - -


2 changed files:

- + bin/rebuilderd_regressions.py
- hosts/osuosl5-amd64/etc/cron.d/rebuilderd


Changes:

=====================================
bin/rebuilderd_regressions.py
=====================================
@@ -0,0 +1,151 @@
+#!/usr/bin/python3
+#
+# Copyright © 2026 Jochen Sprickerhof <jspricke at debian.org>
+#
+# Licensed under GPL-2
+
+from urllib.request import urlopen
+from yaml import safe_load
+
+
+with urlopen("https://release.debian.org/britney/excuses.yaml") as yaml:
+    excuses = safe_load(yaml)
+
+regressions = []
+regressions_blocked = []
+new_packages = []
+new_packages_blocked = []
+waiting_packages = []
+waiting_packages_blocked = []
+waiting_reference = []
+waiting_reference_blocked = []
+
+for source in excuses["sources"]:
+    if (
+        "block" in source.get("reason", ())
+        or not (policy := source.get("policy_info"))
+        or policy.get("rc-bugs", {}).get("verdict") == "REJECTED_PERMANENTLY"
+        or policy.get("builtonbuildd", {}).get("verdict") == "REJECTED_PERMANENTLY"
+        or policy.get("build-depends", {}).get("verdict") == "REJECTED_PERMANENTLY"
+        or not (reproducible := policy.get("reproducible"))
+        or reproducible["verdict"] in ("PASS", "PASS_HINTED")
+    ):
+        continue
+
+    blocked = "migrate-after" in source.get("dependencies", []) or any(
+        policy[test]["verdict"] != "PASS" for test in policy if test != "reproducible"
+    )
+    package = f'<a href="https://reproduce.debian.net/excuses.html?source_name={source["source"]}">{source["source"]}</a> <a href="https://tracker.debian.org/pkg/{source["source"]}">🍥</a> {policy["age"]["current-age"]} days'
+
+    if "state" not in reproducible:
+        if blocked:
+            waiting_packages_blocked.append(package)
+        else:
+            waiting_packages.append(package)
+        continue
+
+    states = [reproducible["state"][arch] for arch in reproducible["state"]]
+
+    if "unavailable" in states:
+        archs = (
+            arch
+            for arch in reproducible["state"]
+            if reproducible["state"][arch] == "unavailable"
+        )
+        package = package + f" ({' '.join(archs)})"
+        if blocked:
+            waiting_packages_blocked.append(package)
+        else:
+            waiting_packages.append(package)
+        continue
+
+    if "new but not reproducible" in states:
+        if blocked:
+            new_packages_blocked.append(package)
+        else:
+            new_packages.append(package)
+        continue
+
+    if "regression" in states:
+        if blocked:
+            regressions_blocked.append(package)
+        else:
+            regressions.append(package)
+        continue
+
+    if "waiting for reference" in states:
+        archs = (
+            arch
+            for arch in reproducible["state"]
+            if reproducible["state"][arch] == "waiting for reference"
+        )
+        package = package + f" ({' '.join(archs)})"
+        if blocked:
+            waiting_reference_blocked.append(package)
+        else:
+            waiting_reference.append(package)
+        continue
+
+    if miss := source.get("missing-builds"):
+        if set(miss.get("on-architectures")).intersection(
+            {"all", "amd64", "arm64", "armhf", "i386"}
+        ):
+            continue
+
+    print("missed package: ", source["source"])
+    if "verdict" in reproducible:
+        print("  ", reproducible["verdict"])
+    for arch in reproducible["state"]:
+        if reproducible["state"][arch] != "reproducible":
+            print("  ", arch, reproducible["state"][arch])
+
+print(
+    '<!DOCTYPE html><html lang="en"><head>'
+    '<meta charset="utf-8">'
+    "<title>Debian testing migration reproducibility regressions</title>"
+    '<meta name="viewport" content="width=device-width, initial-scale=1">'
+    "</head><body>"
+    '<header><h1>Debian testing migration reproducibility regressions</h1></header> <main>',
+)
+print(f"Last changed: {excuses["generated-date"]} - updated every 3h.")
+
+if regressions:
+    print(f"<h2>{len(regressions)} regressed packages</h2>")
+    print("\n".join(regressions))
+    print()
+
+if new_packages:
+    print(f"<h2>{len(new_packages)} new packages</h2>")
+    print("\n".join(new_packages))
+    print()
+
+if waiting_packages:
+    print(f"<h2>{len(waiting_packages)} waiting packages</h2>")
+    print("\n".join(waiting_packages))
+    print()
+
+if waiting_reference:
+    print(f"<h2>{len(waiting_reference)} waiting for reference run</h2>")
+    print("\n".join(waiting_reference))
+    print()
+
+if regressions_blocked:
+    print(f"<h2>{len(regressions_blocked)} regressed blocked packages</h2>")
+    print("\n".join(regressions_blocked))
+    print()
+
+if new_packages_blocked:
+    print(f"<h2>{len(new_packages_blocked)} new blocked packages</h2>")
+    print("\n".join(new_packages_blocked))
+    print()
+
+if waiting_packages_blocked:
+    print(f"<h2>{len(waiting_packages_blocked)} waiting blocked packages</h2>")
+    print("\n".join(waiting_packages_blocked))
+    print()
+
+if waiting_reference_blocked:
+    print(f"<h2>{len(waiting_reference_blocked)} waiting for reference run and blocked packages</h2>")
+    print("\n".join(waiting_reference_blocked))
+
+print('<br/><br/><hr/><a href="https://salsa.debian.org/qa/jenkins.debian.net/-/blob/master/bin/rebuilderd_regressions.py">rebuilderd_regressions.py<a/> - patches welcome.</main></body></html>')


=====================================
hosts/osuosl5-amd64/etc/cron.d/rebuilderd
=====================================
@@ -1,3 +1,4 @@
 MAILTO=root
 42 */3 * * * rebuilderd for arch in all amd64 arm64 armel armhf i386 loong64 ppc64el riscv64 ; do for release in trixie trixie-proposed-updates trixie-updates trixie-security trixie-backports forky unstable experimental ; do mkdir -p /srv/rebuilderd/$arch/stats/$release && /srv/jenkins/bin/rebuilderd_stats.py $arch /srv/rebuilderd/$arch/rebuilderd.db $release --cache /srv/rebuilderd/$arch/stats/$release/cache.pickle /srv/rebuilderd/$arch/stats/$release ; /srv/jenkins/bin/rebuilderd_graph.sh $arch $release ; done ; done
+25 */3 * * * rebuilderd /srv/jenkins/bin/rebuilderd_regressions.py > /srv/rebuilderd/all/stats/unstable/regressions.html
 



View it on GitLab: https://salsa.debian.org/qa/jenkins.debian.net/-/commit/3ca8b4d09ded0dcc53a39fd6b04f6238ad9e6744

-- 
View it on GitLab: https://salsa.debian.org/qa/jenkins.debian.net/-/commit/3ca8b4d09ded0dcc53a39fd6b04f6238ad9e6744
You're receiving this email because of your account on salsa.debian.org. Manage all notifications: https://salsa.debian.org/-/profile/notifications | Help: https://salsa.debian.org/help


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/qa-jenkins-scm/attachments/20261008/5e23eae3/attachment-0001.htm>


More information about the Qa-jenkins-scm mailing list