← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] ~ruinedyourlife/launchpad:craft-builds-launchpad-channel into launchpad:master

 

RuinedYourLife has proposed merging ~ruinedyourlife/launchpad:craft-builds-launchpad-channel into launchpad:master.

Commit message:
Launchpad channel artifactory property

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~ruinedyourlife/launchpad/+git/launchpad/+merge/491704
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of ~ruinedyourlife/launchpad:craft-builds-launchpad-channel into launchpad:master.
diff --git a/lib/lp/crafts/model/craftrecipebuildjob.py b/lib/lp/crafts/model/craftrecipebuildjob.py
index dc92ad2..81b4912 100644
--- a/lib/lp/crafts/model/craftrecipebuildjob.py
+++ b/lib/lp/crafts/model/craftrecipebuildjob.py
@@ -691,6 +691,11 @@ class CraftPublishingJob(CraftRecipeBuildJobDerived):
         new_properties["soss.source_url"] = [self._recipe_git_url()]
         new_properties["soss.type"] = ["source"]
         new_properties["soss.license"] = [self._get_license_metadata()]
+        version_str = self._get_version_metadata()
+        channel_value = (
+            f"{version_str}/stable" if version_str else "unknown/stable"
+        )
+        new_properties["launchpad.channel"] = [channel_value]
 
         # Repo name is derived from the URL
         # refer to schema-lazr.conf for more details about the URL structure
@@ -781,31 +786,46 @@ class CraftPublishingJob(CraftRecipeBuildJobDerived):
             )
             return "unknown"
 
-    def _get_license_metadata(self) -> str:
-        """Get the license metadata from the build files."""
+    def _get_artifact_metadata(self) -> dict:
+        """Load and cache metadata from metadata.yaml if present.
+
+        Returns an empty dict when metadata is missing or cannot be parsed.
+        """
+        if hasattr(self, "_artifact_metadata"):
+            return self._artifact_metadata
+
         for _, lfa, _ in self.build.getFiles():
             if lfa.filename == "metadata.yaml":
                 lfa.open()
                 try:
                     content = lfa.read().decode("utf-8")
-                    metadata = yaml.safe_load(content)
-
-                    if "license" not in metadata:
-                        log.info(
-                            "No license found in metadata.yaml, returning \
-                            'unknown'."
-                        )
-                        return "unknown"
-
-                    return metadata.get("license")
-
+                    metadata = yaml.safe_load(content) or {}
+                    self._artifact_metadata = metadata
+                    return self._artifact_metadata
                 except yaml.YAMLError as e:
                     self.error_message = f"Failed to parse metadata.yaml: {e}"
-
                     log.info(self.error_message)
-                    return "unknown"
+                    self._artifact_metadata = {}
+                    return self._artifact_metadata
                 finally:
                     lfa.close()
 
         log.info("No metadata.yaml file found in the build files.")
-        return "unknown"
+        self._artifact_metadata = {}
+        return self._artifact_metadata
+
+    def _get_license_metadata(self) -> str:
+        """Get the license metadata from the cached metadata."""
+        metadata = self._get_artifact_metadata()
+        if "license" not in metadata:
+            log.info("No license found in metadata.yaml, returning 'unknown'.")
+            return "unknown"
+        return metadata.get("license")
+
+    def _get_version_metadata(self) -> str:
+        """Get the version metadata from the cached metadata."""
+        metadata = self._get_artifact_metadata()
+        if "version" not in metadata:
+            log.info("No version found in metadata.yaml, returning 'unknown'.")
+            return "unknown"
+        return str(metadata.get("version"))
diff --git a/lib/lp/crafts/tests/test_craftrecipebuildjob.py b/lib/lp/crafts/tests/test_craftrecipebuildjob.py
index e7a4fc4..ac3c5ef 100644
--- a/lib/lp/crafts/tests/test_craftrecipebuildjob.py
+++ b/lib/lp/crafts/tests/test_craftrecipebuildjob.py
@@ -421,7 +421,7 @@ class TestCraftPublishingJob(TestCaseWithFactory):
 
         # Add a metadata file with license information
         license_value = "Apache-2.0"
-        metadata_yaml = f"license: {license_value}\n"
+        metadata_yaml = f"license: {license_value}\nversion: 0.1.0\n"
         librarian = getUtility(ILibraryFileAliasSet)
         metadata_lfa = librarian.create(
             "metadata.yaml",
@@ -540,6 +540,9 @@ class TestCraftPublishingJob(TestCaseWithFactory):
         )
         self.assertEqual(artifact["properties"]["soss.type"], "source")
         self.assertEqual(artifact["properties"]["soss.license"], license_value)
+        self.assertEqual(
+            artifact["properties"].get("launchpad.channel"), "0.1.0/stable"
+        )
 
     def test_run_missing_maven_config(self):
         """
@@ -625,7 +628,7 @@ class TestCraftPublishingJob(TestCaseWithFactory):
 
         # Create a metadata file with license information
         license_value = "Apache-2.0"
-        metadata_yaml = f"license: {license_value}\n"
+        metadata_yaml = f"license: {license_value}\nversion: 0.1.0\n"
         librarian = getUtility(ILibraryFileAliasSet)
         metadata_lfa = librarian.create(
             "metadata.yaml",
@@ -762,6 +765,9 @@ class TestCraftPublishingJob(TestCaseWithFactory):
         )
         self.assertEqual(artifact["properties"]["soss.type"], "source")
         self.assertEqual(artifact["properties"]["soss.license"], license_value)
+        self.assertEqual(
+            artifact["properties"].get("launchpad.channel"), "0.1.0/stable"
+        )
 
     def test__publish_properties_sets_expected_properties(self):
         """Test that _publish_properties sets the correct properties in
@@ -805,6 +811,8 @@ class TestCraftPublishingJob(TestCaseWithFactory):
         )
         self.assertEqual(props["soss.type"], "source")
         self.assertEqual(props["soss.license"], "MIT")
+        self.assertIn("launchpad.channel", props)
+        self.assertEqual(props["launchpad.channel"], "unknown/stable")
 
     def test__publish_properties_artifact_not_found(self):
         """Test that _publish_properties raises NotFoundError if artifact is
@@ -848,6 +856,9 @@ class TestCraftPublishingJob(TestCaseWithFactory):
 
         artifact = self._artifactory_search("repository", "artifact.file")
         self.assertEqual(artifact["properties"]["soss.license"], "unknown")
+        self.assertEqual(
+            artifact["properties"].get("launchpad.channel"), "unknown/stable"
+        )
 
     def test__publish_properties_no_license_in_metadata_yaml(self):
         """Test that _publish_properties sets license to 'unknown' if no
@@ -887,6 +898,9 @@ class TestCraftPublishingJob(TestCaseWithFactory):
 
         artifact = self._artifactory_search("repository", "artifact.file")
         self.assertEqual(artifact["properties"]["soss.license"], "unknown")
+        self.assertEqual(
+            artifact["properties"].get("launchpad.channel"), "unknown/stable"
+        )
 
     def test__publish_properties_license_from_metadata_yaml(self):
         """Test that _publish_properties gets license from metadata.yaml
@@ -894,7 +908,7 @@ class TestCraftPublishingJob(TestCaseWithFactory):
 
         # Create a metadata.yaml file with a license
         license_value = "Apache-2.0"
-        metadata_yaml = f"license: {license_value}\n"
+        metadata_yaml = f"license: {license_value}\nversion: 0.1.0\n"
         librarian = getUtility(ILibraryFileAliasSet)
         metadata_lfa = librarian.create(
             "metadata.yaml",
@@ -927,6 +941,9 @@ class TestCraftPublishingJob(TestCaseWithFactory):
 
         artifact = self._artifactory_search("repository", "artifact.file")
         self.assertEqual(artifact["properties"]["soss.license"], license_value)
+        self.assertEqual(
+            artifact["properties"].get("launchpad.channel"), "0.1.0/stable"
+        )
 
     def test__publish_properties_git_repository_source_url(self):
         """Test that _publish_properties gets git_repository as source_url."""