Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Username/password (Basic Auth) support for packages.redhat.com

### Changed
- Local `--artifact-results` folder path: `distributions` in `pulp_results.json` no longer includes a synthetic `artifacts` pulp-content URL (artifacts repo was already skipped; URL map now aligns)
- `upload --target-arch-repo`: `pulp_results.json` `distributions` keys for per-arch RPM bases are `rpm_<arch>` instead of bare architecture names (e.g. `rpm_x86_64` not `x86_64`)
- `upload` / `upload-files`: infer whether log and SBOM repos are needed before repository setup (directory `*.log` scan or `--results-json` artifact keys; SBOM via `--sbom-path` or SBOM-classified keys); omitted types are excluded from results `distributions`; clear errors if uploads are attempted without the matching repository
- Upload orchestration uses `RpmUploadResult` per architecture instead of ad-hoc dicts; gather/collect uses `PulpContentRow`, `ExtraArtifactRef`, and `FileInfoMap` for clearer typed data flow
Expand Down
3 changes: 2 additions & 1 deletion pulp_tool/models/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ class UploadContext(KonfluxBaseModel):
parent_package: Optional parent package name (will not be added to labels if not provided)
config: Optional path to config file
debug: Verbosity level (0=WARNING, 1=INFO, 2=DEBUG, 3+=DEBUG with HTTP logs)
artifact_results: Optional artifact results configuration
artifact_results: Konflux ``url_path,digest_path``, or a single folder path to write ``pulp_results.json``
locally (no comma); local folder also skips artifacts repo and ``artifacts`` distribution URLs in JSON
sbom_results: Optional path to write SBOM results
skip_logs_repo: When True, logs repo was not created; omit logs distribution URLs
skip_sbom_repo: When True, SBOM repo was not created; omit sbom distribution URLs
Expand Down
7 changes: 7 additions & 0 deletions pulp_tool/utils/distribution_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ def get_distribution_urls(
include_signed_rpm_distro: bool = False,
skip_logs_repo: bool = False,
skip_sbom_repo: bool = False,
skip_artifacts_repo: bool = False,
) -> Dict[str, str]:
"""
Get distribution URLs for all repository types.
Expand All @@ -73,6 +74,7 @@ def get_distribution_urls(
include_signed_rpm_distro: If True, add ``rpms_signed`` URL for ``{build}/rpms-signed/``
skip_logs_repo: If True, omit ``logs`` distribution URL
skip_sbom_repo: If True, omit ``sbom`` distribution URL
skip_artifacts_repo: If True, omit ``artifacts`` (e.g. results JSON saved locally)

Returns:
Dictionary mapping repo_type to distribution URL
Expand All @@ -99,6 +101,7 @@ def get_distribution_urls(
include_signed_rpm_distro=include_signed_rpm_distro,
skip_logs_repo=skip_logs_repo,
skip_sbom_repo=skip_sbom_repo,
skip_artifacts_repo=skip_artifacts_repo,
)

logging.debug("Retrieved %d distribution URLs", len(distribution_urls))
Expand Down Expand Up @@ -146,6 +149,7 @@ def _get_distribution_urls_impl(
include_signed_rpm_distro: bool = False,
skip_logs_repo: bool = False,
skip_sbom_repo: bool = False,
skip_artifacts_repo: bool = False,
) -> Dict[str, str]:
"""
Get distribution URLs for all repository types.
Expand All @@ -156,6 +160,7 @@ def _get_distribution_urls_impl(
include_signed_rpm_distro: If True, add ``rpms_signed`` for signed RPM distribution
skip_logs_repo: If True, omit ``logs``
skip_sbom_repo: If True, omit ``sbom``
skip_artifacts_repo: If True, omit ``artifacts``

Returns:
Dictionary mapping repo_type to distribution URL
Expand All @@ -174,6 +179,8 @@ def _get_distribution_urls_impl(
continue
if skip_sbom_repo and repo_type == "sbom":
continue
if skip_artifacts_repo and repo_type == "artifacts":
continue
url = self._get_single_distribution_url(build_id, repo_type, base_url)
if url:
distribution_urls[repo_type] = url
Expand Down
9 changes: 9 additions & 0 deletions pulp_tool/utils/pulp_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ def get_distribution_urls(
include_signed_rpm_distro: bool = False,
skip_logs_repo: bool = False,
skip_sbom_repo: bool = False,
skip_artifacts_repo: bool = False,
) -> dict[str, str]:
"""
Get distribution URLs for all repository types.
Expand All @@ -111,6 +112,7 @@ def get_distribution_urls(
include_signed_rpm_distro: If True, include ``rpms_signed`` URL
skip_logs_repo: If True, omit ``logs`` URL
skip_sbom_repo: If True, omit ``sbom`` URL
skip_artifacts_repo: If True, omit ``artifacts`` URL

Returns:
Dictionary mapping repo_type to distribution URL
Expand All @@ -121,6 +123,7 @@ def get_distribution_urls(
include_signed_rpm_distro=include_signed_rpm_distro,
skip_logs_repo=skip_logs_repo,
skip_sbom_repo=skip_sbom_repo,
skip_artifacts_repo=skip_artifacts_repo,
)

def get_distribution_urls_for_upload_context(self, build_id: str, context: UploadContext) -> dict[str, str]:
Expand All @@ -129,24 +132,30 @@ def get_distribution_urls_for_upload_context(self, build_id: str, context: Uploa
signed_by = getattr(context, "signed_by", None)
skip_logs = bool(getattr(context, "skip_logs_repo", False))
skip_sbom = bool(getattr(context, "skip_sbom_repo", False))
ar = (getattr(context, "artifact_results", None) or "").strip()
# Local folder mode: --artifact-results /path/to/dir (no comma); no artifacts repo or distribution
skip_artifacts = bool(ar and "," not in ar)
if target_arch:
return self.get_distribution_urls(
build_id,
target_arch_repo=True,
skip_logs_repo=skip_logs,
skip_sbom_repo=skip_sbom,
skip_artifacts_repo=skip_artifacts,
)
if signed_by and str(signed_by).strip():
return self.get_distribution_urls(
build_id,
include_signed_rpm_distro=True,
skip_logs_repo=skip_logs,
skip_sbom_repo=skip_sbom,
skip_artifacts_repo=skip_artifacts,
)
return self.get_distribution_urls(
build_id,
skip_logs_repo=skip_logs,
skip_sbom_repo=skip_sbom,
skip_artifacts_repo=skip_artifacts,
)

def ensure_rpm_repository_for_arch(self, build_id: str, arch: str) -> str:
Expand Down
26 changes: 26 additions & 0 deletions tests/test_upload.py
Original file line number Diff line number Diff line change
Expand Up @@ -1101,6 +1101,32 @@ def test_add_distributions_to_results_target_arch_repo(self, mock_pulp_client):
"https://pulp.example.com/api/pulp-content/test-namespace/x86_64/"
)

def test_add_distributions_to_results_omits_artifacts_for_local_artifact_results(self, mock_pulp_client):
"""Folder --artifact-results must not add a synthetic artifacts distribution entry."""
repositories = RepositoryRefs(
rpms_href="/rpms/",
rpms_prn="rpms-prn",
logs_href="/logs/",
logs_prn="logs-prn",
sbom_href="/sbom/",
sbom_prn="sbom-prn",
artifacts_href="",
artifacts_prn="",
)
results_model = PulpResultsModel(build_id="my-build", repositories=repositories)
context = UploadRpmContext(
build_id="my-build",
date_str="2024-01-01",
namespace="test-ns",
parent_package="test-pkg",
rpm_path="/rpms",
artifact_results="/data/results-out",
)
_add_distributions_to_results(mock_pulp_client, context, results_model)
assert "artifacts" not in results_model.distributions
assert "rpms" in results_model.distributions
assert "logs" in results_model.distributions

def test_add_distributions_to_results_warns_when_no_distribution_urls(self, mock_pulp_client, caplog):
"""When no build-scoped distribution URLs are returned, log a warning."""
repositories = RepositoryRefs(
Expand Down
11 changes: 11 additions & 0 deletions tests/utils/test_distribution_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,17 @@ def test_get_distribution_urls_skip_logs_and_sbom(self):
assert "rpms" in urls
assert "artifacts" in urls

def test_get_distribution_urls_skip_artifacts_repo(self):
"""skip_artifacts_repo omits artifacts (local results JSON folder mode)."""
mock_client = Mock()
mock_client.config = {"base_url": "https://pulp.example.com"}
manager = DistributionManager(mock_client, "test-namespace")
urls = manager.get_distribution_urls("b1", skip_artifacts_repo=True)
assert "artifacts" not in urls
assert "rpms" in urls
assert "logs" in urls
assert "sbom" in urls


class TestDistributionManagerTargetArchRepo:
"""Distribution URLs when using per-architecture RPM repositories."""
Expand Down
26 changes: 26 additions & 0 deletions tests/utils/test_pulp_helper_upload.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ def test_get_distribution_urls_for_upload_context_target_arch_repo_branch(self,
target_arch_repo=True,
skip_logs_repo=False,
skip_sbom_repo=False,
skip_artifacts_repo=False,
)

def test_get_distribution_urls_for_upload_context_signed_by_branch(self, mock_pulp_client):
Expand All @@ -113,6 +114,7 @@ def test_get_distribution_urls_for_upload_context_signed_by_branch(self, mock_pu
include_signed_rpm_distro=True,
skip_logs_repo=False,
skip_sbom_repo=False,
skip_artifacts_repo=False,
)

def test_get_distribution_urls_for_upload_context_passes_skip_repo_flags(self, mock_pulp_client):
Expand All @@ -136,6 +138,30 @@ def test_get_distribution_urls_for_upload_context_passes_skip_repo_flags(self, m
"b123",
skip_logs_repo=True,
skip_sbom_repo=True,
skip_artifacts_repo=False,
)

def test_get_distribution_urls_for_upload_context_local_artifact_results_skips_artifacts(self, mock_pulp_client):
"""Folder --artifact-results (no comma) forwards skip_artifacts_repo=True."""
helper = PulpHelper(mock_pulp_client)
context = UploadRpmContext(
build_id="b123",
date_str="2024-01-01 00:00:00",
namespace="ns",
parent_package="pkg",
rpm_path="/r",
artifact_results="/out/dir",
)

with patch.object(helper, "get_distribution_urls", return_value={"rpms": "https://r/"}) as mock_urls:
out = helper.get_distribution_urls_for_upload_context("b123", context)

assert out == {"rpms": "https://r/"}
mock_urls.assert_called_once_with(
"b123",
skip_logs_repo=False,
skip_sbom_repo=False,
skip_artifacts_repo=True,
)

def test_process_uploads(self, mock_pulp_client):
Expand Down
Loading