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 .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ PYTEST_CLOUDSMITH_API_KEY=
PYTEST_CLOUDSMITH_ORGANIZATION=
PYTEST_CLOUDSMITH_PASSWORD=
PYTEST_CLOUDSMITH_USERNAME=
PYTEST_GITHUB_TOKEN=
1 change: 1 addition & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ jobs:
PYTEST_CLOUDSMITH_ORGANIZATION: ${{ vars.PYTEST_CLOUDSMITH_ORGANIZATION }}
PYTEST_CLOUDSMITH_USERNAME: ${{ secrets.PYTEST_CLOUDSMITH_USERNAME }}
PYTEST_CLOUDSMITH_PASSWORD: ${{ secrets.PYTEST_CLOUDSMITH_PASSWORD }}
PYTEST_GITHUB_TOKEN: ${{ secrets.PYTEST_GITHUB_TOKEN }}
run: uv run pytest -m integration --junitxml=./reports/pytest.xml

- name: Upload test results
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,15 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

## [Unreleased]

### Added

- Added `skills` to `cloudsmith upstream`. Use `cloudsmith upstream skills list`, `create`, `update`, and `delete` to manage AI Skills upstreams. An AI Skills upstream caches skills and plugins from a GitHub repository.

### Changed

- After a SAML login, `cloudsmith auth` saves the Workspace to `config.ini`. It writes to the `[profile:NAME]` section of the selected profile, or to `[default]` when you do not select a profile. The CLI writes to the file or directory that `--config-file` gives, or else to your user-level `config.ini`. If the `config.ini` does not exist, the CLI creates it.
- Using `#!/usr/bin/env sh` as shebang path for unix credential helpers.
- The minimum version of `cloudsmith-api` is now 2.0.42.

### Fixed

Expand Down
1 change: 1 addition & 0 deletions cloudsmith_cli/cli/commands/upstream.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"python",
"rpm",
"ruby",
"skills",
Comment thread
pmcguckin-cloudsmith marked this conversation as resolved.
Resolved
"swift",
]

Expand Down
14 changes: 12 additions & 2 deletions cloudsmith_cli/cli/tests/commands/test_upstream.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from ..utils import random_str

#: The canonical public upstream for each format. These are already indexed,
#: so the API validates them quickly, and none needs credentials. The API
#: so the API validates them quickly, and only skills (GitHub) takes a token. The API
#: strips trailing slashes, so none is written with one. Formats without a
#: single canonical source (generic, swift) use a small placeholder page.
UPSTREAM_URLS = {
Expand All @@ -29,6 +29,7 @@
"python": "https://pypi.org",
"rpm": "https://archives.fedoraproject.org/pub/archive/fedora/linux/releases/35/Everything/x86_64/os",
"ruby": "https://rubygems.org",
"skills": "https://github.com/anthropics/claude-plugins-official",
"swift": "https://example.org",
}

Expand All @@ -51,7 +52,7 @@ def assert_succeeded(result):
@pytest.mark.integration
@pytest.mark.parametrize("upstream_format", UPSTREAM_FORMATS)
def test_upstream_commands(
runner, organization, upstream_format, tmp_repository, tmp_path
request, runner, organization, upstream_format, tmp_repository, tmp_path
):
upstream_config = {
# "name" and "upstream_url" are the only required properties for most formats.
Expand All @@ -63,6 +64,15 @@ def test_upstream_commands(
"distro_versions": ["ubuntu/xenial"],
}

# Skills specific arguments
if upstream_format == "skills":
# This GitHub host only offers skills and plugins together.
upstream_config["contents"] = "Skills and plugins"
upstream_config["mode"] = "Cache Only"
# Requested here rather than as a parameter so only skills skips without it.
upstream_config["auth_mode"] = "Token"
upstream_config["auth_secret"] = request.getfixturevalue("github_token")

upstream_config_file = tmp_path / (f"cli-test-upstream-{upstream_format}.json")
upstream_config_file.write_text(str(json.dumps(upstream_config)))

Expand Down
6 changes: 6 additions & 0 deletions cloudsmith_cli/cli/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ def api_key():
return _get_env_var_or_skip("PYTEST_CLOUDSMITH_API_KEY")


@pytest.fixture()
def github_token():
"""Return the PYTEST_GITHUB_TOKEN value."""
return _get_env_var_or_skip("PYTEST_GITHUB_TOKEN")


@pytest.fixture()
def organization():
"""Return the PYTEST_CLOUDSMITH_ORGANIZATION value.
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ dependencies = [
"click-didyoumean>=0.0.3",
"click-spinner>=0.1.7",
"json5>=0.9.0", # For parsing JSONC (JSON with comments) in VS Code settings
"cloudsmith-api>=2.0.38,<3.0", # Compatible up to (but excluding) 3.0+
"cloudsmith-api>=2.0.42,<3.0", # Compatible up to (but excluding) 3.0+
"keyring>=25.4.1",
"keyrings-alt>=5.0.2",
"keyrings-cryptfile>=1.3.9",
Expand Down
8 changes: 4 additions & 4 deletions uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading