apple / apple/container

[Request]: Add a `container upgrade` command

Open
#1,942 2 comments 7 reactions 0 assignees View on GitHub
Dominant language
Swift
Stars
49.9k
Forks
1.8k
Avg merge
1d 20h
Merged PRs (30d)
22

Description

### Feature or enhancement request details

Today, upgrading an installed `container` toolset requires running the `update-container.sh` shell script that ships in `/usr/local/bin`. The script works well, but as a separate script it is not discoverable from the CLI itself (`container --help` gives no hint that an updater exists), it depends on `jq`-style text processing, and its logic cannot be unit tested.

I would like to contribute a native, top-level `container upgrade` command that replicates the script's behavior exactly:

```
container upgrade # upgrade to the latest GitHub release
container upgrade -v 0.6.0 # upgrade (or downgrade) to a pinned release tag
container upgrade -f # force reinstall of the target version
```

Proposed behavior (strict parity with `scripts/update-container.sh`):

1. Refuse to run while `com.apple.container.*` launchd services are running, directing the user to `container system stop` first (the command does not stop services itself).
2. Resolve the target release via the GitHub releases API (`releases/latest`, or `releases/tags/` with `-v`).
3. Exit successfully with an "already on version" message when the installed version matches the target, unless `-f` is passed.
4. Prefer the signed installer package (`container-installer-signed.pkg` / `container--installer-signed.pkg`), falling back to the unsigned package only after interactive confirmation.
5. Download to a temporary directory and install via `sudo installer -pkg -target /` — trust continues to come from macOS Installer/Gatekeeper validating the signed package.

Implementation sketch: a new `UpgradeCommand` in `Sources/ContainerCommands/` following the existing `AsyncLoggableCommand` pattern, with the release-resolution and asset-selection logic in pure functions covered by unit tests, plus an integration test that verifies the running-service guard. `docs/command-reference.md` would be updated accordingly.

Explicit non-goals for a first iteration (possible follow-ups): auto-stopping services before upgrade, semver-aware comparison, a `--dry-run` mode, and a download progress bar.

I have this working locally and can open a PR if the direction sounds good. Happy to adjust scope — including whether `update-container.sh` should eventually be deprecated in favor of the command, or kept alongside it.

### Code of Conduct

- [x] I agree to follow this project's Code of Conduct

Contributor guide

Open the contributing guide

Research direction

Start with scripts/update-container.sh and the existing AsyncLoggableCommand pattern in Sources/ContainerCommands/. Define the release-resolution and asset-selection logic as pure functions, add unit tests and an integration test for the running-service guard, then update docs/command-reference.md. Done means the native command matches the script's stated upgrade, pinned-version, force, package fallback, and service-guard behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
github, macos, shell, swift
Domain
cli, documentation, operating-systems, testing
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.