diff --git a/CHANGES/+pulp-attestation-sync.bugfix b/CHANGES/+pulp-attestation-sync.bugfix new file mode 100644 index 000000000..b61e1661c --- /dev/null +++ b/CHANGES/+pulp-attestation-sync.bugfix @@ -0,0 +1 @@ +Fixed provenance sync failing when syncing Pulp-created attestations that use a `Pulp User` publisher. diff --git a/pulp_python/app/tasks/sync.py b/pulp_python/app/tasks/sync.py index e1fa7b224..25a4955d5 100644 --- a/pulp_python/app/tasks/sync.py +++ b/pulp_python/app/tasks/sync.py @@ -9,7 +9,6 @@ from bandersnatch.mirror import Mirror from lxml.etree import LxmlError from packaging.requirements import Requirement -from pypi_attestations import Provenance from pypi_simple import IndexPage from pulpcore.plugin.download import HttpDownloader @@ -28,6 +27,7 @@ PythonPackageContent, PythonRemote, ) +from pulp_python.app.provenance import Provenance from pulp_python.app.utils import PYPI_LAST_SERIAL, aget_remote_simple_page, parse_metadata logger = logging.getLogger(__name__) diff --git a/pulp_python/tests/functional/api/test_attestations.py b/pulp_python/tests/functional/api/test_attestations.py index 0737256b7..6a8ac9d95 100644 --- a/pulp_python/tests/functional/api/test_attestations.py +++ b/pulp_python/tests/functional/api/test_attestations.py @@ -154,6 +154,54 @@ def test_attestation_sync_upload(python_bindings, twine_package, download_python assert att_bundle["publisher"]["kind"] == "Pulp User" +@pytest.mark.parallel +def test_sync_pulp_created_provenance( + domain_factory, + python_bindings, + twine_package, + python_repo_factory, + python_distribution_factory, + python_remote_factory, + python_repo_with_sync, + python_content_summary, + monitor_task, +): + """Test syncing provenance across domains from a Pulp upload.""" + source_domain = domain_factory() + attestations = get_attestations(twine_package.provenance_url) + source_repo = python_repo_factory(pulp_domain=source_domain.name) + body = { + "relative_path": twine_package.filename, + "file_url": twine_package.url, + "attestations": json.dumps(attestations), + "repository": source_repo.pulp_href, + } + task = python_bindings.ContentPackagesApi.create(pulp_domain=source_domain.name, **body).task + monitor_task(task) + + source_distro = python_distribution_factory( + repository=source_repo, pulp_domain=source_domain.name + ) + dest_domain = domain_factory() + remote = python_remote_factory( + url=source_distro.base_url, + provenance=True, + includes=[f"twine=={twine_package.version}"], + pulp_domain=dest_domain.name, + ) + dest_repo = python_repo_with_sync(remote=remote, pulp_domain=dest_domain.name) + + summary = python_content_summary(repository_version=dest_repo.latest_version_href) + assert summary.present["python.provenance"]["count"] == 1 + + provs = python_bindings.ContentProvenanceApi.list( + repository_version=dest_repo.latest_version_href, + pulp_domain=dest_domain.name, + ) + assert provs.count == 1 + assert provs.results[0].provenance["attestation_bundles"][0]["publisher"]["kind"] == "Pulp User" + + def test_attestation_twine_upload( pulpcore_bindings, python_content_summary, diff --git a/pulp_python/tests/functional/api/test_crud_content_unit.py b/pulp_python/tests/functional/api/test_crud_content_unit.py index 5bf799563..658cc4332 100644 --- a/pulp_python/tests/functional/api/test_crud_content_unit.py +++ b/pulp_python/tests/functional/api/test_crud_content_unit.py @@ -203,7 +203,6 @@ def test_package_creation_with_metadata( ) -@pytest.mark.parallel def test_disallow_package_substitution( monitor_task, python_bindings, @@ -272,7 +271,6 @@ def test_disallow_package_substitution( assert repo.latest_version_href.endswith("/2/") -@pytest.mark.parallel def test_package_substitution_allowed_by_default( monitor_task, python_bindings,