Skip to content
Closed
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
3 changes: 3 additions & 0 deletions crates/tower-cmd/src/package.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,17 +58,20 @@ pub async fn do_package(out: &crate::output::Out, _config: Config, args: &ArgMat
}
Err(err) => {
out.error(&format!("Failed to save package: {}", err));
std::process::exit(1);
}
}
}
Err(err) => {
spinner.failure(out);
out.package_error(err);
std::process::exit(1);
}
}
}
Err(err) => {
out.package_error(err);
std::process::exit(1);
}
}
}
Expand Down
21 changes: 21 additions & 0 deletions tests/integration/features/cli_package.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
Feature: CLI Package
As a developer scripting against the Tower CLI
I want `tower package` to exit non-zero when it cannot build a package
So that a broken Towerfile fails my pipeline instead of passing silently

Scenario: Packaging a Towerfile with no script fails loudly
Given I have a Towerfile that is missing its script
When I run "tower package -d . -o pkg.tar.gz" via CLI
Then the command should exit with a non-zero status
And the output should show "script"

Scenario: Packaging without any Towerfile fails loudly
When I run "tower package -d . -o pkg.tar.gz" via CLI
Then the command should exit with a non-zero status
And the output should show "Towerfile"

Scenario: Packaging a valid app succeeds
Given I have a valid Towerfile in the current directory
When I run "tower package -d . -o pkg.tar.gz" via CLI
Then the command should exit with status 0
And the output should show "Package created successfully"
21 changes: 21 additions & 0 deletions tests/integration/features/steps/cli_steps.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,27 @@ def step_run_cli_command(context, command):
return run_command_with_env(context, command, test_env)


@given("I have a Towerfile that is missing its script")
def step_create_towerfile_missing_script(context):
# Deliberately invalid: `script` is required. Used to check that commands
# fail loudly rather than printing an error and exiting 0.
Path("Towerfile").write_text('[app]\nname = "broken-app"\n')


@then("the command should exit with a non-zero status")
def step_check_nonzero_exit(context):
assert (
context.cli_return_code != 0
), f"Expected a non-zero exit, got {context.cli_return_code}. Output: {context.cli_output}"


@then("the command should exit with status 0")
def step_check_zero_exit(context):
assert (
context.cli_return_code == 0
), f"Expected exit 0, got {context.cli_return_code}. Output: {context.cli_output}"


@step('I run "{command}" via CLI with API key')
def step_run_cli_command_with_api_key(context, command):
"""Run a Tower CLI command authenticating via TOWER_API_KEY instead of session.json"""
Expand Down
Loading