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
2 changes: 1 addition & 1 deletion .bumpversion.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 1.8.4
current_version = 1.8.6
commit = True
tag = True
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<revision>\d+)
Expand Down
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,17 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

## [Unreleased]

## [1.8.6] - 2025-10-16

### Added

- Added `--force` parameter to the Auth command to be used in conjunction with `--token` to refresh tokens without interactive prompts i.e automatic.
- Added `--force` parameter to the Tokens refresh command to automaticlly refresh without an interactive prompt.

## [1.8.5] - 2025-10-16

### Added

## [1.8.4] - 2025-10-06

### Added
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ RUN mkdir -p /opt/cloudsmith \
&& chmod +x /opt/cloudsmith/cloudsmith

# Default command
ENTRYPOINT [ "cloudsmith" ]
ENTRYPOINT [ "cloudsmith" ]
53 changes: 36 additions & 17 deletions cloudsmith_cli/cli/commands/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,18 @@
is_flag=True,
help="Retrieve a user API token after successful authentication.",
)
@click.option(
"-f",
"--force",
default=False,
is_flag=True,
help="Force refresh of user API token without prompts.",
)
@decorators.common_cli_config_options
@decorators.common_cli_output_options
@decorators.initialise_api
@click.pass_context
def authenticate(ctx, opts, owner, token):
def authenticate(ctx, opts, owner, token, force):
"""Authenticate to Cloudsmith using the org's SAML setup."""
owner = owner[0].strip("'[]'")
api_host = opts.api_config.host
Expand Down Expand Up @@ -75,18 +82,22 @@ def authenticate(ctx, opts, owner, token):
try:
api_token = user.create_user_token_saml()
click.echo(f"New token value: {click.style(api_token.key, fg='magenta')}")
create, has_errors = create_config_files(ctx, opts, api_key=api_token.key)
new_config_messaging(has_errors, opts, create, api_key=api_token.key)
return

if not token:
create, has_errors = create_config_files(
ctx, opts, api_key=api_token.key
)
new_config_messaging(has_errors, opts, create, api_key=api_token.key)
except exceptions.ApiException as exc:
if exc.status == 400:
if "User has already created an API key" in exc.detail:
click.confirm(
"User already has a token. Would you like to recreate it?",
abort=True,
)
else:
raise
if not force:
if "User has already created an API key" in exc.detail:
click.confirm(
"User already has a token. Would you like to recreate it?",
abort=True,
)
else:
raise

context_msg = "Failed to refresh the token!"
with handle_api_exceptions(ctx, opts=opts, context_msg=context_msg):
Expand All @@ -98,15 +109,23 @@ def authenticate(ctx, opts, owner, token):
f"Created: {click.style(t.created, fg='green')}, "
f"slug_perm: {click.style(t.slug_perm, fg='cyan')}"
)
token_slug = click.prompt(
"Please enter the slug_perm of the token you would like to refresh"
)

click.echo(f"Refreshing token {token_slug}... ", nl=False)
if not force:
token_slug = click.prompt(
"Please enter the slug_perm of the token you would like to refresh"
)
click.echo(f"Refreshing token {token_slug}... ", nl=False)
else:
# Use the first available slug_perm for simplicity
token_slug = api_tokens[0].slug_perm
click.echo(f"Refreshing token {token_slug}... ", nl=False)

with handle_api_exceptions(ctx, opts=opts, context_msg=context_msg):
with maybe_spinner(opts):
new_token = user.refresh_user_token(token_slug)
click.secho("OK", fg="green")
click.echo(f"New token value: {click.style(new_token.key, fg='magenta')}")
create, has_errors = create_config_files(ctx, opts, api_key=new_token.key)
new_config_messaging(has_errors, opts, create, api_key=new_token.key)

if not force:
create, has_errors = create_config_files(ctx, opts, api_key=new_token.key)
new_config_messaging(has_errors, opts, create, api_key=new_token.key)
20 changes: 16 additions & 4 deletions cloudsmith_cli/cli/commands/tokens.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,19 @@ def list_tokens(ctx, opts):
"token_slug",
required=False,
)
@click.option(
"-f",
"--force",
default=False,
is_flag=True,
help="Force refresh of user API token without prompts.",
)
@decorators.common_cli_config_options
@decorators.common_cli_output_options
@decorators.common_api_auth_options
@decorators.initialise_api
@click.pass_context
def refresh(ctx, opts, token_slug):
def refresh(ctx, opts, token_slug, force):
"""Refresh a specific API token by its slug."""
context_msg = "Failed to refresh the token!"

Expand All @@ -59,9 +66,14 @@ def refresh(ctx, opts, token_slug):
api_tokens = api.list_user_tokens()
click.echo("Current tokens:")
print_tokens(api_tokens)
token_slug = click.prompt(
"Please enter the slug_perm of the token you would like to refresh"
)
if not force:
token_slug = click.prompt(
"Please enter the slug_perm of the token you would like to refresh"
)
else:
# Use the first available slug_perm for simplicity
token_slug = api_tokens[0].slug_perm
click.echo(f"Refreshing token {token_slug}... ", nl=False)

click.echo(f"Refreshing token {token_slug}... ", nl=False)
with handle_api_exceptions(ctx, opts=opts, context_msg=context_msg):
Expand Down
2 changes: 1 addition & 1 deletion cloudsmith_cli/data/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.8.4
1.8.6