sandcastle-build-generic (4548B)
1 #!/usr/bin/env python3 2 # This file is in the public domain. 3 # Helper script to build the latest DEB packages in the container. 4 5 # Supported tag syntax variants: 6 # v$maj.$min$.$patch => release version 7 # v$maj.$min$.$patch-dev.$n => dev version 8 # deb-v$maj.$min$.$patch-$revision => release version with debian revision 9 # Debian revisions of dev versions are *not* supported 10 11 import glob 12 import os 13 import shlex 14 import shutil 15 import subprocess 16 import sys 17 from email.utils import formatdate 18 from logging import log, warning 19 20 21 def run_cmd(cmd, shell=False, cwd=None, env=None): 22 """Helper to run commands and exit on failure (mimicking set -e).""" 23 # If specific env vars are passed, update the current env, otherwise use current 24 command_env = os.environ.copy() 25 if env: 26 command_env.update(env) 27 28 # Flush stdout so logs appear in order 29 sys.stdout.flush() 30 31 subprocess.check_call(cmd, shell=shell, cwd=cwd, env=command_env) 32 33 34 def get_tag_debver(tag): 35 """Get a debian version string from a git tag""" 36 if tag.startswith("v"): 37 devsuff = "-dev." 38 d = tag.find(devsuff) 39 if d < 0: 40 return tag[1:] 41 else: 42 return tag[1:d] + "~dev" + tag[d + len(devsuff)] 43 if tag.startswith("deb-v"): 44 tag = tag[5:] 45 if "-" in tag: 46 a, b = tag.split("-") 47 return a + ":" + b 48 return tag 49 warning(f"unexpected tag format: {tag}") 50 return "100.0.0" # Version big enough to work every time 51 52 53 def main(): 54 if "LD_LIBRARY_PATH" in os.environ: 55 del os.environ["LD_LIBRARY_PATH"] 56 57 # Arguments 58 if len(sys.argv) < 2: 59 print(f"Usage: {sys.argv[0]} <PACKAGE>", file=sys.stderr) 60 sys.exit(1) 61 62 package = sys.argv[1] 63 64 # Path of the debian/ folder in the repository 65 DEBIANPATH = "" 66 debpath_file = f"/buildconfig/{package}.debpath" 67 if os.path.exists(debpath_file): 68 with open(debpath_file, "r") as f: 69 DEBIANPATH = f.read().strip() 70 71 print(f"Building {package} with generic build logic", file=sys.stderr) 72 73 with open(f"/buildconfig/{package}.tag", "r") as f: 74 tag = f.read().strip() 75 76 outdir = f"/packages/{package}/" 77 78 os.makedirs(outdir, exist_ok=True) 79 80 os.chdir("/packages/") 81 82 # Using shell=True here to easily handle the pipe logic 83 run_cmd("dpkg-scanpackages . | xz - > /packages/Packages.xz", shell=True) 84 85 with open("/etc/apt/sources.list.d/taler-packaging-local.list", "w") as f: 86 f.write("deb [trusted=yes] file:/packages ./\n") 87 88 run_cmd(["apt-get", "update"]) 89 90 # Prepare Build Directory 91 if not os.path.exists("/build"): 92 os.makedirs("/build") 93 os.chdir("/build") 94 95 with open(f"/buildconfig/{package}.giturl", "r") as f: 96 GITURL = f.read().strip() 97 98 run_cmd(["git", "config", "--global", "advice.detachedHead", "false"]) 99 run_cmd(["git", "clone", "--depth=1", f"--branch={tag}", GITURL, package]) 100 101 build_pkg_path = os.path.join("/build", package, DEBIANPATH) 102 os.chdir(build_pkg_path) 103 104 deb_version = get_tag_debver(tag) 105 106 # Bootstrap and Install Deps 107 os.chdir(os.path.join("/build", package)) 108 run_cmd(["./bootstrap"]) 109 110 os.chdir(build_pkg_path) 111 112 # Install build-time dependencies 113 tool_cmd = "apt-get -o Debug::pkgProblemResolver=yes --no-install-recommends --yes" 114 run_cmd(["mk-build-deps", "--install", f"--tool={tool_cmd}", "debian/control"]) 115 116 # Sparse checkout hint 117 with open(".version", "w") as f: 118 f.write(f"{deb_version}\n") 119 120 # Configure Environment for Build 121 deb_dbg_repo = "debian/.debhelper/" 122 os.environ["DEB_DBG_SYMBOLS_REPO"] = deb_dbg_repo 123 os.makedirs(deb_dbg_repo, exist_ok=True) 124 125 open(os.path.join(deb_dbg_repo, "debian-symbols-pool"), "a").close() 126 127 os.environ["DEB_BUILD_MAINT_OPTIONS"] = "debug" 128 129 debian_date = formatdate(localtime=True) 130 131 changelog = f"""\ 132 {package} ({deb_version}) unstable; urgency=low 133 134 * Release {deb_version} (for sandcastle-ng). 135 136 -- Taler Packaging Team <deb@taler.net> {debian_date} 137 """ 138 139 with open("debian/changelog", "w") as f: 140 f.write(changelog) 141 142 # Build Package 143 run_cmd(["dpkg-buildpackage", "-rfakeroot", "-b", "-uc", "-us"]) 144 145 # Copy artifacts 146 # Globs for ../*.deb and ../*.ddeb relative to current dir 147 deb_files = glob.glob("../*.deb") 148 ddeb_files = glob.glob("../*.ddeb") 149 150 for f in deb_files: 151 shutil.copy(f, outdir) 152 153 for f in ddeb_files: 154 shutil.copy(f, outdir) 155 156 157 if __name__ == "__main__": 158 main()