]> git.ipfire.org Git - thirdparty/mkosi.git/commitdiff
Allow MinimumVersion to be a git sha
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Tue, 8 Apr 2025 09:19:34 +0000 (11:19 +0200)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Tue, 8 Apr 2025 10:47:29 +0000 (12:47 +0200)
In systemd we very often require newer mkosi git commits which means
that setting MinimumVersion=25~devel doesn't work anymore. Let's allow
the MinimumVersion= to be a git sha so that we can enforce the mkosi
version to be new enough.

We skip git commit checks if we're in the sandbox since mkosi will be
a zipapp there and we won't have access to the git repository to do the
check.

mkosi/config.py
mkosi/resources/man/mkosi.1.md
tests/test_json.py

index c0613847acdfde7e7db0a310f15a94b13d2d9d4f..15bf568f28a5659eff96a5cb01fb0f08a4993de5 100644 (file)
@@ -1463,22 +1463,33 @@ def config_parse_vsock_cid(value: Optional[str], old: Optional[int]) -> Optional
     return cid
 
 
-def config_parse_minimum_version(
-    value: Optional[str],
-    old: Optional[GenericVersion],
-) -> Optional[GenericVersion]:
+def config_parse_minimum_version(value: Optional[str], old: Optional[str]) -> Optional[str]:
     if not value:
         return old
 
+    if len(value) == 40 and all(c.isalnum() for c in value):
+        if not in_sandbox():
+            gitdir = Path(__file__).parent.parent
+            if not (gitdir / ".git").exists():
+                die("Cannot check mkosi git version, not running from a git repository")
+
+            result = run(["git", "-C", gitdir, "merge-base", "--is-ancestor", value, "HEAD"], check=False)
+            if result.returncode == 1:
+                die(f"mkosi commit {value} or newer is required by this configuration")
+            elif result.returncode != 0:
+                die(f"Failed to check if mkosi git checkout is newer than commit {value}")
+
+        return value
+
     new = GenericVersion(value)
 
     if new > __version__:
         die(f"mkosi {new} or newer is required by this configuration (found {__version__})")
 
     if not old:
-        return new
+        return value
 
-    return max(old, new)
+    return value if new > old else old
 
 
 def file_run_or_read(file: Path) -> str:
@@ -1887,7 +1898,7 @@ class Config:
     profiles: list[str]
     files: list[Path]
     dependencies: list[str]
-    minimum_version: Optional[GenericVersion]
+    minimum_version: Optional[str]
     pass_environment: list[str]
 
     distribution: Distribution
index ad6bfd78b9f7521630d81b9dd1cacfb34667e364..700d2588294439e7e663f58468c8a0b7563eb5e2 100644 (file)
@@ -2166,6 +2166,12 @@ config file is read:
 :   The minimum **mkosi** version required to build this configuration. If
     specified multiple times, the highest specified version is used.
 
+    The minimum version can also be specified as a unabbreviated git
+    commit hash, in which case mkosi must be executed from a git
+    checkout and the specified git commit hash must be an ancestor of
+    the currently checked out git commit in the repository that mkosi is
+    being executed from.
+
 `ConfigureScripts=`, `--configure-script=`
 :   Takes a comma-separated list of paths to executables that are used as
     the configure scripts for this image. See the **Scripts** section for
index 11cd2d7efb67283287e26a291d6b69874bd78cc0..66f5611226c5bc4f9de9e309e2de363fcc558b42 100644 (file)
@@ -43,7 +43,6 @@ from mkosi.config import (
     VsockCID,
 )
 from mkosi.distributions import Distribution
-from mkosi.versioncomp import GenericVersion
 
 
 @pytest.mark.parametrize("path", [None, "/baz/qux"])
@@ -509,7 +508,7 @@ def test_config() -> None:
         manifest_format=[ManifestFormat.json, ManifestFormat.changelog],
         microcode_host=True,
         devicetree=Path("freescale/imx8mm-verdin-nonwifi-dev.dtb"),
-        minimum_version=GenericVersion("123"),
+        minimum_version="123",
         mirror=None,
         nspawn_settings=None,
         openpgp_tool="gpg",