taler-deployment

Deployment scripts and configuration files
Log | Files | Refs | README

commit a0319889d1fe79e87ca8d60c1972f787bc3206fa
parent 099201ce8813f17b8cce839a82202ef3a8d0daf5
Author: Florian Dold <dold@taler.net>
Date:   Tue,  8 Sep 2026 22:11:39 +0200

buildbot: cache full checkouts for Debian publishers

Retain complete Git history and release tags for all thirteen Debian
publishers so package versions can use the highest SemVer tag. Replace
previous shallow workspaces once before retaining the full checkout.

Diffstat:
Mbuildbot/master.cfg | 8++++++--
Mbuildbot/test_container_steps.py | 72++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 78 insertions(+), 2 deletions(-)

diff --git a/buildbot/master.cfg b/buildbot/master.cfg @@ -1081,7 +1081,11 @@ for repo in container_repos: # Factory-wide variables REPO_NAME = repo.rsplit('/', 1)[1] REPO_URL = "git://" + repo + ".git" - CACHE_CHECKOUT = REPO_NAME in ("donau", "taler-typescript-core") + CACHE_CHECKOUT = REPO_NAME in ( + "gnunet", "exchange", "merchant", "donau", "challenger", "anastasis", + "sync", "libeufin", "taler-rust", "depolymerization", "taler-mailbox", + "taldir", "taler-typescript-core", + ) CONTAINER_WORKDIR = f"/home/container-worker/workspace/{REPO_NAME}" CI_JOBS_PATH = f"{CONTAINER_WORKDIR}/contrib/ci/jobs" @@ -1113,7 +1117,7 @@ for repo in container_repos: )) # "fresh" cleans build outputs but retains Git history between builds. - # Donau and TypeScript build versions require full history and release tags. + # Debian package versions require full history and all release tags. # Other container builders use a new depth-1 clone on every build. # Will checkout value of "branch" property from job properties. # https://docs.buildbot.net/latest/manual/configuration/steps/source_git.html diff --git a/buildbot/test_container_steps.py b/buildbot/test_container_steps.py @@ -105,3 +105,75 @@ class ContainerStepTests(unittest.TestCase): self.assertEqual(self.run_sequence( step, [results.SUCCESS, results.SUCCESS]), (results.SUCCESS, results.SUCCESS, False)) + + +class ContainerCheckoutTests(unittest.TestCase): + def checkout(self, repo): + # Evaluate the actual factory prefix, without registering schedulers or + # workers. Keep real Buildbot steps so their checkout options are checked. + loop = next(node for node in config_ast.body + if isinstance(node, ast.For) + and isinstance(node.iter, ast.Name) + and node.iter.id == "container_repos") + prefix = [] + for node in loop.body: + if (isinstance(node, ast.Expr) and isinstance(node.value, ast.Call) + and node.value.args and isinstance(node.value.args[0], ast.Call) + and isinstance(node.value.args[0].func, ast.Name) + and node.value.args[0].func.id == "GenerateStagesCommand"): + break + prefix.append(node) + scope = {"repo": "git.taler.net/" + repo, "util": util, + "ShellCommand": steps.ShellCommand, "Git": steps.Git} + exec(compile(ast.Module(body=prefix, type_ignores=[]), + str(config_path), "exec"), scope) + factory = scope["container_factory"] + return (scope["CONTAINER_WORKDIR"], + [step.buildStep() for step in factory.steps]) + + def test_debian_publishers_cache_full_history_and_tags(self): + publishers = ("gnunet", "exchange", "merchant", "donau", "challenger", + "anastasis", "sync", "libeufin", "taler-rust", + "depolymerization", "taler-mailbox", "taldir", + "taler-typescript-core") + for repo in publishers: + with self.subTest(repo=repo): + _, (_, checkout) = self.checkout(repo) + self.assertEqual(checkout.mode, "full") + self.assertEqual(checkout.method, "fresh") + self.assertFalse(checkout.shallow) + self.assertTrue(checkout.tags) + self.assertTrue(checkout.submodules) + _, (_, android) = self.checkout("taler-android") + self.assertEqual(android.method, "clobber") + self.assertTrue(android.shallow) + + def test_workspace_migrates_shallow_checkout_once(self): + import os + import subprocess + import tempfile + + original, (workspace, _) = self.checkout("gnunet") + with tempfile.TemporaryDirectory() as temp: + root = Path(temp) + checkout = root / "checkout" + bindir = root / "bin" + bindir.mkdir() + # Skip only the container chmod. Exercise the actual removal and + # recreation commands against a disposable checkout directory. + podman = bindir / "podman" + podman.write_text("#!/bin/sh\nexit 0\n") + podman.chmod(0o755) + env = dict(os.environ, PATH=f"{bindir}:{os.environ['PATH']}") + command = workspace.command.replace(original, str(checkout)) + (checkout / ".git").mkdir(parents=True) + (checkout / ".git/shallow").touch() + marker = checkout / "old-checkout" + marker.touch() + subprocess.run(["sh", "-ec", command], check=True, env=env) + self.assertTrue(checkout.is_dir()) + self.assertFalse(marker.exists()) + (checkout / ".git").mkdir() + marker.touch() + subprocess.run(["sh", "-ec", command], check=True, env=env) + self.assertTrue(marker.exists())