launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #32586
[Merge] ~ruinedyourlife/launchpad:maven-and-cargo-proxies into launchpad:master
Quentin Debhi has proposed merging ~ruinedyourlife/launchpad:maven-and-cargo-proxies into launchpad:master.
Commit message:
Add proxy configuration for maven and cargo
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~ruinedyourlife/launchpad/+git/launchpad/+merge/486656
This brings proxy settings for maven and cargo, so they can publish to artifactory.
The tests have also been refactored to be less cumbersome, as well as an additional test function for the proxy settings.
I also removed the native publisher cron jobs from the MAIN group, so it does not collide with the scripts unit.
--
Your team Launchpad code reviewers is requested to review the proposed merge of ~ruinedyourlife/launchpad:maven-and-cargo-proxies into launchpad:master.
diff --git a/lib/lp/crafts/model/craftrecipebuildjob.py b/lib/lp/crafts/model/craftrecipebuildjob.py
index 58aa740..296ebf5 100644
--- a/lib/lp/crafts/model/craftrecipebuildjob.py
+++ b/lib/lp/crafts/model/craftrecipebuildjob.py
@@ -9,6 +9,7 @@ __all__ = [
"CraftRecipeBuildJobType",
]
+import glob
import json
import os
import subprocess
@@ -216,6 +217,12 @@ class CraftPublishingJob(CraftRecipeBuildJobDerived):
)
raise Exception(self.error_message)
+ # Check if HTTP proxy is configured - skip publishing if not
+ if not config.launchpad.http_proxy:
+ raise Exception(
+ "Skipping artifact publishing: No HTTP proxy configured"
+ )
+
# Check if we have a .crate file or .jar file
crate_file = None
jar_file = None
@@ -336,6 +343,7 @@ class CraftPublishingJob(CraftRecipeBuildJobDerived):
# Extract token from auth string (discard username if present)
if ":" in cargo_publish_auth:
_, token = cargo_publish_auth.split(":", 1)
+ token = token.strip('"')
else:
token = cargo_publish_auth
@@ -352,6 +360,11 @@ class CraftPublishingJob(CraftRecipeBuildJobDerived):
"\n"
"[registries.launchpad]\n"
f'index = "{cargo_publish_url}"\n'
+ "\n"
+ "[http]\n"
+ f"proxy = '{config.launchpad.http_proxy}'\n"
+ "timeout = 60\n"
+ "multiplexing = false\n"
)
# Create credentials.toml
@@ -360,6 +373,12 @@ class CraftPublishingJob(CraftRecipeBuildJobDerived):
"\n" "[registries.launchpad]\n" f'token = "Bearer {token}"\n'
)
+ orig_files = glob.glob(
+ f"{extract_dir}/**/Cargo.toml.orig", recursive=True
+ )
+ for file in orig_files:
+ os.remove(file)
+
# Run cargo publish from the extracted directory
result = subprocess.run(
[
@@ -451,6 +470,24 @@ class CraftPublishingJob(CraftRecipeBuildJobDerived):
:param password: Maven repository password
:return: XML content as string
"""
+ # Get proxy settings from config
+ proxy_url = config.launchpad.http_proxy
+ proxy_host = None
+ proxy_port = None
+
+ if proxy_url:
+ # Parse the proxy URL to extract host and port
+ # Example: http://localhost:8080 -> host=localhost, port=8080
+ proxy_parts = (
+ proxy_url.replace("http://", "")
+ .replace("https://", "")
+ .split(":")
+ )
+ if len(proxy_parts) >= 1:
+ proxy_host = proxy_parts[0]
+ if len(proxy_parts) >= 2:
+ proxy_port = proxy_parts[1].split("/")[0] # Remove any path
+
# Break it into smaller parts to avoid long lines
header = (
'<?xml version="1.0" encoding="UTF-8"?>\n'
@@ -474,6 +511,21 @@ class CraftPublishingJob(CraftRecipeBuildJobDerived):
" </servers>\n"
)
+ # Add proxy configuration if proxy is configured
+ proxies = ""
+ if proxy_host and proxy_port:
+ proxies = (
+ " <proxies>\n"
+ " <proxy>\n"
+ " <id>launchpad-proxy</id>\n"
+ " <active>true</active>\n"
+ " <protocol>http</protocol>\n"
+ f" <host>{proxy_host}</host>\n"
+ f" <port>{proxy_port}</port>\n"
+ " </proxy>\n"
+ " </proxies>\n"
+ )
+
profiles = (
" <profiles>\n"
" <profile>\n"
@@ -496,7 +548,7 @@ class CraftPublishingJob(CraftRecipeBuildJobDerived):
)
# Combine all parts
- return header + schema + servers + profiles + active_profiles
+ return header + schema + servers + proxies + profiles + active_profiles
def _publish_properties(
self, publish_url: str, artifact_name: str
diff --git a/lib/lp/crafts/subscribers/craftrecipebuild.py b/lib/lp/crafts/subscribers/craftrecipebuild.py
index 5437c55..8cc06ac 100644
--- a/lib/lp/crafts/subscribers/craftrecipebuild.py
+++ b/lib/lp/crafts/subscribers/craftrecipebuild.py
@@ -55,6 +55,10 @@ def craft_build_status_changed(build, event):
)
try:
# Check if there are any config variables for this distribution
+ # XXX ruinedyourlife 2025-06-05: For now, we publish only using
+ # our craftbuild configuration, so only to one place.
+ # We could use the store_name property of the recipe to
+ # determine where to publish, when we have other destinations.
config["craftbuild." + distribution_name]
should_publish = True
except NoSectionError:
diff --git a/lib/lp/crafts/tests/test_craftrecipebuildjob.py b/lib/lp/crafts/tests/test_craftrecipebuildjob.py
index 3fe42ab..6e5c8d0 100644
--- a/lib/lp/crafts/tests/test_craftrecipebuildjob.py
+++ b/lib/lp/crafts/tests/test_craftrecipebuildjob.py
@@ -90,6 +90,136 @@ class TestCraftPublishingJob(TestCaseWithFactory):
FakeArtifactoryFixture(self.base_url, self.repository_name)
)
+ def run_job(self, job):
+ """Helper to run a job and return the result."""
+ job = getUtility(ICraftPublishingJobSource).create(self.build)
+ JobRunner([job]).runAll()
+ job = removeSecurityProxy(job)
+ return job
+
+ def _setup_distribution(self, distribution_name="soss"):
+ """Helper to setup a distribution and its source package."""
+ distribution = self.factory.makeDistribution(name=distribution_name)
+ package = self.factory.makeDistributionSourcePackage(
+ distribution=distribution
+ )
+ git_repository = self.factory.makeGitRepository(target=package)
+ removeSecurityProxy(self.recipe).git_repository = git_repository
+
+ def _setup_config(self, with_env_vars=False, with_http_proxy=False):
+ """Helper to setup a config with the given values."""
+ distribution_name = "soss"
+
+ # Push config with or without env vars
+ if not with_env_vars:
+ # Just push the distribution section without env vars
+ self.pushConfig(f"craftbuild.{distribution_name}")
+ else:
+ # Push with standard environment variables
+ env_vars = {
+ "CARGO_PUBLISH_URL": f"{self.base_url}/repository",
+ "CARGO_PUBLISH_AUTH": "lp:token123",
+ "MAVEN_PUBLISH_URL": f"{self.base_url}/repository",
+ "MAVEN_PUBLISH_AUTH": "lp:token123",
+ }
+ self.pushConfig(
+ f"craftbuild.{distribution_name}",
+ environment_variables=json.dumps(env_vars),
+ )
+
+ if with_http_proxy:
+ self.pushConfig("launchpad", http_proxy="http://localhost:8080")
+
+ def _create_crate_file(self, crate_name="test-0.1.0"):
+ """Helper to create a crate file."""
+ # Create a BytesIO object to hold the tar data
+ tar_data = io.BytesIO()
+
+ # Create a tar archive
+ with tarfile.open(fileobj=tar_data, mode="w") as tar:
+ # Create a directory entry for the crate
+ crate_dir_info = tarfile.TarInfo(crate_name)
+ crate_dir_info.type = tarfile.DIRTYPE
+ crate_dir_info.mode = 0o755
+ tar.addfile(crate_dir_info)
+
+ # Add a Cargo.toml file
+ cargo_toml = (
+ "[package]\n"
+ 'name = "test"\n'
+ 'version = "0.1.0"\n'
+ 'authors = ["Test <test@xxxxxxxxxxx>"]\n'
+ 'edition = "2025"\n'
+ )
+ cargo_toml_info = tarfile.TarInfo(f"{crate_name}/Cargo.toml")
+ cargo_toml_bytes = cargo_toml.encode("utf-8")
+ cargo_toml_info.size = len(cargo_toml_bytes)
+ tar.addfile(cargo_toml_info, io.BytesIO(cargo_toml_bytes))
+
+ # Add a src directory
+ src_dir_info = tarfile.TarInfo(f"{crate_name}/src")
+ src_dir_info.type = tarfile.DIRTYPE
+ tar.addfile(src_dir_info)
+
+ # Add a main.rs file
+ main_rs = 'fn main() { println!("Hello, world!"); }'
+ main_rs_info = tarfile.TarInfo(f"{crate_name}/src/main.rs")
+ main_rs_bytes = main_rs.encode("utf-8")
+ main_rs_info.size = len(main_rs_bytes)
+ tar.addfile(main_rs_info, io.BytesIO(main_rs_bytes))
+
+ # Get the tar data
+ tar_data.seek(0)
+ crate_content = tar_data.getvalue()
+
+ # Create a LibraryFileAlias with the crate content
+ librarian = getUtility(ILibraryFileAliasSet)
+ lfa = librarian.create(
+ f"{crate_name}.crate",
+ len(crate_content),
+ io.BytesIO(crate_content),
+ "application/x-tar",
+ )
+
+ removeSecurityProxy(self.build).addFile(lfa)
+
+ return lfa
+
+ def _create_invalid_crate_file(self, type):
+ """Create an invalid crate file of different types."""
+ if type == "no_dirs":
+ tar_data = io.BytesIO()
+ with tarfile.open(fileobj=tar_data, mode="w") as tar:
+ # Add a file at the root level (no directory)
+ file_info = tarfile.TarInfo("file.txt")
+ file_content = b"This is a file with no directory"
+ file_info.size = len(file_content)
+ tar.addfile(file_info, io.BytesIO(file_content))
+ tar_data.seek(0)
+ content = tar_data.getvalue()
+ filename = "nodirs-0.1.0.crate"
+ mimetype = "application/x-tar"
+ elif type == "dummy":
+ content = b"test content"
+ filename = "test.txt"
+ mimetype = "text/plain"
+ elif type == "invalid_tar":
+ content = b"This is not a valid tar file"
+ filename = "invalid-0.1.0.crate"
+ mimetype = "application/x-tar"
+ else:
+ raise ValueError(f"Unknown invalid crate type: {type}")
+
+ librarian = getUtility(ILibraryFileAliasSet)
+ lfa = librarian.create(
+ filename,
+ len(content),
+ io.BytesIO(content),
+ mimetype,
+ )
+
+ removeSecurityProxy(self.build).addFile(lfa)
+
def _artifactory_search(self, repo_name, artifact_name):
"""Helper to search for a file in the Artifactory fixture."""
@@ -170,17 +300,8 @@ class TestCraftPublishingJob(TestCaseWithFactory):
def test_run_failure_cannot_determine_distribution(self):
"""Test failure when distribution cannot be determined."""
- job = getUtility(ICraftPublishingJobSource).create(self.build)
-
- # Create a mock git repository with a non-distribution target
- git_repo = self.factory.makeGitRepository()
- self.patch(
- removeSecurityProxy(self.recipe), "git_repository", git_repo
- )
+ job = self.run_job(self.build)
- JobRunner([job]).runAll()
-
- job = removeSecurityProxy(job)
self.assertEqual(JobStatus.FAILED, job.job.status)
self.assertEqual(
"Could not determine distribution for build",
@@ -189,65 +310,39 @@ class TestCraftPublishingJob(TestCaseWithFactory):
def test_run_failure_no_configuration(self):
"""Test failure when no configuration is found for the distribution."""
- # Create a distribution with a name that won't have a configuration
- distribution = self.factory.makeDistribution(name="nonexistent")
+ self._setup_distribution("nonexistent")
- # Create a distribution source package for our distribution
- package = self.factory.makeDistributionSourcePackage(
- distribution=distribution
+ job = self.run_job(self.build)
+
+ self.assertEqual(JobStatus.FAILED, job.job.status)
+ self.assertEqual(
+ "No configuration found for nonexistent",
+ job.error_message,
)
- # Create a git repository targeting that package
- git_repository = self.factory.makeGitRepository(target=package)
+ def test_run_no_http_proxy(self):
+ """Test failure when no HTTP proxy is configured."""
+ self._setup_distribution("soss")
+ self._setup_config()
- # Update our recipe to use this git repository
- removeSecurityProxy(self.recipe).git_repository = git_repository
-
- job = getUtility(ICraftPublishingJobSource).create(self.build)
- JobRunner([job]).runAll()
- job = removeSecurityProxy(job)
+ job = self.run_job(self.build)
self.assertEqual(JobStatus.FAILED, job.job.status)
self.assertEqual(
- "No configuration found for nonexistent",
+ "Skipping artifact publishing: No HTTP proxy configured",
job.error_message,
)
def test_run_no_publishable_artifacts(self):
"""Test failure when no publishable artifacts are found."""
- distribution = self.factory.makeDistribution(name="soss")
+ self._setup_distribution("soss")
+ self._setup_config(with_http_proxy=True)
- # Set up config with environment variables but no Cargo publishing info
- # We just need a config section for the distribution name
- self.pushConfig("craftbuild.soss")
- package = self.factory.makeDistributionSourcePackage(
- distribution=distribution
- )
- git_repository = self.factory.makeGitRepository(target=package)
- removeSecurityProxy(self.recipe).git_repository = git_repository
-
- # Create a dummy file (but not a crate or jar)
- from io import BytesIO
-
- dummy_content = b"test content"
-
- # Create a LibraryFileAlias with the dummy content
- librarian = getUtility(ILibraryFileAliasSet)
- lfa = librarian.create(
- "test.txt",
- len(dummy_content),
- BytesIO(dummy_content),
- "text/plain",
- )
+ self._create_invalid_crate_file(type="dummy")
- # Add the file to the build
- removeSecurityProxy(self.build).addFile(lfa)
+ job = self.run_job(self.build)
- job = getUtility(ICraftPublishingJobSource).create(self.build)
- JobRunner([job]).runAll()
- job = removeSecurityProxy(job)
self.assertEqual(JobStatus.FAILED, job.job.status)
-
self.assertEqual(
"No publishable artifacts found in build",
job.error_message,
@@ -255,69 +350,12 @@ class TestCraftPublishingJob(TestCaseWithFactory):
def test_run_missing_cargo_config(self):
"""Test failure when a crate is found but Cargo config is missing."""
- distribution = self.factory.makeDistribution(name="soss")
- self.pushConfig("craftbuild.soss")
- package = self.factory.makeDistributionSourcePackage(
- distribution=distribution
- )
-
- git_repository = self.factory.makeGitRepository(target=package)
-
- removeSecurityProxy(self.recipe).git_repository = git_repository
-
- # Create a BytesIO object to hold the tar data
- tar_data = io.BytesIO()
-
- # Create a tar archive
- with tarfile.open(fileobj=tar_data, mode="w") as tar:
- # Create a directory entry for the crate
- crate_dir_info = tarfile.TarInfo("test-0.1.0")
- crate_dir_info.type = tarfile.DIRTYPE
- tar.addfile(crate_dir_info)
-
- # Add a Cargo.toml file
- cargo_toml = """
-[package]
-name = "test"
-version = "0.1.0"
-authors = ["Test <test@xxxxxxxxxxx>"]
-edition = "2018"
-"""
- cargo_toml_info = tarfile.TarInfo("test-0.1.0/Cargo.toml")
- cargo_toml_bytes = cargo_toml.encode("utf-8")
- cargo_toml_info.size = len(cargo_toml_bytes)
- tar.addfile(cargo_toml_info, io.BytesIO(cargo_toml_bytes))
-
- # Add a src directory
- src_dir_info = tarfile.TarInfo("test-0.1.0/src")
- src_dir_info.type = tarfile.DIRTYPE
- tar.addfile(src_dir_info)
-
- # Add a main.rs file
- main_rs = 'fn main() { println!("Hello, world!"); }'
- main_rs_info = tarfile.TarInfo("test-0.1.0/src/main.rs")
- main_rs_bytes = main_rs.encode("utf-8")
- main_rs_info.size = len(main_rs_bytes)
- tar.addfile(main_rs_info, io.BytesIO(main_rs_bytes))
-
- # Get the tar data
- tar_data.seek(0)
- crate_content = tar_data.getvalue()
-
- # Create a LibraryFileAlias with the crate content
- librarian = getUtility(ILibraryFileAliasSet)
- lfa = librarian.create(
- "test-0.1.0.crate",
- len(crate_content),
- io.BytesIO(crate_content),
- "application/x-tar",
- )
+ self._setup_distribution("soss")
+ self._setup_config(with_http_proxy=True)
- removeSecurityProxy(self.build).addFile(lfa)
+ self._create_crate_file()
- job = getUtility(ICraftPublishingJobSource).create(self.build)
- JobRunner([job]).runAll()
- job = removeSecurityProxy(job)
+ job = self.run_job(self.build)
self.assertEqual(JobStatus.FAILED, job.job.status)
self.assertEqual(
@@ -327,43 +365,12 @@ edition = "2018"
def test_run_crate_extraction_failure(self):
"""Test failure when crate extraction fails."""
- distribution = self.factory.makeDistribution(name="soss")
-
- # Set up config with environment variables
- self.pushConfig(
- "craftbuild.soss",
- environment_variables=json.dumps(
- {
- "CARGO_PUBLISH_URL": "https://example.com/registry",
- "CARGO_PUBLISH_AUTH": "lp:token123",
- }
- ),
- )
-
- package = self.factory.makeDistributionSourcePackage(
- distribution=distribution
- )
+ self._setup_distribution("soss")
+ self._setup_config(with_env_vars=True, with_http_proxy=True)
- git_repository = self.factory.makeGitRepository(target=package)
-
- removeSecurityProxy(self.recipe).git_repository = git_repository
+ self._create_invalid_crate_file(type="invalid_tar")
- # Create an invalid tar file (just some random bytes)
- invalid_crate_content = b"This is not a valid tar file"
-
- librarian = getUtility(ILibraryFileAliasSet)
- lfa = librarian.create(
- "invalid-0.1.0.crate",
- len(invalid_crate_content),
- io.BytesIO(invalid_crate_content),
- "application/x-tar",
- )
-
- removeSecurityProxy(self.build).addFile(lfa)
-
- job = getUtility(ICraftPublishingJobSource).create(self.build)
- JobRunner([job]).runAll()
- job = removeSecurityProxy(job)
+ job = self.run_job(self.build)
self.assertEqual(JobStatus.FAILED, job.job.status)
self.assertIn(
@@ -373,60 +380,13 @@ edition = "2018"
def test_run_no_directory_in_crate(self):
"""Test failure when no directory is found in extracted crate."""
- distribution = self.factory.makeDistribution(name="soss")
-
- # Set up config with environment variables
- self.pushConfig(
- "craftbuild.soss",
- environment_variables=json.dumps(
- {
- "CARGO_PUBLISH_URL": "https://example.com/registry",
- "CARGO_PUBLISH_AUTH": "lp:token123",
- }
- ),
- )
+ self._setup_distribution("soss")
+ self._setup_config(with_env_vars=True, with_http_proxy=True)
- package = self.factory.makeDistributionSourcePackage(
- distribution=distribution
- )
+ self._create_invalid_crate_file(type="no_dirs")
- git_repository = self.factory.makeGitRepository(target=package)
-
- removeSecurityProxy(self.recipe).git_repository = git_repository
-
- tar_data = io.BytesIO()
-
- # Create a tar archive with only files (no directories)
- with tarfile.open(fileobj=tar_data, mode="w") as tar:
- # Add a file at the root level (no directory)
- file_info = tarfile.TarInfo("file.txt")
- file_content = b"This is a file with no directory"
- file_info.size = len(file_content)
- tar.addfile(file_info, io.BytesIO(file_content))
+ job = self.run_job(self.build)
- # Get the tar data
- tar_data.seek(0)
- crate_content = tar_data.getvalue()
-
- # Create a LibraryFileAlias with the crate content
- librarian = getUtility(ILibraryFileAliasSet)
- lfa = librarian.create(
- "nodirs-0.1.0.crate",
- len(crate_content),
- io.BytesIO(crate_content),
- "application/x-tar",
- )
-
- # Add the file to the build
- removeSecurityProxy(self.build).addFile(lfa)
-
- # Create and run the job
- job = getUtility(ICraftPublishingJobSource).create(self.build)
-
- JobRunner([job]).runAll()
-
- # Verify job failed with expected error message
- job = removeSecurityProxy(job)
self.assertEqual(JobStatus.FAILED, job.job.status)
self.assertEqual(
"No directory found in extracted crate",
@@ -435,74 +395,10 @@ edition = "2018"
def test_run_cargo_publish_success(self):
"""Test success when a crate is found and Cargo config is present."""
- distribution = self.factory.makeDistribution(name="soss")
- self.pushConfig(
- "craftbuild.soss",
- environment_variables=json.dumps(
- {
- "CARGO_PUBLISH_URL": f"{self.base_url}/repository",
- "CARGO_PUBLISH_AUTH": "lp:token123",
- }
- ),
- )
- package = self.factory.makeDistributionSourcePackage(
- distribution=distribution
- )
-
- git_repository = self.factory.makeGitRepository(target=package)
-
- removeSecurityProxy(self.recipe).git_repository = git_repository
-
- # Create a BytesIO object to hold the tar data
- tar_data = io.BytesIO()
-
- # Create a tar archive
- with tarfile.open(fileobj=tar_data, mode="w") as tar:
- # Create a directory entry for the crate
- crate_dir_info = tarfile.TarInfo("test-0.1.0")
- crate_dir_info.type = tarfile.DIRTYPE
- crate_dir_info.mode = 0o755 # rwxr-xr-x
- tar.addfile(crate_dir_info)
-
- # Add a Cargo.toml file
- cargo_toml = """
-[package]
-name = "test"
-version = "0.1.0"
-authors = ["Test <test@xxxxxxxxxxx>"]
-edition = "2018"
-"""
- cargo_toml_info = tarfile.TarInfo("test-0.1.0/Cargo.toml")
- cargo_toml_bytes = cargo_toml.encode("utf-8")
- cargo_toml_info.size = len(cargo_toml_bytes)
- tar.addfile(cargo_toml_info, io.BytesIO(cargo_toml_bytes))
-
- # Add a src directory
- src_dir_info = tarfile.TarInfo("test-0.1.0/src")
- src_dir_info.type = tarfile.DIRTYPE
- tar.addfile(src_dir_info)
-
- # Add a main.rs file
- main_rs = 'fn main() { println!("Hello, world!"); }'
- main_rs_info = tarfile.TarInfo("test-0.1.0/src/main.rs")
- main_rs_bytes = main_rs.encode("utf-8")
- main_rs_info.size = len(main_rs_bytes)
- tar.addfile(main_rs_info, io.BytesIO(main_rs_bytes))
-
- # Get the tar data
- tar_data.seek(0)
- crate_content = tar_data.getvalue()
+ self._setup_distribution("soss")
+ self._setup_config(with_env_vars=True, with_http_proxy=True)
- # Create a LibraryFileAlias with the crate content
- librarian = getUtility(ILibraryFileAliasSet)
- lfa = librarian.create(
- "test-0.1.0.crate",
- len(crate_content),
- io.BytesIO(crate_content),
- "application/x-tar",
- )
-
- removeSecurityProxy(self.build).addFile(lfa)
+ lfa = self._create_crate_file()
# Add a metadata file with license information
license_value = "Apache-2.0"
@@ -619,7 +515,7 @@ edition = "2018"
)
self.assertEqual(
artifact["properties"]["soss.source_url"],
- git_repository.git_https_url,
+ removeSecurityProxy(self.recipe).git_repository.git_https_url,
)
self.assertEqual(artifact["properties"]["soss.type"], "source")
self.assertEqual(artifact["properties"]["soss.license"], license_value)
@@ -629,14 +525,8 @@ edition = "2018"
Test failure when Maven artifacts are found but Maven config is
missing.
"""
- distribution = self.factory.makeDistribution(name="soss")
-
- self.pushConfig("craftbuild.soss")
- package = self.factory.makeDistributionSourcePackage(
- distribution=distribution
- )
- git_repository = self.factory.makeGitRepository(target=package)
- removeSecurityProxy(self.recipe).git_repository = git_repository
+ self._setup_distribution("soss")
+ self._setup_config(with_http_proxy=True)
# Create a dummy jar file
from io import BytesIO
@@ -668,9 +558,7 @@ edition = "2018"
removeSecurityProxy(self.build).addFile(pom_lfa)
# Create and run the job
- job = getUtility(ICraftPublishingJobSource).create(self.build)
- JobRunner([job]).runAll()
- job = removeSecurityProxy(job)
+ job = self.run_job(self.build)
self.assertEqual(JobStatus.FAILED, job.job.status)
self.assertEqual(
@@ -680,24 +568,8 @@ edition = "2018"
def test_run_maven_deploy_success(self):
"""Test successful Maven artifact publishing."""
- distribution = self.factory.makeDistribution(name="soss")
-
- # Set up config with Maven publishing environment variables
- self.pushConfig(
- "craftbuild.soss",
- environment_variables=json.dumps(
- {
- "MAVEN_PUBLISH_URL": f"{self.base_url}/repository",
- "MAVEN_PUBLISH_AUTH": "maven_user:maven_password",
- }
- ),
- )
-
- package = self.factory.makeDistributionSourcePackage(
- distribution=distribution
- )
- git_repository = self.factory.makeGitRepository(target=package)
- removeSecurityProxy(self.recipe).git_repository = git_repository
+ self._setup_distribution("soss")
+ self._setup_config(with_env_vars=True, with_http_proxy=True)
# Create a dummy jar file
dummy_jar_content = b"dummy jar content"
@@ -790,12 +662,8 @@ edition = "2018"
mock_maven_publish_properties,
)
- # Create and run the job
- job = getUtility(ICraftPublishingJobSource).create(self.build)
- JobRunner([job]).runAll()
+ job = self.run_job(self.build)
- # Verify job succeeded
- job = removeSecurityProxy(job)
self.assertEqual(JobStatus.COMPLETED, job.job.status)
# Find the call for mvn deploy
@@ -865,7 +733,7 @@ edition = "2018"
)
self.assertEqual(
artifact["properties"]["soss.source_url"],
- git_repository.git_https_url,
+ removeSecurityProxy(self.recipe).git_repository.git_https_url,
)
self.assertEqual(artifact["properties"]["soss.type"], "source")
self.assertEqual(artifact["properties"]["soss.license"], license_value)
diff --git a/lib/lp/services/config/schema-lazr.conf b/lib/lp/services/config/schema-lazr.conf
index 27321c8..faed840 100644
--- a/lib/lp/services/config/schema-lazr.conf
+++ b/lib/lp/services/config/schema-lazr.conf
@@ -2040,7 +2040,6 @@ crontab_group: MAIN
[ICraftRecipeRequestBuildsJobSource]
module: lp.crafts.interfaces.craftrecipejob
dbuser: craft-build-job
-crontab_group: MAIN
[ICraftPublishingJobSource]
module: lp.crafts.interfaces.craftrecipebuildjob
Follow ups