import yaml import subprocess import os import shutil import glob import sys import time LOCAL_REPO = "/tmp/pkgout" def repo_init(): os.makedirs(LOCAL_REPO, exist_ok=True) conf_path = "/etc/pacman.conf" with open(conf_path) as f: conf = f.read() # Insert before first active repo ([system] for Artix, [core] for Arch) for tag in ("[system]", "[core]"): if tag in conf: sep = tag break else: sep = "[options]" if "[euri-local]" not in conf: with open(conf_path, "w") as f: f.write(conf.replace( sep, "[euri-local]\nSigLevel = Never\nServer = file:///tmp/pkgout\n\n" + sep )) # Create empty repo db so pacman doesn't choke db = f"{LOCAL_REPO}/euri-local.db.tar.gz" if not os.path.exists(db): subprocess.run(["bsdtar", "-czf", db, "-T", "/dev/null"]) def repo_add(pkg_path): db = f"{LOCAL_REPO}/euri-local.db.tar.gz" subprocess.run(["repo-add", db, pkg_path], capture_output=True) def repo_has(pkgname): db = f"{LOCAL_REPO}/euri-local.db.tar.gz" if not os.path.exists(db): return False result = subprocess.run( ["bsdtar", "-tf", db], capture_output=True, text=True ) return pkgname in result.stdout with open("packages.yaml") as f: pkgs = yaml.safe_load(f)["packages"] repo_init() for pkg in pkgs: local_pkgbuild = f"packages/{pkg}/PKGBUILD" build_dir = f"/tmp/build-{pkg}" if os.path.exists(build_dir): shutil.rmtree(build_dir) if os.path.exists(local_pkgbuild): shutil.copytree(f"packages/{pkg}", build_dir) else: url = f"https://aur.archlinux.org/{pkg}.git" for attempt in range(3): r = subprocess.run(["git", "clone", url, build_dir], capture_output=True) if r.returncode == 0: break print(f"AUR clone attempt {attempt+1}/3 failed for {pkg}, retrying...") try: shutil.rmtree(build_dir) except FileNotFoundError: pass time.sleep(2) else: print(f"::error::FAILED to clone AUR package: {pkg}") sys.exit(1) subprocess.run(["chown", "-R", "builder:builder", build_dir]) # Sync pacman so makepkg -s can resolve local packages subprocess.run(["pacman", "-Sy", "--noconfirm"], capture_output=True) result = subprocess.run( ["su", "-", "builder", "-c", f"cd {build_dir} && makepkg -s --noconfirm --noprogress --skippgpcheck --skipinteg"], capture_output=True, text=True ) if result.returncode != 0: print(f"::error::BUILD FAILED: {pkg}") print(result.stdout[-500:]) print(result.stderr[-500:]) sys.exit(1) for pkg_file in glob.glob(f"{build_dir}/*.pkg.tar.zst"): shutil.copy(pkg_file, LOCAL_REPO) repo_add(pkg_file) print("Done!")