diff --git a/src/apm_cli/utils/github_host.py b/src/apm_cli/utils/github_host.py index 023b83077..d77992617 100644 --- a/src/apm_cli/utils/github_host.py +++ b/src/apm_cli/utils/github_host.py @@ -1068,6 +1068,13 @@ def build_artifactory_archive_url( # that Artifactory cannot follow across hosts) f"{base}/zip/refs/heads/{ref}", f"{base}/zip/refs/tags/{ref}", + # Frozen installs resolve refs to a full commit SHA. Artifactory proxies + # expose that immutable object through GitHub's generic commit archive path. + *( + (f"{base}/archive/{ref}.zip",) + if re.fullmatch(r"[0-9a-fA-F]{40}", ref) + else () + ), ) diff --git a/tests/unit/test_artifactory_support.py b/tests/unit/test_artifactory_support.py index 4da75d333..ec454a18f 100644 --- a/tests/unit/test_artifactory_support.py +++ b/tests/unit/test_artifactory_support.py @@ -270,6 +270,24 @@ def test_custom_ref(self): assert any("/refs/heads/v1.0.0.zip" in u for u in urls) assert any("/-/archive/v1.0.0/repo-v1.0.0.zip" in u for u in urls) + def test_commit_sha_adds_generic_archive_fallback(self): + """Resolved commits include the immutable GitHub commit archive URL.""" + sha = "a" * 40 + urls = build_artifactory_archive_url( + "art.example.com", "artifactory/github", "owner", "repo", ref=sha + ) + + assert urls[-1].endswith(f"/owner/repo/archive/{sha}.zip") + assert any(f"/refs/heads/{sha}.zip" in u for u in urls) + assert any(f"/refs/tags/{sha}.zip" in u for u in urls) + + def test_short_hex_ref_does_not_add_commit_archive_fallback(self): + urls = build_artifactory_archive_url( + "art.example.com", "artifactory/github", "owner", "repo", ref="abc123" + ) + + assert not any(u.endswith("/archive/abc123.zip") for u in urls) + def test_real_artifactory_host(self): """Build URLs matching real Artifactory pattern.""" urls = build_artifactory_archive_url(