Use deployment group id instead of name for deploy via CLI (#3037)

This commit is contained in:
Hugo Baraúna 2025-08-01 15:34:59 -03:00 committed by GitHub
parent a9c360ee9d
commit 8c6089fccb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 62 additions and 46 deletions

View file

@ -264,10 +264,14 @@ defmodule Livebook.Teams do
@doc """ @doc """
Deploys the given app deployment to given deployment group using a deploy key. Deploys the given app deployment to given deployment group using a deploy key.
""" """
@spec deploy_app_from_cli(Team.t(), Teams.AppDeployment.t(), String.t()) :: @spec deploy_app_from_cli(Team.t(), Teams.AppDeployment.t(), integer()) ::
{:ok, String.t()} | {:error, map()} | {:transport_error, String.t()} {:ok, String.t()} | {:error, map()} | {:transport_error, String.t()}
def deploy_app_from_cli(%Team{} = team, %Teams.AppDeployment{} = app_deployment, name) do def deploy_app_from_cli(
case Requests.deploy_app_from_cli(team, app_deployment, name) do %Team{} = team,
%Teams.AppDeployment{} = app_deployment,
deployment_group_id
) do
case Requests.deploy_app_from_cli(team, app_deployment, deployment_group_id) do
{:ok, %{"url" => url}} -> {:ok, url} {:ok, %{"url" => url}} -> {:ok, url}
{:error, %{"errors" => errors}} -> {:error, errors} {:error, %{"errors" => errors}} -> {:error, errors}
any -> any any -> any

View file

@ -239,8 +239,8 @@ defmodule Livebook.Teams.Requests do
@doc """ @doc """
Send a request to Livebook Team API to deploy an app using a deploy key. Send a request to Livebook Team API to deploy an app using a deploy key.
""" """
@spec deploy_app_from_cli(Team.t(), Teams.AppDeployment.t(), String.t()) :: api_result() @spec deploy_app_from_cli(Team.t(), Teams.AppDeployment.t(), integer()) :: api_result()
def deploy_app_from_cli(team, app_deployment, deployment_group_name) do def deploy_app_from_cli(team, app_deployment, deployment_group_id) do
secret_key = Teams.derive_key(team.teams_key) secret_key = Teams.derive_key(team.teams_key)
params = %{ params = %{
@ -248,7 +248,7 @@ defmodule Livebook.Teams.Requests do
slug: app_deployment.slug, slug: app_deployment.slug,
multi_session: app_deployment.multi_session, multi_session: app_deployment.multi_session,
access_type: app_deployment.access_type, access_type: app_deployment.access_type,
deployment_group_name: deployment_group_name, deployment_group_id: deployment_group_id,
sha: app_deployment.sha sha: app_deployment.sha
} }

View file

@ -14,9 +14,9 @@ defmodule LivebookCLI.Deploy do
## Available options ## Available options
--deploy-key Deploy key from your Livebook Teams organization --deploy-key Deploy key from your Livebook Teams organization
--teams-key Teams key from your Teams workspace --teams-key Teams key from your Teams workspace
--deployment-group The deployment group name which you want to deploy to --deployment-group-id The ID of the deployment group you want to deploy to
The --help option can be given to print this notice. The --help option can be given to print this notice.
@ -24,18 +24,18 @@ defmodule LivebookCLI.Deploy do
Deploys a single notebook: Deploys a single notebook:
livebook deploy --deploy-key="lb_dk_..." --teams-key="lb_tk_..." --deployment-group="production" path/to/app1.livemd livebook deploy --deploy-key="lb_dk_..." --teams-key="lb_tk_..." --deployment-group-id=123 path/to/app1.livemd
Deploys multiple notebooks: Deploys multiple notebooks:
livebook deploy --deploy-key="lb_dk_..." --teams-key="lb_tk_..." --deployment-group="production" path/to/*.livemd\ livebook deploy --deploy-key="lb_dk_..." --teams-key="lb_tk_..." --deployment-group-id=123 path/to/*.livemd\
""" """
end end
@switches [ @switches [
deploy_key: :string, deploy_key: :string,
teams_key: :string, teams_key: :string,
deployment_group: :string deployment_group_id: :integer
] ]
@impl true @impl true
@ -56,7 +56,7 @@ defmodule LivebookCLI.Deploy do
paths: paths, paths: paths,
session_token: opts[:deploy_key], session_token: opts[:deploy_key],
teams_key: opts[:teams_key], teams_key: opts[:teams_key],
deployment_group: opts[:deployment_group] deployment_group_id: opts[:deployment_group_id]
} }
end end
@ -139,10 +139,13 @@ defmodule LivebookCLI.Deploy do
with {:ok, content} <- File.read(path), with {:ok, content} <- File.read(path),
{:ok, app_deployment} <- prepare_app_deployment(path, content, files_dir) do {:ok, app_deployment} <- prepare_app_deployment(path, content, files_dir) do
case Livebook.Teams.deploy_app_from_cli(team, app_deployment, config.deployment_group) do case Livebook.Teams.deploy_app_from_cli(
team,
app_deployment,
config.deployment_group_id
) do
{:ok, url} -> {:ok, url} ->
log_info([:green, " * #{app_deployment.title} deployed successfully. (#{url})"]) log_info([:green, " * #{app_deployment.title} deployed successfully. (#{url})"])
:ok
{:error, errors} -> {:error, errors} ->
log_error(" * #{app_deployment.title} failed to deploy.") log_error(" * #{app_deployment.title} failed to deploy.")
@ -208,7 +211,8 @@ defmodule LivebookCLI.Deploy do
defp normalize_key(key) when is_atom(key), do: to_string(key) |> normalize_key() defp normalize_key(key) when is_atom(key), do: to_string(key) |> normalize_key()
defp normalize_key("session_token"), do: "Deploy Key" defp normalize_key("session_token"), do: "Deploy Key"
defp normalize_key("teams_key"), do: "Teams Key" defp normalize_key("teams_key"), do: "Teams Key"
defp normalize_key("deployment_group"), do: "Deployment Group" defp normalize_key("deployment_group_id"), do: "Deployment Group ID"
defp normalize_key("paths"), do: "File Paths" defp normalize_key("paths"), do: "File Paths"
defp format_errors(errors, prefix) do defp format_errors(errors, prefix) do

View file

@ -43,7 +43,7 @@ defmodule LivebookCLI.Integration.DeployTest do
assert deploy( assert deploy(
key, key,
team.teams_key, team.teams_key,
deployment_group.name, deployment_group.id,
app_path app_path
) == :ok ) == :ok
end) end)
@ -92,7 +92,7 @@ defmodule LivebookCLI.Integration.DeployTest do
assert deploy( assert deploy(
key, key,
team.teams_key, team.teams_key,
deployment_group.name, deployment_group.id,
Path.join(tmp_dir, "*.livemd") Path.join(tmp_dir, "*.livemd")
) == :ok ) == :ok
end) end)
@ -127,7 +127,7 @@ defmodule LivebookCLI.Integration.DeployTest do
deploy( deploy(
"invalid_key", "invalid_key",
team.teams_key, team.teams_key,
deployment_group.name, deployment_group.id,
app_path app_path
) )
end end
@ -149,7 +149,7 @@ defmodule LivebookCLI.Integration.DeployTest do
deploy( deploy(
key, key,
"invalid-key", "invalid-key",
deployment_group.name, deployment_group.id,
app_path app_path
) )
end end
@ -167,14 +167,16 @@ defmodule LivebookCLI.Integration.DeployTest do
# Test App # Test App
""") """)
assert_raise LivebookCLI.Error, ~r/Deployment Group can't be blank/s, fn -> assert_raise OptionParser.ParseError,
deploy( ~r/--deployment-group-id : Expected type integer, got ""/s,
key, fn ->
team.teams_key, deploy(
"", key,
app_path team.teams_key,
) "",
end app_path
)
end
end end
test "fails with invalid deployment group", test "fails with invalid deployment group",
@ -201,17 +203,17 @@ defmodule LivebookCLI.Integration.DeployTest do
output = output =
ExUnit.CaptureIO.capture_io(fn -> ExUnit.CaptureIO.capture_io(fn ->
assert_raise LivebookCLI.Error, "Some app deployments failed.", fn -> assert_raise(LivebookCLI.Error, ~r/Some app deployments failed./s, fn ->
deploy( deploy(
key, key,
team.teams_key, team.teams_key,
Utils.random_short_id(), 999_999,
app_path app_path
) )
end end)
end) end)
assert output =~ ~r/Deployment Group does not exist/ assert output =~ ~r/Deployment Group ID does not exist/
refute_receive {:app_deployment_started, refute_receive {:app_deployment_started,
%{ %{
@ -231,7 +233,7 @@ defmodule LivebookCLI.Integration.DeployTest do
deploy( deploy(
key, key,
team.teams_key, team.teams_key,
deployment_group.name, deployment_group.id,
Path.join(tmp_dir, "app.livemd") Path.join(tmp_dir, "app.livemd")
) )
end end
@ -245,7 +247,7 @@ defmodule LivebookCLI.Integration.DeployTest do
deploy( deploy(
key, key,
team.teams_key, team.teams_key,
deployment_group.name, deployment_group.id,
tmp_dir tmp_dir
) )
end end
@ -293,7 +295,7 @@ defmodule LivebookCLI.Integration.DeployTest do
deploy( deploy(
deploy_key, deploy_key,
team.teams_key, team.teams_key,
deployment_group.name, deployment_group.id,
[invalid_app_path, valid_app_path] [invalid_app_path, valid_app_path]
) )
end) end)
@ -322,7 +324,7 @@ defmodule LivebookCLI.Integration.DeployTest do
end end
end end
defp deploy(deploy_key, teams_key, deployment_group_name, path) do defp deploy(deploy_key, teams_key, deployment_group_id, path) do
paths = paths =
if is_list(path) do if is_list(path) do
path path
@ -334,14 +336,20 @@ defmodule LivebookCLI.Integration.DeployTest do
end end
end end
deployment_group_id =
cond do
deployment_group_id == "" -> ""
true -> Integer.to_string(deployment_group_id)
end
LivebookCLI.Deploy.call( LivebookCLI.Deploy.call(
[ [
"--deploy-key", "--deploy-key",
deploy_key, deploy_key,
"--teams-key", "--teams-key",
teams_key, teams_key,
"--deployment-group", "--deployment-group-id",
deployment_group_name deployment_group_id
] ++ paths ] ++ paths
) )
end end

View file

@ -304,7 +304,7 @@ defmodule Livebook.TeamsTest do
@tag :tmp_dir @tag :tmp_dir
test "deploys app to Teams using a CLI session", test "deploys app to Teams using a CLI session",
%{team: team, node: node, tmp_dir: tmp_dir, org: org} do %{team: team, node: node, tmp_dir: tmp_dir, org: org} do
%{id: id, name: name} = %{id: id} =
TeamsRPC.create_deployment_group(node, TeamsRPC.create_deployment_group(node,
name: "angry-cat-#{Ecto.UUID.generate()}", name: "angry-cat-#{Ecto.UUID.generate()}",
url: "http://localhost:4123", url: "http://localhost:4123",
@ -337,7 +337,7 @@ defmodule Livebook.TeamsTest do
assert {:ok, team} = Teams.fetch_cli_session(config) assert {:ok, team} = Teams.fetch_cli_session(config)
# deploy the app # deploy the app
assert {:ok, _url} = Teams.deploy_app_from_cli(team, app_deployment, name) assert {:ok, _url} = Teams.deploy_app_from_cli(team, app_deployment, id)
sha = app_deployment.sha sha = app_deployment.sha
multi_session = app_settings.multi_session multi_session = app_settings.multi_session
@ -354,19 +354,19 @@ defmodule Livebook.TeamsTest do
deployment_group_id: ^id deployment_group_id: ^id
} = app_deployment2} } = app_deployment2}
assert Teams.deploy_app_from_cli(team, app_deployment, "foo") == assert Teams.deploy_app_from_cli(team, app_deployment, 999) ==
{:error, %{"deployment_group" => ["does not exist"]}} {:error, %{"deployment_group_id" => ["does not exist"]}}
assert Teams.deploy_app_from_cli(team, %{app_deployment | slug: "@abc"}, name) == assert Teams.deploy_app_from_cli(team, %{app_deployment | slug: "@abc"}, id) ==
{:error, %{"slug" => ["should only contain alphanumeric characters and dashes"]}} {:error, %{"slug" => ["should only contain alphanumeric characters and dashes"]}}
assert Teams.deploy_app_from_cli(team, %{app_deployment | multi_session: nil}, name) == assert Teams.deploy_app_from_cli(team, %{app_deployment | multi_session: nil}, id) ==
{:error, %{"multi_session" => ["can't be blank"]}} {:error, %{"multi_session" => ["can't be blank"]}}
assert Teams.deploy_app_from_cli(team, %{app_deployment | access_type: nil}, name) == assert Teams.deploy_app_from_cli(team, %{app_deployment | access_type: nil}, id) ==
{:error, %{"access_type" => ["can't be blank"]}} {:error, %{"access_type" => ["can't be blank"]}}
assert Teams.deploy_app_from_cli(team, %{app_deployment | access_type: :abc}, name) == assert Teams.deploy_app_from_cli(team, %{app_deployment | access_type: :abc}, id) ==
{:error, %{"access_type" => ["is invalid"]}} {:error, %{"access_type" => ["is invalid"]}}
# force app deployment to be stopped # force app deployment to be stopped