Skip to content

Commit

Permalink
Add snow app release-channel add-version and remove-version commands (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
sfc-gh-melnacouzi authored Dec 19, 2024
1 parent 3009e8b commit 1c2ef97
Show file tree
Hide file tree
Showing 9 changed files with 767 additions and 6 deletions.
12 changes: 7 additions & 5 deletions RELEASE-NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,17 @@
* Added deprecation message for default Streamlit warehouse

## New additions
* Add Release Directives support by introducing the following commands:
* Add support for Release Directives by introducing the following commands:
* `snow app release-directive list`
* `snow app release-directive set`
* `snow app release-directive unset`
* Add support for release channels feature in native app version creation/drop.
* `snow app version create` now returns version, patch, and label in JSON format.
* Add ability to specify release channel when creating application instance from release directive: `snow app run --from-release-directive --channel=<channel>`
* Add ability to list release channels through `snow app release-channel list` command
* Add ability to add and remove accounts from release channels through `snow app release-channel add-accounts` and snow app release-channel remove-accounts` commands.
* Add support for release channels:
* Add support for release channels feature in native app version creation/drop.
* Add ability to specify release channel when creating application instance from release directive: `snow app run --from-release-directive --channel=<channel>`
* Add ability to list release channels through `snow app release-channel list` command
* Add ability to add and remove accounts from release channels through `snow app release-channel add-accounts` and snow app release-channel remove-accounts` commands.
* Add ability to add/remove versions to/from release channels through `snow app release-channel add-version` and `snow app release-channel remove-version` commands.

## Fixes and improvements
* Fixed crashes with older x86_64 Intel CPUs.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -930,6 +930,46 @@ def action_release_channel_remove_accounts(
role=self.role,
)

def action_release_channel_add_version(
self,
action_ctx: ActionContext,
release_channel: str,
version: str,
*args,
**kwargs,
):
"""
Adds a version to a release channel.
"""

self.validate_release_channel(release_channel)
get_snowflake_facade().add_version_to_release_channel(
package_name=self.name,
release_channel=release_channel,
version=version,
role=self.role,
)

def action_release_channel_remove_version(
self,
action_ctx: ActionContext,
release_channel: str,
version: str,
*args,
**kwargs,
):
"""
Removes a version from a release channel.
"""

self.validate_release_channel(release_channel)
get_snowflake_facade().remove_version_from_release_channel(
package_name=self.name,
release_channel=release_channel,
version=version,
role=self.role,
)

def _bundle_children(self, action_ctx: ActionContext) -> List[str]:
# Create _children directory
children_artifacts_dir = self.children_artifacts_deploy_root
Expand Down
72 changes: 72 additions & 0 deletions src/snowflake/cli/_plugins/nativeapp/release_channel/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,3 +138,75 @@ def release_channel_remove_accounts(
)

return MessageResult("Successfully removed accounts from the release channel.")


@app.command("add-version", requires_connection=True)
@with_project_definition()
@force_project_definition_v2()
def release_channel_add_version(
channel: str = typer.Argument(
show_default=False,
help="The release channel to add a version to.",
),
version: str = typer.Option(
show_default=False,
help="The version to add to the release channel.",
),
**options,
) -> CommandResult:
"""
Adds a version to a release channel.
"""

cli_context = get_cli_context()
ws = WorkspaceManager(
project_definition=cli_context.project_definition,
project_root=cli_context.project_root,
)
package_id = options["package_entity_id"]
ws.perform_action(
package_id,
EntityActions.RELEASE_CHANNEL_ADD_VERSION,
release_channel=channel,
version=version,
)

return MessageResult(
f"Successfully added version {version} to the release channel."
)


@app.command("remove-version", requires_connection=True)
@with_project_definition()
@force_project_definition_v2()
def release_channel_remove_version(
channel: str = typer.Argument(
show_default=False,
help="The release channel to remove a version from.",
),
version: str = typer.Option(
show_default=False,
help="The version to remove from the release channel.",
),
**options,
) -> CommandResult:
"""
Removes a version from a release channel.
"""

cli_context = get_cli_context()
ws = WorkspaceManager(
project_definition=cli_context.project_definition,
project_root=cli_context.project_root,
)
package_id = options["package_entity_id"]
ws.perform_action(
package_id,
EntityActions.RELEASE_CHANNEL_REMOVE_VERSION,
release_channel=channel,
version=version,
)

return MessageResult(
f"Successfully removed version {version} from the release channel."
)
88 changes: 88 additions & 0 deletions src/snowflake/cli/_plugins/nativeapp/sf_sql_facade.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,16 @@
DOES_NOT_EXIST_OR_CANNOT_BE_PERFORMED,
DOES_NOT_EXIST_OR_NOT_AUTHORIZED,
INSUFFICIENT_PRIVILEGES,
MAX_VERSIONS_IN_RELEASE_CHANNEL_REACHED,
NO_WAREHOUSE_SELECTED_IN_SESSION,
RELEASE_DIRECTIVE_DOES_NOT_EXIST,
RELEASE_DIRECTIVES_VERSION_PATCH_NOT_FOUND,
SQL_COMPILATION_ERROR,
VERSION_ALREADY_ADDED_TO_RELEASE_CHANNEL,
VERSION_DOES_NOT_EXIST,
VERSION_NOT_ADDED_TO_RELEASE_CHANNEL,
VERSION_NOT_IN_RELEASE_CHANNEL,
VERSION_REFERENCED_BY_RELEASE_DIRECTIVE,
)
from snowflake.cli.api.identifiers import FQN
from snowflake.cli.api.metrics import CLICounterField
Expand Down Expand Up @@ -1302,6 +1306,90 @@ def remove_accounts_from_release_channel(
f"Failed to remove accounts from release channel {release_channel} in application package {package_name}.",
)

def add_version_to_release_channel(
self,
package_name: str,
release_channel: str,
version: str,
role: str | None = None,
):
"""
Adds a version to a release channel.
@param package_name: Name of the application package
@param release_channel: Name of the release channel
@param version: Version to add to the release channel
@param [Optional] role: Role to switch to while running this script. Current role will be used if no role is passed in.
"""

package_name = to_identifier(package_name)
release_channel = to_identifier(release_channel)
version = to_identifier(version)

with self._use_role_optional(role):
try:
self._sql_executor.execute_query(
f"alter application package {package_name} modify release channel {release_channel} add version {version}"
)
except Exception as err:
if isinstance(err, ProgrammingError):
if err.errno == VERSION_DOES_NOT_EXIST:
raise UserInputError(
f"Version {version} does not exist in application package {package_name}."
) from err
if err.errno == VERSION_ALREADY_ADDED_TO_RELEASE_CHANNEL:
raise UserInputError(
f"Version {version} is already added to release channel {release_channel}."
) from err
if err.errno == MAX_VERSIONS_IN_RELEASE_CHANNEL_REACHED:
raise UserInputError(
f"Maximum number of versions allowed in release channel {release_channel} has been reached."
) from err
handle_unclassified_error(
err,
f"Failed to add version {version} to release channel {release_channel} in application package {package_name}.",
)

def remove_version_from_release_channel(
self,
package_name: str,
release_channel: str,
version: str,
role: str | None = None,
):
"""
Removes a version from a release channel.
@param package_name: Name of the application package
@param release_channel: Name of the release channel
@param version: Version to remove from the release channel
@param [Optional] role: Role to switch to while running this script. Current role will be used if no role is passed in.
"""

package_name = to_identifier(package_name)
release_channel = to_identifier(release_channel)
version = to_identifier(version)

with self._use_role_optional(role):
try:
self._sql_executor.execute_query(
f"alter application package {package_name} modify release channel {release_channel} drop version {version}"
)
except Exception as err:
if isinstance(err, ProgrammingError):
if err.errno == VERSION_NOT_IN_RELEASE_CHANNEL:
raise UserInputError(
f"Version {version} is not found in release channel {release_channel}."
) from err
if err.errno == VERSION_REFERENCED_BY_RELEASE_DIRECTIVE:
raise UserInputError(
f"Cannot remove version {version} from release channel {release_channel} as it is referenced by a release directive."
) from err
handle_unclassified_error(
err,
f"Failed to remove version {version} from release channel {release_channel} in application package {package_name}.",
)


def _strip_empty_lines(text: str) -> str:
"""
Expand Down
5 changes: 4 additions & 1 deletion src/snowflake/cli/api/errno.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
APPLICATION_INSTANCE_FAILED_TO_RUN_SETUP_SCRIPT = 93082
APPLICATION_INSTANCE_NO_ACTIVE_WAREHOUSE_FOR_CREATE_OR_UPGRADE = 93083
APPLICATION_INSTANCE_EMPTY_SETUP_SCRIPT = 93084
APPLICATION_PACKAGE_CANNOT_DROP_VERSION_IF_IT_IS_IN_USE = 93088
VERSION_REFERENCED_BY_RELEASE_DIRECTIVE = 93088
APPLICATION_PACKAGE_MANIFEST_CONTAINER_IMAGE_URL_BAD_VALUE = 93148
CANNOT_GRANT_NON_MANIFEST_PRIVILEGE = 93118
APPLICATION_OWNS_EXTERNAL_OBJECTS = 93128
Expand All @@ -66,9 +66,12 @@
RELEASE_DIRECTIVES_VERSION_PATCH_NOT_FOUND = 93036
RELEASE_DIRECTIVE_DOES_NOT_EXIST = 93090
VERSION_DOES_NOT_EXIST = 93031
VERSION_NOT_IN_RELEASE_CHANNEL = 512010
ACCOUNT_DOES_NOT_EXIST = 1999
ACCOUNT_HAS_TOO_MANY_QUALIFIERS = 906
CANNOT_MODIFY_RELEASE_CHANNEL_ACCOUNTS = 512017
VERSION_ALREADY_ADDED_TO_RELEASE_CHANNEL = 512005
MAX_VERSIONS_IN_RELEASE_CHANNEL_REACHED = 512004

ERR_JAVASCRIPT_EXECUTION = 100132

Expand Down
Loading

0 comments on commit 1c2ef97

Please sign in to comment.