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