Skip to content
Merged
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
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@

`stack-sh/cli` is the open-source native Rust `stack` command for Stack architecture diagrams.

The repository contains native validation, formatting, and rendering commands. The interface remains pre-release and no supported binary distribution is published yet. The planned target matrix, artifact names, verification material, channel ownership, and rollback rules are defined by the [distribution contract](./docs/distribution.md), with signing and verification procedures in the [supply-chain guide](./docs/supply-chain.md).
The repository contains native validation, formatting, and rendering commands. [Stack CLI 0.3.0](https://github.com/stack-sh/cli/releases/tag/v0.3.0) is the first supported native binary release for macOS 13 or newer and glibc-based Linux 2.31 or newer, on arm64 and x86_64. Homebrew, Cargo, Aqua, and self-update are not available yet. The target matrix, artifact names, verification material, channel ownership, and rollback rules are defined by the [distribution contract](./docs/distribution.md), with signing and verification procedures in the [supply-chain guide](./docs/supply-chain.md).

## Install

Download the archive for your target and its verification material from [GitHub Releases](https://github.com/stack-sh/cli/releases/tag/v0.3.0). Verify the checksum signature and both attestations by following the [supply-chain guide](./docs/supply-chain.md), then follow the [direct installation steps](./docs/distribution.md#direct-installation). The macOS artifacts are reproducibly ad-hoc signed, not Apple-notarized; Sigstore and GitHub attestations provide the publisher-identity check.

## Commands

Expand Down Expand Up @@ -79,4 +83,4 @@ See [CONTRIBUTING.md](./CONTRIBUTING.md) before opening a change. Please report

## Licensing

Repository-authored work is licensed under the [Apache License 2.0](./LICENSE) for personal and commercial use. Runtime and build dependency licenses are recorded in [THIRD_PARTY_LICENSES.md](./THIRD_PARTY_LICENSES.md). A future binary release must ship the applicable license and notice files described there.
Repository-authored work is licensed under the [Apache License 2.0](./LICENSE) for personal and commercial use. Runtime and build dependency licenses are recorded in [THIRD_PARTY_LICENSES.md](./THIRD_PARTY_LICENSES.md). Every published binary archive ships the applicable license and notice files described there.
2 changes: 1 addition & 1 deletion SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Supported versions

Stack CLI is pre-release. Security fixes are applied to the latest revision on `main`; no released binary version is currently supported.
Stack CLI 0.3.0 is the supported stable binary release. Before 1.0, only the latest stable release receives release support; `main` is an unreleased development revision. Download supported binaries and their verification material from the [v0.3.0 GitHub Release](https://github.com/stack-sh/cli/releases/tag/v0.3.0).

## Reporting a vulnerability

Expand Down
14 changes: 7 additions & 7 deletions distribution/distribution-contract.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
"minimumRustVersion": "1.85"
},
"availability": {
"state": "planned",
"message": "No supported binary or package-manager release is currently published. A channel becomes available only after its required verification passes for a stable release."
"state": "available",
"message": "Stack CLI 0.3.0 is available from GitHub Releases. Homebrew, Cargo, Aqua, and self-update remain planned."
},
"versioning": {
"scheme": "Semantic Versioning",
Expand Down Expand Up @@ -55,7 +55,7 @@
"libc": "system",
"minimumRuntime": "macOS 13",
"supportTier": "tier-1",
"state": "planned"
"state": "available"
},
{
"target": "x86_64-apple-darwin",
Expand All @@ -64,7 +64,7 @@
"libc": "system",
"minimumRuntime": "macOS 13",
"supportTier": "tier-1",
"state": "planned"
"state": "available"
},
{
"target": "aarch64-unknown-linux-gnu",
Expand All @@ -73,7 +73,7 @@
"libc": "glibc",
"minimumRuntime": "glibc 2.31",
"supportTier": "tier-1",
"state": "planned"
"state": "available"
},
{
"target": "x86_64-unknown-linux-gnu",
Expand All @@ -82,7 +82,7 @@
"libc": "glibc",
"minimumRuntime": "glibc 2.31",
"supportTier": "tier-1",
"state": "planned"
"state": "available"
}
],
"unsupported": [
Expand All @@ -106,7 +106,7 @@
"channels": [
{
"id": "github-release",
"state": "planned",
"state": "available",
"targets": [
"aarch64-apple-darwin",
"x86_64-apple-darwin",
Expand Down
16 changes: 8 additions & 8 deletions docs/distribution.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@

This document defines the shared release contract for the Stack CLI. It is normative for GitHub Releases, Homebrew, Cargo, Aqua, and `stack` self-update implementations. The machine-readable source is [`distribution/distribution-contract.json`](../distribution/distribution-contract.json).

No supported binary or package-manager release is published yet. Every target and channel below is **planned**, not currently available. A stable release changes availability only after its complete matrix passes the activation checks in this document.
[Stack CLI 0.3.0](https://github.com/stack-sh/cli/releases/tag/v0.3.0) is available as a supported GitHub Release for every target below. Homebrew, Cargo, Aqua, and self-update remain **planned** and have no supported install command yet.

## Supported platform matrix

The first supported binary matrix is intentionally narrow:

| Rust target | OS | Architecture | Runtime floor | Direct | Homebrew | Cargo | Aqua | Self-update |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| `aarch64-apple-darwin` | macOS | arm64 | macOS 13 | planned | planned | planned | planned | planned |
| `x86_64-apple-darwin` | macOS | x86_64 | macOS 13 | planned | — | planned | planned | planned |
| `aarch64-unknown-linux-gnu` | Linux | arm64 | glibc 2.31 | planned | planned | planned | planned | planned |
| `x86_64-unknown-linux-gnu` | Linux | x86_64 | glibc 2.31 | planned | planned | planned | planned | planned |
| `aarch64-apple-darwin` | macOS | arm64 | macOS 13 | available | planned | planned | planned | planned |
| `x86_64-apple-darwin` | macOS | x86_64 | macOS 13 | available | — | planned | planned | planned |
| `aarch64-unknown-linux-gnu` | Linux | arm64 | glibc 2.31 | available | planned | planned | planned | planned |
| `x86_64-unknown-linux-gnu` | Linux | x86_64 | glibc 2.31 | available | planned | planned | planned | planned |

Windows, musl-based Linux distributions such as Alpine, BSD, and 32-bit architectures are not supported release targets. A source build may happen to work elsewhere, but it is best-effort and does not block a release. Cargo installs on supported targets require Rust 1.85 or newer. Homebrew availability additionally follows [Homebrew's current tier-1 host requirements](https://docs.brew.sh/Support-Tiers); Stack does not label a host as supported when the package manager itself classifies it below tier 1.

Expand Down Expand Up @@ -60,12 +60,12 @@ The release manifest records the tag, commit, source version, `minimumSupportedC

## Direct installation

After a GitHub Release is marked available, select the archive whose target matches the supported platform table and download it together with all matching verification material. Complete the [supply-chain verification](./supply-chain.md), then extract and install the verified binary. For example, replace `{version}` and `{target}` with the exact release values:
Download [Stack CLI 0.3.0](https://github.com/stack-sh/cli/releases/tag/v0.3.0), select the archive whose target matches the supported platform table, and obtain all matching verification material. Complete the [supply-chain verification](./supply-chain.md), then extract and install the verified binary. Replace `{target}` with the exact release target:

```sh
tar -xzf "stack-v{version}-{target}.tar.gz"
tar -xzf "stack-v0.3.0-{target}.tar.gz"
mkdir -p "$HOME/.local/bin"
install -m 0755 "stack-v{version}-{target}/stack" "$HOME/.local/bin/stack"
install -m 0755 "stack-v0.3.0-{target}/stack" "$HOME/.local/bin/stack"
"$HOME/.local/bin/stack" --version
```

Expand Down
13 changes: 10 additions & 3 deletions scripts/distribution-contract.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,16 @@ test("package-manager ownership cannot be delegated to self-update", () => {
assert.throws(() => validateDistributionContract(candidate, cargoToml), /must own upgrades/);
});

test("a distribution cannot be marked available before release verification", () => {
test("the GitHub release cannot be activated with a planned target", () => {
const candidate = changed((value) => {
value.availability.state = "available";
value.targets[0].state = "planned";
});
assert.throws(() => validateDistributionContract(candidate, cargoToml), /must remain planned/);
assert.throws(() => validateDistributionContract(candidate, cargoToml), /must be available after release verification/);
});

test("package-manager channels remain planned after direct release activation", () => {
const candidate = changed((value) => {
value.channels.find(({ id }) => id === "homebrew").state = "available";
});
assert.throws(() => validateDistributionContract(candidate, cargoToml), /homebrew state must be planned/);
});
12 changes: 9 additions & 3 deletions scripts/validate-distribution-contract.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,12 @@ export function validateDistributionContract(contract, cargoToml) {
"sourceCargoPackage must match Cargo.toml",
);
invariant(contract.product?.publishedCargoPackage === null, "published Cargo package must remain unset before registry ownership is verified");
invariant(contract.availability?.state === "planned", "distribution must remain planned until a verified stable release exists");
invariant(contract.availability?.state === "available", "distribution must be available after the verified stable release");
invariant(
contract.availability?.message?.includes("Stack CLI 0.3.0") &&
contract.availability.message.includes("GitHub Releases"),
"availability message must identify the verified stable GitHub release",
);
invariant(
contract.product.currentSourceVersion === cargoValue(cargoToml, "version"),
"currentSourceVersion must match Cargo.toml",
Expand All @@ -75,7 +80,7 @@ export function validateDistributionContract(contract, cargoToml) {
`${target.target} has inconsistent OS, architecture, or libc metadata`,
);
invariant(target.supportTier === "tier-1", `${target.target} must be tier-1`);
invariant(target.state === "planned", `${target.target} must remain planned before release`);
invariant(target.state === "available", `${target.target} must be available after release verification`);
invariant(target.minimumRuntime, `${target.target} must declare a runtime floor`);
if (target.os === "linux") invariant(target.libc === "glibc", `${target.target} must use glibc`);
if (target.os === "macos") invariant(target.libc === "system", `${target.target} must use the system libc`);
Expand All @@ -89,7 +94,8 @@ export function validateDistributionContract(contract, cargoToml) {
);
const targetIds = new Set(expectedTargets);
for (const channel of contract.channels) {
invariant(channel.state === "planned", `${channel.id} must remain planned before release`);
const expectedState = channel.id === "github-release" ? "available" : "planned";
invariant(channel.state === expectedState, `${channel.id} state must be ${expectedState}`);
uniqueSorted(channel.targets, `${channel.id} targets`);
for (const target of channel.targets) {
invariant(targetIds.has(target), `${channel.id} references unknown target ${target}`);
Expand Down