osmith has submitted this change. ( https://gerrit.osmocom.org/c/osmo-ci/+/43678?usp=email )
Change subject: OBS: fix wrong .tarball-version after release ......................................................................
OBS: fix wrong .tarball-version after release
Fix that projects can have a wrong .tarball-version in this scenario: * "Bump version" commit is merged to master. * Osmocom_OBS_master job runs before the tag is pushed.
I have already added logic that ensures debian/changelog stays on the bumped version even if the tag is missing. But the tarball-version would still be wrong in this case (e.g. 1.8.0.6-2b92 instead of 1.9.0), which then leads to wrong pkg-config versions. Packages depending on the one with the wrong version can then fail to build:
Package dependency requirement 'libosmo-ranap >= 1.8.1' could not be satisfied. Package 'libosmo-ranap' has version '1.8.0.6-2b92', required version is '>= 1.8.1'
Fix this by calculating the proper version once beforehand, based on the debian/changelog and git-based versions, and then using it to write the .tarball-version and writing back to debian/changelog if necessary.
Related: OS#6173 Change-Id: I2ae46fa77818bdee0287694cc5de6f9277cd0c91 --- M scripts/obs/lib/debian.py M scripts/obs/lib/srcpkg.py A tests/test_obs_srcpkg.py 3 files changed, 132 insertions(+), 51 deletions(-)
Approvals: pespin: Looks good to me, but someone else must approve laforge: Looks good to me, but someone else must approve fixeria: Looks good to me, approved Jenkins Builder: Verified
diff --git a/scripts/obs/lib/debian.py b/scripts/obs/lib/debian.py index b9e6779..f3b18ec 100644 --- a/scripts/obs/lib/debian.py +++ b/scripts/obs/lib/debian.py @@ -1,20 +1,12 @@ #!/usr/bin/env python3 # SPDX-License-Identifier: GPL-2.0-or-later -# Copyright 2022 sysmocom - s.f.m.c. GmbH info@sysmocom.de +# Copyright 2026 sysmocom - s.f.m.c. GmbH info@sysmocom.de import datetime import os import shlex import lib import lib.git
-# Imports that may not be available during startup, ignore it here and rely on -# lib.check_required_programs() checking this later on (possibly after the -# script executed itself in docker if using --docker). -try: - import packaging.version -except ImportError: - pass -
def control_add_depend(project, pkgname, version): """:param pkgname: of the meta-package to depend on (e.g. osmocom-nightly) @@ -108,27 +100,11 @@ the given version.""" version_changelog = get_last_version_from_changelog(project)
- # Don't use a lower number (OS#6173) - try: - if packaging.version.parse(version_changelog.split("-")[0]) > packaging.version.parse(version.split("-")[0]): - print( - f"{project}: WARNING: version from changelog ({version_changelog}) is higher than version based on git tag ({version})" - ) - if lib.args.version_append: - print(f"{project}: WARNING: assuming commit from last git tag was amended, ignoring...") - else: - print(f"{project}: WARNING: using version from changelog (git tag not pushed yet?)") - return - except packaging.version.InvalidVersion: - # packaging.version.parse can parse the version numbers used in Osmocom - # projects (where we need the above check), but not e.g. some versions - # from wireshark. Don't abort here if that is the case. - pass - # Debian versions must start with a digit version = transform_version(version)
if version_changelog == version: + print(f"{project}: adding debian/changelog entry is unnecessary") return
print(f"{project}: adding debian/changelog entry ({version_changelog} => {version})") diff --git a/scripts/obs/lib/srcpkg.py b/scripts/obs/lib/srcpkg.py index 40c1883..8743939 100644 --- a/scripts/obs/lib/srcpkg.py +++ b/scripts/obs/lib/srcpkg.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # SPDX-License-Identifier: GPL-2.0-or-later -# Copyright 2022 sysmocom - s.f.m.c. GmbH info@sysmocom.de +# Copyright 2026 sysmocom - s.f.m.c. GmbH info@sysmocom.de import glob import os import pathlib @@ -8,6 +8,14 @@ import lib.debian import lib.rpm_spec
+# Imports that may not be available during startup, ignore it here and rely on +# lib.check_required_programs() checking this later on (possibly after the +# script executed itself in docker if using --docker). +try: + import packaging.version +except ImportError: + pass +
def checkout_for_feed(project): """checkout a commit, either latest tag or master or 20YY branch""" @@ -97,14 +105,8 @@ return ret[1:] if ret.startswith("v") else ret
ret = get_git_version(project) - - # Try to get the last version from the debian/changelog if we can't get - # it with git-version-gen, like it was done in the previous OBS scripts if ret == "UNKNOWN": - ret = lib.debian.get_last_version_from_changelog(project) - # cut off epoch, we retrieve it separately in get_epoch() below - if ":" in ret: - ret = ret.split(":")[1] + return None # Caller will use version from debian/changelog instead
# Nightly: add a ".0" after the version if the current commit is on a # version tag, so the next version is higher (OS#6981) @@ -121,21 +123,57 @@ return ret
-def get_epoch(project): - """The osmo-gbproxy used to have the same package version as osmo-sgsn - until 2021 where it was split into its own git repository. From then on, - osmo-gbproxy has a 0.*.* package version, which is smaller than the - previous 1.*.* from osmo-sgsn. We had to set the epoch to 1 for - osmo-gbproxy so package managers know these 0.*.* versions are higher than - the previous 1.*.* ones that are still found in e.g. debian 11. The epoch - is set in debian/changelog, retrieve it from there. - :returns: the epoch number if set, e.g. "1" or an empty string""" +def get_version_epoch(project): + version_append = lib.args.version_append + version = None + epoch = None + + # Start with version and epoch from debian/changelog version_epoch = lib.debian.get_last_version_from_changelog(project) - if ":" in version_epoch: - return version_epoch.split(":")[0] + epoch, version = version_epoch.split(":", 1) + else: + version = version_epoch
- return "" + # Use git-based version if it is higher + version_git = get_version_for_feed(project) + use_git_version = False + if version_git: + use_git_version = True + try: + if packaging.version.parse(version) > packaging.version.parse(version_git.split("-")[0]): + print( + f"{project}: WARNING: version from changelog ({version}) is higher than version based on git tag ({version_git})" + ) + if version_append: + print(f"{project}: WARNING: assuming commit from last git tag was amended, ignoring...") + else: + print(f"{project}: WARNING: using version from changelog (git tag not pushed yet?)") + use_git_version = False + except packaging.version.InvalidVersion: + # packaging.version.parse can parse the version numbers used in + # Osmocom projects (where we need the above check), but not e.g. + # some versions from wireshark. Don't abort here in that case. + print(f"{project}: WARNING: couldn't parse versions (dch: {version}, git: {version_git})") + + else: + print(f"{project}: WARNING: couldn't generate a git-based version") + + if use_git_version: + version = version_git + + if version_append: + version += version_append + + if use_git_version: + print(f"{project}: using git-based version ({version})") + else: + print(f"{project}: using version based on debian/changelog ({version})") + + if epoch: + print(f"{project}: retrieved epoch ({epoch}) from debian/changelog") + + return (version, epoch)
def prepare_project_open5gs(): @@ -179,6 +217,7 @@ def write_tarball_version(project, version): repo_path = lib.git.get_repo_path(project)
+ print(f"{project}: writing .tarball-version: {version}") with open(f"{repo_path}/.tarball-version", "w") as f: f.write(f"{version}\n")
@@ -222,7 +261,6 @@ def build(project, gerrit_id=0): conflict_version = lib.args.conflict_version feed = lib.args.feed - version_append = lib.args.version_append
lib.git.clone(project) lib.git.clean(project) @@ -231,10 +269,7 @@ else: checkout_for_feed(project)
- version = get_version_for_feed(project) - if version_append: - version += version_append - epoch = get_epoch(project) + version, epoch = get_version_epoch(project) version_epoch = f"{epoch}:{version}" if epoch else version
has_rpm_spec = lib.rpm_spec.get_spec_in_path(project) is not None diff --git a/tests/test_obs_srcpkg.py b/tests/test_obs_srcpkg.py new file mode 100644 index 0000000..a1bf357 --- /dev/null +++ b/tests/test_obs_srcpkg.py @@ -0,0 +1,70 @@ +import argparse +import os +import sys + +sys.path.append(os.path.realpath(os.path.dirname(__file__) + "/../scripts/obs")) + +import lib.srcpkg + + +def test_obs_srcpkg_get_version_epoch(monkeypatch): + # Mock args + parser = argparse.ArgumentParser() + parser.add_argument("--version-append") + monkeypatch.setattr(sys, "argv", ["test"]) + monkeypatch.setattr(lib, "args", parser.parse_args()) + + # Mock functions for getting version from debian changelog / git + version_changelog = None + version_for_feed = None + + def get_last_version_from_changelog(project): + return version_changelog + + def get_version_for_feed(project): + return version_for_feed + + monkeypatch.setattr(lib.debian, "get_last_version_from_changelog", get_last_version_from_changelog) + monkeypatch.setattr(lib.srcpkg, "get_version_for_feed", get_version_for_feed) + + # + # Run get_version_epoch() (prints are for "pytest -s") + # + + print("\n*** changelog > git version") + func = lib.srcpkg.get_version_epoch + project = "osmo-iuh" + version_changelog = "1.8.1" + version_for_feed = "1.8.0.6-2b92" + assert ("1.8.1", None) == func(project) + + print("\n*** changelog > git version + epoch in changelog") + project = "osmo-gbproxy" + version_changelog = "1:0.5.2" + version_for_feed = "0.5.1.1-422ff" + assert ("0.5.2", "1") == func(project) + + print("\n*** changelog < git version") + project = "osmo-iuh" + version_changelog = "1.8.0" + version_for_feed = "1.8.0.6-2b92" + assert ("1.8.0.6-2b92", None) == func(project) + + print("\n*** unknown git version") + project = "test" + version_changelog = "1.8.0" + version_for_feed = None + assert ("1.8.0", None) == func(project) + + print("\n*** invalid changelog version") + project = "test" + version_changelog = "some-invalid-version" + version_for_feed = "1.8.0" + assert ("1.8.0", None) == func(project) + + print("\n*** changelog < git version + version append") + project = "test" + version_changelog = "1.0.0" + version_for_feed = "1.0.0.1-c0ff33" + monkeypatch.setattr(lib.args, "version_append", "~test") + assert ("1.0.0.1-c0ff33~test", None) == func(project)