Skip to content
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Fixed

- Positional `apm install <url>` now exits non-zero when all packages fail
validation, matching manifest installs for reliable CI scripting. (#2131)
- Fresh checkouts with declared consumer targets no longer remain
`apm audit --ci`-red for files those targets cannot restore: `apm install`
now removes stale `deployed_files` entries outside the legitimate target
Expand Down
3 changes: 2 additions & 1 deletion src/apm_cli/commands/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -1530,7 +1530,8 @@ def install( # noqa: PLR0913
)
# Short-circuit: all packages failed validation -- nothing to install
if outcome.all_failed:
return
summary_rendered = True
sys.exit(1)
# Note: Empty validated_packages is OK if packages are already in apm.yml;
# only_packages is derived from validation outcomes below.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1056,8 +1056,8 @@ def test_install_package_validation_failure(self, runner: CliRunner, tmp_path: P
),
):
result = runner.invoke(cli, ["install", "owner/nonexistent"])
# All validations failed → exit
assert result.exit_code != 0 or "not accessible" in result.output
# All validations failed, so the command must report failure.
assert result.exit_code == 1


# ===========================================================================
Expand Down
11 changes: 11 additions & 0 deletions tests/unit/test_install_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,17 @@ def test_install_auto_created_apm_yml_has_correct_metadata(
assert "description" in config
assert "APM project" in config["description"]

@patch("apm_cli.commands.install._validate_package_exists", return_value=False)
def test_install_positional_url_total_validation_failure_exits_one(self, mock_validate):
"""A positional URL that cannot be validated must fail the command."""
with self._chdir_tmp():
result = self.runner.invoke(cli, ["install", "https://127.0.0.1:1/org/repo.git"])

assert result.exit_code == 1
assert "All packages failed validation" in result.output
assert "Install interrupted" not in result.output
mock_validate.assert_called()

@patch("apm_cli.commands.install._validate_package_exists")
def test_install_invalid_package_format_with_no_apm_yml(self, mock_validate):
"""Test that invalid package format fails gracefully even with auto-bootstrap."""
Expand Down
Loading