mirror of
https://github.com/livebook-dev/livebook.git
synced 2025-09-05 04:24:21 +08:00
Merge branch 'main' into hb-deploy-cli-dg-id-instead-name
This commit is contained in:
commit
886df60786
3 changed files with 132 additions and 39 deletions
|
@ -132,9 +132,10 @@ defmodule LivebookCLI.Deploy do
|
|||
|
||||
log_info("Deploying notebooks:")
|
||||
|
||||
for path <- config.paths do
|
||||
log_info(" * Preparing to deploy notebook #{Path.basename(path)}")
|
||||
files_dir = Livebook.FileSystem.File.local(path)
|
||||
deploy_results =
|
||||
for path <- config.paths do
|
||||
log_info(" * Preparing to deploy notebook #{Path.basename(path)}")
|
||||
files_dir = Livebook.FileSystem.File.local(path)
|
||||
|
||||
with {:ok, content} <- File.read(path),
|
||||
{:ok, app_deployment} <- prepare_app_deployment(path, content, files_dir) do
|
||||
|
@ -142,24 +143,33 @@ defmodule LivebookCLI.Deploy do
|
|||
{:ok, url} ->
|
||||
log_info([:green, " * #{app_deployment.title} deployed successfully. (#{url})"])
|
||||
|
||||
{:error, errors} ->
|
||||
log_error(" * #{app_deployment.title} failed to deploy.")
|
||||
errors = normalize_errors(errors)
|
||||
{:error, errors} ->
|
||||
log_error(" * #{app_deployment.title} failed to deploy.")
|
||||
|
||||
raise LivebookCLI.Error, """
|
||||
#{format_errors(errors, " * ")}
|
||||
error_message =
|
||||
errors
|
||||
|> normalize_errors
|
||||
|> format_errors(" * ")
|
||||
|
||||
#{Teams.Requests.error_message()}\
|
||||
"""
|
||||
log_error(error_message)
|
||||
|
||||
{:transport_error, reason} ->
|
||||
log_error(" * #{app_deployment.title} failed to deploy.")
|
||||
raise LivebookCLI.Error, reason
|
||||
:error
|
||||
|
||||
{:transport_error, reason} ->
|
||||
log_error(
|
||||
" * #{app_deployment.title} failed to deploy. Transport error: #{reason}"
|
||||
)
|
||||
|
||||
:error
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
:ok
|
||||
if Enum.any?(deploy_results, fn result -> result != :ok end) do
|
||||
raise LivebookCLI.Error, "Some app deployments failed."
|
||||
else
|
||||
:ok
|
||||
end
|
||||
end
|
||||
|
||||
defp prepare_app_deployment(path, content, files_dir) do
|
||||
|
@ -168,13 +178,19 @@ defmodule LivebookCLI.Deploy do
|
|||
{:ok, app_deployment}
|
||||
|
||||
{:warning, warnings} ->
|
||||
raise LivebookCLI.Error, """
|
||||
Deployment for notebook #{Path.basename(path)} failed because the notebook has some warnings:
|
||||
#{format_list(warnings, " * ")}
|
||||
error_message = """
|
||||
* Deployment for notebook #{Path.basename(path)} failed because the notebook has some warnings:
|
||||
#{format_list(warnings, " * ")}
|
||||
"""
|
||||
|
||||
log_error(error_message)
|
||||
|
||||
:error
|
||||
|
||||
{:error, reason} ->
|
||||
raise LivebookCLI.Error, "Failed to handle I/O operations: #{reason}"
|
||||
log_error(" * Failed to handle I/O operations: #{reason}")
|
||||
|
||||
:error
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -201,16 +201,19 @@ defmodule LivebookCLI.Integration.DeployTest do
|
|||
```
|
||||
""")
|
||||
|
||||
assert_raise LivebookCLI.Error, ~r/Deployment Group ID does not exist/s, fn ->
|
||||
output =
|
||||
ExUnit.CaptureIO.capture_io(fn ->
|
||||
deploy(
|
||||
key,
|
||||
team.teams_key,
|
||||
999_999,
|
||||
app_path
|
||||
)
|
||||
assert_raise(LivebookCLI.Error, ~r/Some app deployments failed./s, fn ->
|
||||
deploy(
|
||||
key,
|
||||
team.teams_key,
|
||||
999_999,
|
||||
app_path
|
||||
)
|
||||
end)
|
||||
end)
|
||||
end
|
||||
|
||||
assert output =~ ~r/Deployment Group ID does not exist/
|
||||
|
||||
refute_receive {:app_deployment_started,
|
||||
%{
|
||||
|
@ -249,14 +252,88 @@ defmodule LivebookCLI.Integration.DeployTest do
|
|||
)
|
||||
end
|
||||
end
|
||||
|
||||
test "handles partial failure when deploying multiple notebooks",
|
||||
%{team: team, node: node, org: org, tmp_dir: tmp_dir} do
|
||||
{deploy_key, _} = TeamsRPC.create_deploy_key(node, org: org)
|
||||
deployment_group = TeamsRPC.create_deployment_group(node, org: org, url: @url)
|
||||
hub_id = team.id
|
||||
|
||||
# Notebook without app settings (deploymeny should fail)
|
||||
invalid_title = "Invalid App"
|
||||
invalid_slug = "invalid-#{Utils.random_short_id()}"
|
||||
invalid_app_path = Path.join(tmp_dir, "#{invalid_slug}.livemd")
|
||||
|
||||
File.write!(invalid_app_path, """
|
||||
<!-- livebook:{"hub_id":"#{hub_id}"} -->
|
||||
|
||||
# #{invalid_title}
|
||||
|
||||
```elixir
|
||||
1 + 1
|
||||
```
|
||||
""")
|
||||
|
||||
# Second notebook should succeed
|
||||
valid_title = "Valid App"
|
||||
valid_slug = "valid-#{Utils.random_short_id()}"
|
||||
valid_app_path = Path.join(tmp_dir, "#{valid_slug}.livemd")
|
||||
|
||||
stamp_notebook(valid_app_path, """
|
||||
<!-- livebook:{"app_settings":{"access_type":"public","slug":"#{valid_slug}"},"hub_id":"#{hub_id}"} -->
|
||||
|
||||
# #{valid_title}
|
||||
|
||||
```elixir
|
||||
1 + 1
|
||||
```
|
||||
""")
|
||||
|
||||
output =
|
||||
ExUnit.CaptureIO.capture_io(fn ->
|
||||
assert_raise(LivebookCLI.Error, "Some app deployments failed.", fn ->
|
||||
deploy(
|
||||
deploy_key,
|
||||
team.teams_key,
|
||||
deployment_group.id,
|
||||
[invalid_app_path, valid_app_path]
|
||||
)
|
||||
end)
|
||||
end)
|
||||
|
||||
# The valid notebook should have been deployed successfully
|
||||
assert output =~
|
||||
"#{valid_title} deployed successfully. (#{@url}/apps/#{valid_slug})"
|
||||
|
||||
deployment_group_id = to_string(deployment_group.id)
|
||||
|
||||
assert_receive {:app_deployment_started,
|
||||
%{
|
||||
title: ^valid_title,
|
||||
slug: ^valid_slug,
|
||||
deployment_group_id: ^deployment_group_id,
|
||||
hub_id: ^hub_id,
|
||||
deployed_by: "CLI"
|
||||
}}
|
||||
|
||||
# And deployment of the invalide notebook shows an error message
|
||||
invalid_app_filename = Path.basename(invalid_app_path)
|
||||
|
||||
assert output =~
|
||||
"Deployment for notebook #{invalid_app_filename} failed"
|
||||
end
|
||||
end
|
||||
|
||||
defp deploy(deploy_key, teams_key, deployment_group_id, path) do
|
||||
paths =
|
||||
case Path.wildcard(path) do
|
||||
[] -> [path]
|
||||
[path] -> [path]
|
||||
paths -> paths
|
||||
if is_list(path) do
|
||||
path
|
||||
else
|
||||
case Path.wildcard(path) do
|
||||
[] -> [path]
|
||||
[path] -> [path]
|
||||
paths -> paths
|
||||
end
|
||||
end
|
||||
|
||||
deployment_group_id =
|
||||
|
|
|
@ -304,7 +304,7 @@ defmodule Livebook.TeamsTest do
|
|||
@tag :tmp_dir
|
||||
test "deploys app to Teams using a CLI session",
|
||||
%{team: team, node: node, tmp_dir: tmp_dir, org: org} do
|
||||
%{id: id, name: name} =
|
||||
%{id: id} =
|
||||
TeamsRPC.create_deployment_group(node,
|
||||
name: "angry-cat-#{Ecto.UUID.generate()}",
|
||||
url: "http://localhost:4123",
|
||||
|
@ -337,7 +337,7 @@ defmodule Livebook.TeamsTest do
|
|||
assert {:ok, team} = Teams.fetch_cli_session(config)
|
||||
|
||||
# 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
|
||||
multi_session = app_settings.multi_session
|
||||
|
@ -354,19 +354,19 @@ defmodule Livebook.TeamsTest do
|
|||
deployment_group_id: ^id
|
||||
} = app_deployment2}
|
||||
|
||||
assert Teams.deploy_app_from_cli(team, app_deployment, "foo") ==
|
||||
{:error, %{"deployment_group" => ["does not exist"]}}
|
||||
assert Teams.deploy_app_from_cli(team, app_deployment, 999) ==
|
||||
{: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"]}}
|
||||
|
||||
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"]}}
|
||||
|
||||
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"]}}
|
||||
|
||||
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"]}}
|
||||
|
||||
# force app deployment to be stopped
|
||||
|
|
Loading…
Add table
Reference in a new issue