Release status: packaging, archive acceptance and GitHub publication are implemented by package-release, verify-release, publish-release and the release workflow. Version selection, compatibility review and tag signature verification are manual.
apple-cli adopts the organization VERSIONING, supplemented by the repository's VERSIONING. Those documents own version rules, including tags, release timing, version choice and the changelog. This reference owns release facts and procedures. The Release Guide covers source builds, installation, startup dependencies and target-specific validation limits.
| Shipped component | Version meaning | Version source | Mirrors and derived fields | Update and read-only check |
|---|---|---|---|---|
apple and its target commands |
Shared product version | CLIVersion.current in Sources/Utility/CLIVersion.swift |
apple --version, archive identity and provenance |
Edit the declaration manually; scripts/validate-version; CLIExecutableTests |
apple-cli-mcp |
Same product version | The same CLIVersion.current |
apple-cli-mcp --version, MCP initialization serverInfo.version |
Same declaration; CLIExecutableTests, AppleMCPAdapterTests and MCPExecutableTests |
Both executable products release together. Target modules and source skills
follow the repository release and have no independent product version
declaration. Sources/AppleCLI/Info.plist supplies bundle identity and usage
descriptions, with no separate version or build-number field. Installed
binaries and previous build directories are not version sources.
CHANGELOG.md supplies release notes for the declared product version. Its
entry and the optional existing release tag are checked against that
declaration; archive names and receipts are derived from the checked source
and build.
Consumers depend on the two executable names, command paths and options, exit
codes, structured output and error codes, MCP tool schemas and transports,
mutation and external-action gates, and documented runtime requirements.
The CLI contract
and MCP adapter boundary
own those contracts. The archive layout keeps both programs and their Swift
runtime libraries together in bin; the adapter's sibling lookup and
APPLE_CLI_BIN_DIR directory override are installation interfaces.
Package.swift declares Swift tools 6.3 and macOS 13 as the deployment floor.
Builds need a compatible Xcode toolchain and the Notes private-framework SDK
inputs described in the Release Guide. Native macOS arm64 is the implemented
packaging and executable-acceptance target. The deployment declaration does
not establish a tested runtime range; Intel and older macOS releases require
separate evidence. Review affected behavior and tests to establish
compatibility; version-number comparisons do not establish it.
Package.swift owns requirements under the organization VERSIONING; Package.resolved records selected versions and full revisions. The direct declarations are:
| Dependency | Declared requirement | Locked version | Role |
|---|---|---|---|
apple/swift-argument-parser |
from: "1.8.2" |
1.8.2 |
Typed command parsing |
hummingbird-project/hummingbird |
.upToNextMinor(from: "2.23.0") |
2.23.0 |
HTTP host shell |
computer-mcp/swift-sdk |
exact: "0.13.2-computer-mcp.1" |
0.13.2-computer-mcp.1 |
MCP protocol and transports; decode errors retain request ids and HTTP errors complete their POST |
apple/swift-http-types |
from: "1.8.0" |
1.8.0 |
HTTP request and response types |
swiftlang/swift-subprocess |
.upToNextMinor(from: "1.0.2") |
1.0.2 |
Process execution |
The MCP SDK comes from the Computer MCP fork. Transitive requirements, including swift-nio and swift-crypto, belong to the packages declaring them; their selected revisions are in the lockfile.
Dependency updates include manual confirmation that each selected source release tag peels to its locked revision. Use the dependency's actual tag spelling, accounting for any prefix SwiftPM normalizes in the recorded version. The release scripts check the local lockfile and its provenance digest; an automated dependency-tag verification command is not established. Update dependency notices and copied licenses with their selected sources, and revalidate downstream behavior affected by an update.
Test and release builds use --force-resolved-versions. Provenance records the
lockfile digest, resolved dependency records, OS, architecture, Xcode, Swift
toolchain, SDK and generated Notes link inputs. A successful candidate
establishes that recorded combination within the checks performed. The MCP
protocol baseline, SDK version, toolchain version and product version have
separate meanings.
The CI workflow
and release build job select the xcode-27 arm64 runner with Xcode 27.0.
That configuration is not evidence of a completed run or broader OS coverage;
runner image updates require renewed validation. The actual tested combination
comes from successful workflow results and packaged provenance.
Dependabot
checks Swift dependencies and Actions weekly. Its update pull requests run CI
and need compatibility, lockfile and dependency-notice review.
| Field or artifact | Authority and production | Read-only verification |
|---|---|---|
Executable version and MCP serverInfo.version |
Compiled from CLIVersion.current |
Executable and MCP initialization tests; packager checks both staged --version results |
| Release notes | Matching entry in CHANGELOG.md; publisher renders that entry and source/Actions links |
scripts/validate-version [--tag TAG] and publisher input validation |
| Archive basename | apple-cli-VERSION-macos-arm64, derived by scripts/package-release |
scripts/verify-release compares names, source version, tag and architecture |
.provenance.json and embedded provenance.json |
Packager records source commit/tree, lock digest and dependencies, environment, link inputs, linked libraries, run paths, binary/runtime hashes and successful validation-log hashes | Verifier checks source identity, lock digest, required checks, archive contents and embedded/adjacent manifest equality, apart from the adjacent archive digest |
.tar.gz.sha256 |
Packager hashes the archive bytes | Verifier recomputes the archive digest and exact checksum contents |
.verification.json |
scripts/verify-release --run-tests records archive/provenance/checksum hashes, checker hash, tested environment, successful checks and test-log digest; Actions adds run identity |
scripts/verify-release --require-verification checks identity, hashes, required checks and positive test/suite counts |
Provenance and verification receipts use schema_version: 1. Provenance also
records a build timestamp. Build timestamps and compiler output can vary; the
packager does not claim bit-for-bit rebuilds.
scripts/validate-version
requires exactly one canonical declaration in the supported version format.
For untagged validation, a changelog whose sole section is Unreleased may be
empty. Otherwise it requires exactly one nonempty entry for the product
version. --tag TAG additionally requires versioned notes, the expected tag
name and an existing tag whose peeled commit equals HEAD. These checks can
read an uncommitted working tree; they do not edit versions or infer upgrades.
Automated tag checks cover name and commit identity. Annotation and signature
verification remain manual under VERSIONING.
Packaging requires a clean committed source checkout before and after its checks. Locked builds constrain dependency resolution, and the verifier compares the lockfile digest with provenance. Missing or conflicting version, repository, source, artifact or receipt identity fails validation.
-
Manually prepare the canonical declaration and changelog under VERSIONING, then run the source gates:
scripts/validate-version --json scripts/validate-public-content python3 -B -m unittest discover -s Tests/ReleaseTools
-
Commit the complete candidate, including the lockfile, project license and dependency notices. From its clean checkout, build and accept the archive:
scripts/package-release --jobs 2 scripts/verify-release --run-tests
The packager bootstraps SDK link inputs, builds tests, runs default concurrent tests and separate MCP executable tests, and builds both release products. It collects Swift runtime libraries from the selected toolchain, removes external toolchain run paths, strips executable debug symbols and applies ad-hoc executable signatures. Runtime libraries retain their toolchain signatures. It checks standalone linkage, signatures, architecture, staged content and CLI/MCP behavior before creating the archive. These steps do not establish project Developer ID signing or notarization.
Archive verification checks safe extraction, source-matching bundled documents and licenses, binary inventory and digests, local Markdown links and machine-local path scans.
--run-teststhen verifies installed signatures and runsCLIExecutableTests,AppleMCPAdapterTestsandMCPExecutableTestsagainst the extracted binaries. This includes PATH/symlink startup, explicit CLI-directory selection and stdio/loopback HTTP forwarding with CLI help and a benign notification preview. It needs the matching source, build logs and built test executables. Default tests do not establish app/account permissions or native mutation behavior; see the Release Guide and Native Fixture Validation. -
For a candidate with an existing release tag at its commit, pass that tag to both shared steps:
scripts/package-release --tag vVERSION --jobs 2 scripts/verify-release --tag vVERSION --run-tests
Packaging creates no tag, remote push or GitHub release. CI runs the source gates, packaging and archive acceptance for pushes to
master, pull requests and manual runs. The release workflow performs the same checks on its checked-out tag, triggered by av*tag push or a manual existingtaginput. Each release workflow build independently accepts its tagged archive. -
The release build job has read-only repository permissions. It transfers the accepted archive, checksum, provenance and verification receipt to an independent Linux publication job in
computer-mcp/apple-cli. The publisher needs Python 3.12 or newer andgh; its job-scoped token hascontents: write. It verifies the four files against the tag checkout, source handoff and acceptance run, then checks the remote tag's peeled commit. It creates or resumes a draft, verifies existing assets, uploads missing files, checks uploaded sizes and digests, rechecks the remote tag and publishes those accepted bytes. Prerelease versions set the GitHub prerelease flag. The publication step does not rebuild or re-sign.
The release scripts require Python 3.12 or newer for archive validation.
scripts/verify-release --require-verification checks accepted files and the
receipt without executing macOS programs, as used by the Linux publisher.
Local candidate acceptance is development evidence; formal publication requires
the release workflow's accepted files and run identity. Installation and
Homebrew distribution procedures are in the Release Guide; the
organization tap owns its
distribution metadata and downstream installation acceptance.
Trusted publication evidence is the release workflow's accepted four-file artifact. Provenance binds it to the source commit/tree, dependency lock, toolchain, SDK, generated link inputs, validation-log hashes and binary/archive digests. Archive acceptance binds the checker digest and tested environment. The publisher verifies those receipts and the remote tag, and requires the acceptance repository, run ID and run URL to match its current Actions run. These are consistency checks on trusted workflow outputs, not independently signed receipt attestations.
Reuse successful evidence for matching inputs and intact accepted bytes. Source, dependency, build configuration, packaging, rebuild or re-sign changes require a new candidate and affected downstream acceptance. Checker changes invalidate checker evidence. Current verification requires the archive's exact clean source commit/tree, so a committed check-only change also requires a fresh candidate. There is no separate check-only artifact-reuse mechanism. Source tests do not replace installation checks on the actual archive.
For interrupted publication, rerun the failed publication job in the same Actions run to reuse its successful build's artifact. The original acceptance attempt remains recorded; publication matches the run ID rather than requiring that original attempt to equal the retry attempt. Matching draft assets are verified and missing assets are uploaded. An already published release with the same complete accepted files succeeds read-only. Incomplete, different or unexpected assets are refused. Reusing a draft with different build bytes requires manual disposal of that incomplete draft before a fresh candidate is published, under VERSIONING. An expired or unavailable workflow artifact needs a new build and acceptance; a standalone recovery command is not established.
Preserve failed logs and identify subsequent attempts separately before retrying. Archive executable acceptance has a 120-second deadline and reuses its log path for the same archive name. Build logs use separate run directories. Workflow attempt records and logs retain timing and failure context; local evidence supports only the source, artifacts and checks it covers.
Run repository commands from the source root. VERSION and TAG below denote
the intended candidate's existing version and tag, not inferred installed
values.
| Operation | Existing command or explicit manual procedure | Required access |
|---|---|---|
| Version update and check | Manually edit CLIVersion.current and changelog; scripts/validate-version [--tag TAG] [--json]. Automated version selection/update is not established. |
Source write for edits; read for validation |
| Source/documentation checks | scripts/validate-public-content; python3 -B -m unittest discover -s Tests/ReleaseTools |
Source read; temporary fixture writes; Swift toolchain |
| Candidate validation and build | scripts/package-release [--output DIRECTORY] [--tag TAG] [--jobs COUNT], then scripts/verify-release [--directory DIRECTORY] [--tag TAG] --run-tests |
Clean source; native macOS arm64, Xcode/SDK and writable build output |
| Existing accepted-file check | scripts/verify-release [--directory DIRECTORY] [--tag TAG] --require-verification |
Clean matching source and artifact read; Python 3.12+ |
| Status and interrupted-run recovery | Inspect the Actions run and artifact manually; rerun its failed publication job with the original accepted files. A standalone status/recovery command is not established. | Actions read; workflow rerun permission |
| Acceptance and publication | Existing-tag release workflow; its publish job invokes scripts/publish-release [--directory DIRECTORY] |
Workflow environment, accepted artifact and scoped GitHub release write |
| Cleanup | Manually inventory and remove owned reproducible output; no cleanup command is established. | Write access to the owned output |
Output defaults to .build/releases. One verification directory contains just
the archive, checksum, adjacent provenance and, after executable acceptance,
verification receipt. Existing packaging output names are refused. Both
workflows upload those files and preserve .build/release-validation logs even
after failed validation. Their artifact names include run ID and attempt. The
workflows set no retention-days; Actions retention depends on settings not
established in this repository. Published assets and release notes hold the
durable release record under VERSIONING.
Build logs, Notes link inputs, staging and caches belong beneath .build.
The packager removes its temporary staging directory on exit. Before manually
removing reproducible caches or completed outputs, check run ownership and
preserve unique source changes, required evidence, active-process inputs and
necessary rollback artifacts. Production app data is outside release-output
cleanup.