796f2d097d
At the moment we assume that all files except in /.* belong to a package. Now that .shared-patches was moved to device/.shared-patches that does not work correctly anymore. This method should really check to which package the files belong (e.g. walk up directories until it finds an APKBUILD) instead of assuming they are directly in the same directory as the APKBUILD. For now just ignore **/.* (i.e. all files in dot folders), to unblock the MR since it's a critical fix.
148 lines
5.4 KiB
Python
Executable file
148 lines
5.4 KiB
Python
Executable file
#!/usr/bin/env python3
|
|
# Copyright 2020 Oliver Smith
|
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
import glob
|
|
import tempfile
|
|
import sys
|
|
import subprocess
|
|
|
|
# Same dir
|
|
import common
|
|
|
|
# pmbootstrap
|
|
import testcases.add_pmbootstrap_to_import_path # noqa
|
|
import pmb.parse
|
|
import pmb.parse.version
|
|
import pmb.helpers.logging
|
|
|
|
|
|
def get_package_version(args, package, revision, check=True):
|
|
# Redirect stderr to /dev/null, so git doesn't complain about files not
|
|
# existing in master for new packages
|
|
stderr = None
|
|
if not check:
|
|
stderr = subprocess.DEVNULL
|
|
|
|
# Run something like "git show upstream/master:main/hello-world/APKBUILD"
|
|
pmaports_dir = common.get_pmaports_dir()
|
|
pattern = pmaports_dir + "/**/" + package + "/APKBUILD"
|
|
path = glob.glob(pattern, recursive=True)[0][len(pmaports_dir + "/"):]
|
|
apkbuild_content = common.run_git(["show", revision + ":" + path], check,
|
|
stderr)
|
|
if not apkbuild_content:
|
|
return None
|
|
|
|
# Save APKBUILD to a temporary path and parse it from there. (Not the best
|
|
# way to do things, but good enough for this CI script.)
|
|
with tempfile.TemporaryDirectory() as tempdir:
|
|
with open(tempdir + "/APKBUILD", "w", encoding="utf-8") as handle:
|
|
handle.write(apkbuild_content)
|
|
parsed = pmb.parse.apkbuild(args, tempdir + "/APKBUILD", False, False)
|
|
|
|
return parsed["pkgver"] + "-r" + parsed["pkgrel"]
|
|
|
|
|
|
def version_compare_operator(result):
|
|
""" :param result: return value from pmb.parse.version.compare() """
|
|
if result == -1:
|
|
return "<"
|
|
elif result == 0:
|
|
return "=="
|
|
elif result == 1:
|
|
return ">"
|
|
|
|
raise RuntimeError("Unexpected version_compare_operator input: " + result)
|
|
|
|
|
|
def exit_with_error_message():
|
|
print()
|
|
print("ERROR: Modified package(s) don't have an increased version!")
|
|
print()
|
|
print("This can either happen if you did not change the pkgver/pkgrel")
|
|
print("variables in the APKBUILDs. Or you did change them, but the")
|
|
print("packages have been updated in the official master branch, and now")
|
|
print("your versions are not higher anymore.")
|
|
print()
|
|
print("Your options:")
|
|
print("a) If you made changes to the packages, and did not increase the")
|
|
print(" pkgrel/pkgver: increase them now, and force push your branch.")
|
|
print(" => https://postmarketos.org/howto-bump-pkgrel-pkgver")
|
|
print("b) If you had already increased the package versions, rebase on")
|
|
print(" master, increase the versions again and then force push:")
|
|
print(" => https://postmarketos.org/rebase")
|
|
print("c) If you made a change, that does not require rebuilding the")
|
|
print(" packages, such as only changing the arch=... line: you can")
|
|
print(" disable this check by adding '[ci:skip-vercheck]' to the")
|
|
print(" latest commit message, then force push.")
|
|
print()
|
|
print("Thank you and sorry for the inconvenience.")
|
|
exit(1)
|
|
|
|
|
|
def check_versions(args, packages):
|
|
error = False
|
|
|
|
# Get relevant commits: compare HEAD against upstream/master or HEAD~1
|
|
# (the latter if this CI check is running on upstream/master). Note that
|
|
# for the common.get_changed_files() code, we don't check against
|
|
# upstream/master, but against the latest common ancestor. This is not
|
|
# desired here, since we already know what packages changed, and really
|
|
# want to check if the version was increased towards *current* master.
|
|
commit = "upstream/master"
|
|
if common.run_git(["rev-parse", "HEAD"]) == common.run_git(["rev-parse",
|
|
commit]):
|
|
print("NOTE: upstream/master is on same commit as HEAD, comparing"
|
|
" HEAD against HEAD~1.")
|
|
commit = "HEAD~1"
|
|
|
|
for package in packages:
|
|
# Get versions, skip new packages
|
|
head = get_package_version(args, package, "HEAD")
|
|
master = get_package_version(args, package, commit, False)
|
|
if not master:
|
|
print("- {}: {} (HEAD) (new package)".format(package, head))
|
|
continue
|
|
|
|
# Compare head and master versions
|
|
result = pmb.parse.version.compare(head, master)
|
|
if result != 1:
|
|
error = True
|
|
|
|
# Print result line ("- hello-world: 1-r2 (HEAD) > 1-r1 (HEAD~1)")
|
|
formatstr = "- {}: {} (HEAD) {} {} ({})"
|
|
if result != 1:
|
|
formatstr += " [ERROR]"
|
|
operator = version_compare_operator(result)
|
|
print(formatstr.format(package, head, operator, master, commit))
|
|
|
|
if error:
|
|
exit_with_error_message()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
# Get and print modified packages
|
|
common.add_upstream_git_remote()
|
|
packages = common.get_changed_packages()
|
|
print(f"Changed packages: {packages}")
|
|
|
|
# Verify modified package count
|
|
common.get_changed_packages_sanity_check(len(packages))
|
|
if len(packages) == 0:
|
|
print("no aports changed in this branch")
|
|
exit(0)
|
|
|
|
# Potentially skip this check
|
|
if common.commit_message_has_string("[ci:skip-vercheck]"):
|
|
print("WARNING: not checking for changed package versions"
|
|
" ([ci:skip-vercheck])!")
|
|
exit(0)
|
|
|
|
# Initialize args (so we can use pmbootstrap's APKBUILD parsing)
|
|
sys.argv = ["pmbootstrap.py", "chroot"]
|
|
args = pmb.parse.arguments()
|
|
pmb.helpers.logging.init(args)
|
|
|
|
# Verify package versions
|
|
print("checking changed package versions...")
|
|
check_versions(args, packages)
|