Previously, the build was marked failed in case at least one artifact
was not found after the bitbake returned. However, this is too strict,
as some build commands which are used during development (e.g. clean),
don't generate artifacts by design.
Instead, we now only require the artifacts to be present when also
generating build attestations. This patch updates the specification
(docs), the implementation as well as the test for missing artifacts.
docs/userguide/project-configuration.rst | 5 +++--
kas/attestation.py | 2 +-
kas/config.py | 6 ++++--
kas/plugins/build.py | 6 ++++--
tests/test_build.py | 8 +++++---
5 files changed, 17 insertions(+), 10 deletions(-)
diff --git a/docs/userguide/project-configuration.rst b/docs/userguide/project-configuration.rst
index e4d9ff36c..878f9a17a 100644
--- a/docs/userguide/project-configuration.rst
+++ b/docs/userguide/project-configuration.rst
@@ -446,8 +446,9 @@ Configuration reference
This entry describes artifacts which are expected to be present after
executing the build. Each key-value pair describes an identifier and a
path relative to the kas build dir, whereby the path can contain wildcards
- like '*'. Unix-style globbing is applied to all paths and at least one file
- per entry must match. Otherwise the build is considered to be failed.
+ like '*'. Unix-style globbing is applied to all paths. In case no artifact
+ is found, the build is considered successful, if not stated otherwise by
+ the used plugin and mode of operation.
.. note:: There are no further semantics attached to the identifiers (yet).
Both the author and the consumer of the artifacts node need to
diff --git a/kas/attestation.py b/kas/attestation.py
index d42416b41..dfa5d22a4 100644
--- a/kas/attestation.py
+++ b/kas/attestation.py
@@ -220,7 +220,7 @@ class Statement:
pt = self._predicate.type_()
pp = self._predicate.as_dict()
subjects = []
- for n, s in self._ctx.config.get_artifacts():
+ for n, s in self._ctx.config.get_artifacts(missing_ok=False):
self._check_artifact_timestamp(n, s)
fullpath = Path(self._ctx.build_dir) / s
with open(fullpath, "rb") as f:
diff --git a/kas/config.py b/kas/config.py
index 8281178d7..de50ca9b3 100644
--- a/kas/config.py
+++ b/kas/config.py
@@ -223,16 +223,18 @@ class Config:
multiconfigs.add(target.split(':')[1])
return ' '.join(multiconfigs)
- def get_artifacts(self):
+ def get_artifacts(self, missing_ok=True):
"""
Returns the found artifacts after glob expansion, relative
to the build_dir as a list of tuples (name, path).
+ If missing_ok=False, raises an ArtifactNotFoundError if no
+ artifact for a given name is found.
"""
arts = self._config.get('artifacts', {})
foundfiles = []
for name, art in arts.items():
files = list(Path(self._build_dir).glob(art))
- if len(files) == 0:
+ if not missing_ok and len(files) == 0:
raise ArtifactNotFoundError(name, art)
foundfiles.extend([(name, f) for f in files])
return [(n, f.relative_to(self._build_dir))
diff --git a/kas/plugins/build.py b/kas/plugins/build.py
index b3b9f08cd..f626b5c22 100644
--- a/kas/plugins/build.py
+++ b/kas/plugins/build.py
@@ -30,6 +30,10 @@
provenance attestation for the build. The attestation will be stored in
``attestation/kas-build.provenance.json`` in the build directory.
For details about provenance, see the build attestation chapter.
+
+ .. note::
+ In provenance mode, the command returns with a non-zero exit
+ code in case no artifact is found for at least one entry.
"""
import logging
@@ -147,8 +151,6 @@ class BuildCommand(Command):
run_cmd(cmd, cwd=ctx.build_dir, liveupdate=True)
time_finished = datetime.now()
- artifacts = ctx.config.get_artifacts()
-
if ctx.args.provenance:
mode = Provenance.Mode.MAX if ctx.args.provenance == 'mode=max' \
else Provenance.Mode.MIN
diff --git a/tests/test_build.py b/tests/test_build.py
index 1903103bb..1771a5a6d 100644
--- a/tests/test_build.py
+++ b/tests/test_build.py
@@ -36,9 +36,7 @@ def test_artifact_node(monkeykas, tmpdir):
monkeykas.chdir(tdir)
kas.kas(['build', 'artifact-named.yml'])
kas.kas(['build', 'artifact-glob.yml'])
-
- with pytest.raises(ArtifactNotFoundError):
- kas.kas(['build', 'artifact-invalid.yml'])
+ kas.kas(['build', 'artifact-invalid.yml'])
def test_provenance(monkeykas, tmpdir):
@@ -46,6 +44,10 @@ def test_provenance(monkeykas, tmpdir):
shutil.copytree('tests/test_build', tdir)
monkeykas.chdir(tdir)
+ with pytest.raises(ArtifactNotFoundError):
+ kas.kas(['build', '--provenance', 'mode=min',
+ 'artifact-invalid.yml'])
+
kas.kas(['build', '--provenance', 'mode=min', 'provenance.yml'])
with open('build/attestation/kas-build.provenance.json', 'r') as f:
prov = json.load(f)
--
2.39.2