continuwuity-bsd/update.py

169 lines
5.6 KiB
Python
Executable file

#!/usr/bin/env python3
"""
This script automates the process of updating the distinfo files for the BSDs
when a new c10y version is released.
We start with FreeBSD, since that defines the package version for all three
based on the upstream distribution version (e.g. c10y release "26.6.0-alpha.1"
becomes package release "26.6.0.a.1") and only FreeBSD has Mk automation which
does this automatically.
All three are then updated in similar fashion: update the package and
distribution versions, then run "make makesum", then add Makefile and distinfo
to Git and push.
A human can then perform any OS-specific customizations, like updating patches
and importing the Cargo vendor config.
The release workflow performs each OS's step on a runner for that specific OS;
running make cross-platform generally has issues even when the Mk files for
each OS are present, and some (OpenBSD in particular) demand to be run as root
within a full ports tree checkout.
The script expects to be run on a pre-existing release branch with the
release.toml file updated to the new version.
"""
import os
import shutil
import contextlib
import re
import tomllib
import subprocess
import sys
import argparse
from git import Repo
@contextlib.contextmanager
def working_dir(d):
cwd = os.getcwd()
os.chdir(d)
try:
yield
finally:
os.chdir(cwd)
def write_job_output(name, value):
with open(os.environ["FORGEJO_OUTPUT"], "a") as f:
f.write(f"{name}={value}\n")
def main():
parser = argparse.ArgumentParser()
parser.add_argument("step")
parser.add_argument("-v", "--version")
args = parser.parse_args()
with open("release.toml", "rb") as f:
config = tomllib.load(f)
if args.step == "version":
version(config, args)
elif args.step == "freebsd":
with working_dir("local/freebsd"):
freebsd(config, args)
elif args.step == "openbsd":
with working_dir("local/openbsd"):
openbsd(config, args)
elif args.step == "netbsd":
with working_dir("local/netbsd"):
netbsd(config, args)
else:
raise Exception(f"Unknown step {args.step}")
def version(config, args):
write_job_output("distversion", config['distversion'])
def freebsd(config, args):
with open("Makefile", "r") as f:
makefile = f.read()
makefile = re.sub("^(DISTVERSION=\\W+).+$", f"\\g<1>%s" % config['distversion'], makefile, flags=re.MULTILINE)
with open("Makefile", "w") as f:
f.write(makefile)
subp = subprocess.run(["make", "-V", "PKGVERSION"], capture_output=True, text=True)
assert subp.returncode == 0
pkgversion = subp.stdout.strip()
print(f"New package version is {pkgversion}")
write_job_output("version", pkgversion)
subp = subprocess.run(["make", "makesum"], capture_output=True, text=True)
print(subp.stdout)
print(subp.stderr)
assert subp.returncode == 0
repo = Repo("..")
repo.index.add("freebsd/Makefile")
repo.index.add("freebsd/distinfo")
commit = repo.index.commit(f"freebsd: update to %s" % config['distversion'])
print(f"Committed {commit.hexsha}")
def openbsd(config, args):
with open("Makefile", "r") as f:
makefile = f.read()
print(f"Updating OpenBSD package to {args.version} (%s)" % config['distversion'])
makefile = re.sub("^(V=\\W+).+$", f"\\g<1>%s" % args.version, makefile, flags=re.MULTILINE)
makefile = re.sub("^(DIST_V=\\W+).+$", f"\\g<1>%s" % config['distversion'], makefile, flags=re.MULTILINE)
with open("Makefile", "w") as f:
f.write(makefile)
shutil.copytree(".", os.path.join(os.environ["PORTSDIR"], "net", "continuwuity"))
with working_dir(os.path.join(os.environ["PORTSDIR"], "net", "continuwuity")):
subp = subprocess.run(["make", "makesum"], capture_output=True, text=True)
print(subp.stdout)
print(subp.stderr)
assert subp.returncode == 0
shutil.copy(os.path.join(os.environ["PORTSDIR"], "net", "continuwuity", "distinfo"), ".")
repo = Repo("..")
repo.index.add("openbsd/Makefile")
repo.index.add("openbsd/distinfo")
commit = repo.index.commit(f"openbsd: update to %s" % config['distversion'])
print(f"Committed {commit.hexsha}")
def netbsd(config, args):
with open("Makefile", "r") as f:
makefile = f.read()
print(f"Updating NetBSD package to {args.version} (%s)" % config['distversion'])
makefile = re.sub("^(V=\\W+).+$", f"\\g<1>%s" % args.version, makefile, flags=re.MULTILINE)
makefile = re.sub("^(DIST_V=\\W+).+$", f"\\g<1>%s" % config['distversion'], makefile, flags=re.MULTILINE)
with open("Makefile", "w") as f:
f.write(makefile)
shutil.copytree(".", os.path.join(os.environ["PORTSDIR"], "net", "continuwuity"))
# idk why this has to run twice, but the first time it removes the files from distinfo
# and then readds them the second time.
# it works correctly if I do everything by hand, so there's probably something obvious.
for i in range(0, 2):
with working_dir(os.path.join(os.environ["PORTSDIR"], "net", "continuwuity")):
subp = subprocess.run(["make", "makesum"], capture_output=True, text=True)
print(subp.stdout)
print(subp.stderr)
assert subp.returncode == 0
shutil.copy(os.path.join(os.environ["PORTSDIR"], "net", "continuwuity", "distinfo"), ".")
repo = Repo("..")
repo.index.add("netbsd/Makefile")
repo.index.add("netbsd/distinfo")
commit = repo.index.commit(f"netbsd: update to %s" % config['distversion'])
print(f"Committed {commit.hexsha}")
if __name__ == "__main__":
main()