sandcastle-ng

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

sandcastle-build-generic (4308B)


      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_output(cmd, shell=False, cwd=None):
     32     """Helper to get command output as string."""
     33     return subprocess.check_output(cmd, shell=shell, cwd=cwd, text=True).strip()
     34 
     35 def get_tag_debver(tag):
     36     """Get a debian version string from a git tag"""
     37     if tag.startswith("v"):
     38         devsuff = "-dev."
     39         d = tag.find(devsuff)
     40         if d < 0:
     41             return tag[1:]
     42         else:
     43             return tag[1:d] + "~dev" + tag[d + len(devsuff)]
     44     if tag.startswith("deb-v"):
     45         tag = tag[5:]
     46         if "-" in tag:
     47             a, b = tag.split("-")
     48             return a + ":" + b
     49         return tag
     50     raise Error("unexpected tag format")
     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     # Prepare Build Directory
     77     if not os.path.exists("/build"):
     78         os.makedirs("/build")
     79     os.chdir("/build")
     80 
     81     with open(f"/buildconfig/{package}.giturl", 'r') as f:
     82         GITURL = f.read().strip()
     83 
     84     run_cmd(["git", "config", "--global", "advice.detachedHead", "false"])
     85     run_cmd(["git", "clone", "--depth=1", f"--branch={tag}", GITURL, package])
     86 
     87     build_pkg_path = os.path.join("/build", package, DEBIANPATH)
     88     os.chdir(build_pkg_path)
     89 
     90     deb_version = get_tag_debver(tag)
     91 
     92     # Bootstrap and Install Deps
     93     os.chdir(os.path.join("/build", package))
     94     run_cmd(["./bootstrap"])
     95 
     96     os.chdir(build_pkg_path)
     97 
     98     # Sparse checkout hint
     99     with open(".version", "w") as f:
    100         f.write(f"{deb_version}\n")
    101 
    102     # Configure Environment for Build
    103     deb_dbg_repo = "debian/.debhelper/"
    104     os.environ["DEB_DBG_SYMBOLS_REPO"] = deb_dbg_repo
    105     os.makedirs(deb_dbg_repo, exist_ok=True)
    106     
    107     open(os.path.join(deb_dbg_repo, "debian-symbols-pool"), 'a').close()
    108     
    109     os.environ["DEB_BUILD_MAINT_OPTIONS"] = "debug"
    110 
    111     debian_date = formatdate(localtime=True)
    112 
    113     changelog = f"""\
    114 {package} ({deb_version}) unstable; urgency=low
    115 
    116   * Release {deb_version} (for sandcastle-ng).
    117 
    118  -- Taler Packaging Team <deb@taler.net>  {debian_date}
    119 """
    120 
    121     with open("debian/changelog", "w") as f:
    122         f.write(changelog)
    123 
    124     # Build Package
    125     run_cmd(["dpkg-buildpackage", "-rfakeroot", "-b", "-uc", "-us"])
    126 
    127     # Copy artifacts
    128     # Globs for ../*.deb and ../*.ddeb relative to current dir
    129     deb_files = glob.glob("../*.deb")
    130     ddeb_files = glob.glob("../*.ddeb")
    131 
    132     outdir = f"/packages/{package}/"
    133 
    134     os.makedirs(outdir, exist_ok=True)
    135 
    136     for f in deb_files:
    137         shutil.copy(f, outdir)
    138     
    139     for f in ddeb_files:
    140         shutil.copy(f, outdir)
    141 
    142     print(f"Installing built packages from {build_pkg_path}/..", file=sys.stderr)
    143     pkgdir_debs = glob.glob(f"{build_pkg_path}/../*.deb")
    144     if pkgdir_debs:
    145         run_cmd(["apt", "install", "-y"] + pkgdir_debs)
    146 
    147 if __name__ == "__main__":
    148     main()