From 24b6fd0ae33097ce90988c34f42493706d0736c7 Mon Sep 17 00:00:00 2001 From: Padraig O'Connor Date: Wed, 8 Apr 2026 19:29:35 +0100 Subject: [PATCH 1/2] modify alpine upstream rsa fields --- cloudsmith_cli/cli/commands/upstream.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/cloudsmith_cli/cli/commands/upstream.py b/cloudsmith_cli/cli/commands/upstream.py index d6252613..902006fb 100644 --- a/cloudsmith_cli/cli/commands/upstream.py +++ b/cloudsmith_cli/cli/commands/upstream.py @@ -66,6 +66,20 @@ def build_row(u): click.style(fmt_bool(u["verify_ssl"]), fg="green"), ] + if upstream_fmt == "alpine": + # RSA verification fields are alpine-only + row.append( + click.style( + maybe_truncate_string(str(u.get("rsa_key_inline", "") or "")), + fg="yellow", + ) + ) + row.append(click.style(str(u.get("rsa_key_url", "") or ""), fg="yellow")) + row.append(click.style(str(u.get("rsa_verification", "")), fg="yellow")) + row.append( + click.style(str(u.get("rsa_verification_status", "")), fg="yellow") + ) + if upstream_fmt == "deb": # `Component`, `Distribution Versions` and `Upstream Distribution` are deb-only row.append(click.style(str(u.get("component", None)), fg="yellow")) @@ -104,6 +118,12 @@ def build_row(u): "Verify SSL", ] + if upstream_fmt == "alpine": + headers.append("RSA Key Inline") + headers.append("RSA Key URL") + headers.append("RSA Verification") + headers.append("RSA Verification Status") + if upstream_fmt == "deb": headers.append("Component") headers.append("Distribution Versions") From 3dcfac87f99f7eb1dd1e904b23fad9d88b365b38 Mon Sep 17 00:00:00 2001 From: Padraig O'Connor Date: Tue, 14 Apr 2026 13:12:36 +0100 Subject: [PATCH 2/2] address copilot feedback --- cloudsmith_cli/cli/commands/upstream.py | 14 ++-- .../cli/tests/commands/test_upstream.py | 66 +++++++++++++++++++ 2 files changed, 76 insertions(+), 4 deletions(-) diff --git a/cloudsmith_cli/cli/commands/upstream.py b/cloudsmith_cli/cli/commands/upstream.py index 902006fb..f317139f 100644 --- a/cloudsmith_cli/cli/commands/upstream.py +++ b/cloudsmith_cli/cli/commands/upstream.py @@ -75,14 +75,18 @@ def build_row(u): ) ) row.append(click.style(str(u.get("rsa_key_url", "") or ""), fg="yellow")) - row.append(click.style(str(u.get("rsa_verification", "")), fg="yellow")) row.append( - click.style(str(u.get("rsa_verification_status", "")), fg="yellow") + click.style(str(u.get("rsa_verification", "") or ""), fg="yellow") + ) + row.append( + click.style( + str(u.get("rsa_verification_status", "") or ""), fg="yellow" + ) ) if upstream_fmt == "deb": # `Component`, `Distribution Versions` and `Upstream Distribution` are deb-only - row.append(click.style(str(u.get("component", None)), fg="yellow")) + row.append(click.style(str(u.get("component", None) or ""), fg="yellow")) row.append( click.style( str(maybe_truncate_list(u.get("distro_versions", []))), @@ -90,7 +94,9 @@ def build_row(u): ) ) row.append( - click.style(str(u.get("upstream_distribution", None)), fg="yellow") + click.style( + str(u.get("upstream_distribution", None) or ""), fg="yellow" + ) ) if upstream_fmt == "rpm": diff --git a/cloudsmith_cli/cli/tests/commands/test_upstream.py b/cloudsmith_cli/cli/tests/commands/test_upstream.py index 3069784f..d7c3c4cd 100644 --- a/cloudsmith_cli/cli/tests/commands/test_upstream.py +++ b/cloudsmith_cli/cli/tests/commands/test_upstream.py @@ -159,3 +159,69 @@ def test_upstream_commands( assert result.exit_code == 0 result_data = json.loads(result.output)["data"] assert not result_data # We should have no upstreams at this point + + +@pytest.mark.usefixtures("set_api_key_env_var", "set_api_host_env_var") +def test_alpine_upstream_ls_pretty_rsa_columns( + runner, organization, tmp_repository, tmp_path +): + """Pretty-output ls for alpine must render all four RSA columns with correct headers and values. + + Alpine is the only format with RSA verification fields (rsa_key_inline, rsa_key_url, + rsa_verification, rsa_verification_status). These are appended to the common column set + inside print_upstreams(), so a regression in the branching logic or header list would + silently drop or misalign them. This test catches that by asserting against the rendered + table text rather than JSON output. + """ + rsa_key_url = "https://www.cloudsmith.io" + upstream_config = { + "name": "cli-test-upstream-alpine-rsa", + "upstream_url": "https://www.cloudsmith.io", + "rsa_key_url": rsa_key_url, + } + + upstream_config_file = tmp_path / "cli-test-upstream-alpine-rsa.json" + upstream_config_file.write_text(json.dumps(upstream_config)) + + org_repo = f"{organization}/{tmp_repository['slug']}" + + # Create the upstream and capture its slug_perm for later cleanup + create_result = runner.invoke( + upstream, + args=["alpine", "create", org_repo, str(upstream_config_file), "-F", "json"], + catch_exceptions=False, + ) + assert create_result.exit_code == 0 + slug_perm = json.loads(create_result.output)["data"]["slug_perm"] + + try: + # Run ls with default pretty output — the path under test + result = runner.invoke( + upstream, + args=["alpine", "ls", org_repo], + catch_exceptions=False, + ) + assert result.exit_code == 0 + + # All four RSA column headers must appear in the table header row + assert "RSA Key Inline" in result.output + assert "RSA Key URL" in result.output + assert ( + "RSA Verification Status" in result.output + ) # most specific; covers "RSA Verification" too + assert "RSA Verification" in result.output + + # The rsa_key_url value we set must appear in the data row + assert rsa_key_url in result.output + + # Common non-RSA headers must still be present (guard against over-trimming) + assert "Name" in result.output + assert "Upstream Url" in result.output + assert "Verify SSL" in result.output + + finally: + runner.invoke( + upstream, + args=["alpine", "delete", f"{org_repo}/{slug_perm}", "-y"], + catch_exceptions=False, + )