sandcastle-ng

Scripts for the deployment of Sandcastle (GNU Taler)
Log | Files | Refs | README

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()