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
10 changes: 5 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "stack-diagram-cli"
version = "0.5.1"
version = "0.5.2"
edition = "2024"
rust-version = "1.85"
publish = ["crates-io"]
Expand Down Expand Up @@ -28,8 +28,8 @@ serde_json = "=1.0.151"
serde_yaml_ng = "=0.10.0"
sha2 = "=0.11.0"
stack-compiler = "=0.1.0"
stack-engine = "=0.7.0"
stack-theme = "=0.5.0"
stack-engine = "=0.8.0"
stack-theme = "=0.6.0"
ureq = { version = "=3.4.0", default-features = false, features = ["rustls"] }
zip = { version = "=6.0.0", default-features = false, features = ["deflate-flate2-zlib-rs"] }

Expand Down
4 changes: 2 additions & 2 deletions THIRD_PARTY_LICENSES.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ Audit date: 2026-09-05

| Component | Version or revision | License | Source | Distribution note |
| --- | --- | --- | --- | --- |
| `stack-engine` / `stack-formatter` | `0.7.0` / `0.1.0` (crates.io) | Apache-2.0 | <https://github.com/stack-sh/engine> | Linked into the native binary; validates and renders caller-owned provider packs without bundling vendor assets. |
| `stack-engine` / `stack-formatter` | `0.8.0` / `0.1.0` (crates.io) | Apache-2.0 | <https://github.com/stack-sh/engine> | Linked into the native binary; validates and renders caller-owned provider packs without bundling vendor assets. |
| `stack-compiler` | `0.1.0 (crates.io)` | Apache-2.0 | <https://github.com/stack-sh/compiler> | Linked directly for protocol-neutral language intelligence and transitively through `stack-engine`; performs no runtime I/O. |
| `stack-theme` | `0.5.0 (crates.io)` | Apache-2.0 | <https://github.com/stack-sh/theme> | Linked directly and through `stack-engine`; its 30 fallback and 12 explicit core SVGs are Stack-authored Apache-2.0 assets. It also provides the asset-free provider-pack contract and types. |
| `stack-theme` | `0.6.0 (crates.io)` | Apache-2.0 | <https://github.com/stack-sh/theme> | Linked directly and through `stack-engine`; its fallback icons and 30 explicit core SVGs are Stack-authored Apache-2.0 assets. It also provides the asset-free provider-pack contract and types. |
| `roxmltree` | `0.21.1` | MIT OR Apache-2.0 | <https://github.com/RazrFalcon/roxmltree> | Parses untrusted local SVG into a read-only tree before allowlisted serialization. |
| `sha2`, `digest`, `block-buffer`, `crypto-common`, `hybrid-array`, `const-oid`, `typenum` | `0.11.0`, `0.11.3`, `0.12.1`, `0.2.2`, `0.4.14`, `0.10.2`, `1.20.1` | MIT OR Apache-2.0 | <https://github.com/RustCrypto> | Computes complete archive and per-asset SHA-256 identities. |
| `zip` | `6.0.0` | MIT | <https://github.com/zip-rs/zip2> | Reads audited, allowlisted entries from verified official ZIP archives. |
Expand Down
2 changes: 1 addition & 1 deletion distribution/distribution-contract.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"sourceCargoPackage": "stack-diagram-cli",
"publishedCargoPackage": "stack-diagram-cli",
"sourceVersionFile": "Cargo.toml",
"currentSourceVersion": "0.5.1",
"currentSourceVersion": "0.5.2",
"minimumRustVersion": "1.85",
"currentReleaseVersion": "0.5.1"
},
Expand Down
2 changes: 1 addition & 1 deletion distribution/generated/share/man/man1/stack.1
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.TH STACK 1 "" "Stack CLI 0.5.1" "Stack CLI Manual"
.TH STACK 1 "" "Stack CLI 0.5.2" "Stack CLI Manual"
.SH NAME
stack \- Stack diagram toolchain
.SH SYNOPSIS
Expand Down
10 changes: 10 additions & 0 deletions docs/releases/v0.5.2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Stack CLI 0.5.2

- Upgrade the shared rendering engine to 0.8.0 and the core theme catalog to 0.6.0.
- Generate graph-aware layouts with measured label spacing and connectors that avoid text, blocks, and parallel group borders.
- Render database nodes as rounded cards with the existing database icon.
- Use exact CSS pixel SVG coordinates to prevent browser font clamping and malformed-looking shapes.

Commands, configuration, machine-readable contracts, and the Rust 1.85 minimum remain unchanged. SVG geometry and bytes intentionally change; review any snapshots or exported diagrams when upgrading. Custom palette authoring is not part of this release.

Upgrade through the package manager that owns the installation. There is no self-update command. A new source version does not activate a distribution channel until its release artifacts and clean-install checks have succeeded.
9 changes: 8 additions & 1 deletion scripts/distribution-contract.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ test("source version drift is rejected", () => {
test("a stale stable release in the availability message is rejected", () => {
const candidate = changed((value) => {
value.availability.message = value.availability.message.replace(
`Stack CLI ${value.product.currentSourceVersion}`,
`Stack CLI ${value.product.currentReleaseVersion}`,
"Stack CLI 0.0.0",
);
});
Expand All @@ -54,6 +54,13 @@ test("a stale stable release in the availability message is rejected", () => {
);
});

test("release preparation preserves the last verified distribution version", () => {
const candidate = changed(value => { value.product.currentSourceVersion = "0.99.0"; });
const futureSource = cargoToml.replace(/^version = "[^"]+"/m, 'version = "0.99.0"');
assert.notEqual(candidate.product.currentSourceVersion, candidate.product.currentReleaseVersion);
assert.deepEqual(validateDistributionContract(candidate, futureSource), { targets: 4, channels: 4 });
});

test("an unverified crates.io package name is rejected", () => {
const candidate = changed((value) => {
value.product.publishedCargoPackage = "stack-cli";
Expand Down
2 changes: 1 addition & 1 deletion scripts/release-security.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
verifyReleaseMetadata,
} from "./release-security.mjs";

const version = "0.5.1";
const version = "0.5.2";
const commit = "0123456789abcdef0123456789abcdef01234567";
const provenancePredicate = "https://slsa.dev/provenance/v1";
const sbomPredicate = "https://spdx.dev/Document/v2.3";
Expand Down
26 changes: 13 additions & 13 deletions scripts/resolve-release-context.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,17 @@ test("main dispatch resolves a non-publishing verification run", () => {
ref: "refs/heads/main",
refName: "main",
sha,
requestedVersion: "0.5.1",
requestedVersion: "0.5.2",
cargoToml,
contract,
}),
{
version: "0.5.1",
tag: "v0.5.1",
version: "0.5.2",
tag: "v0.5.2",
sourceRef: "refs/heads/main",
publish: false,
verifiedChannels: "",
minimumSupportedCliVersion: "0.5.1",
minimumSupportedCliVersion: "0.5.2",
},
);
});
Expand All @@ -39,28 +39,28 @@ test("an exact version tag resolves a publishing run", () => {
assert.deepEqual(
resolveReleaseContext({
eventName: "push",
ref: "refs/tags/v0.5.1",
refName: "v0.5.1",
ref: "refs/tags/v0.5.2",
refName: "v0.5.2",
sha,
requestedVersion: "",
cargoToml,
contract,
}),
{
version: "0.5.1",
tag: "v0.5.1",
sourceRef: "refs/tags/v0.5.1",
version: "0.5.2",
tag: "v0.5.2",
sourceRef: "refs/tags/v0.5.2",
publish: true,
verifiedChannels: "github-release",
minimumSupportedCliVersion: "0.5.1",
minimumSupportedCliVersion: "0.5.2",
},
);
});

test("removed self-update cannot be activated", () => {
const activated = structuredClone(contract);
activated.channels.push({ id: "self-update", state: "available" });
assert.throws(() => resolveReleaseContext({eventName: "push", ref: "refs/tags/v0.5.1", refName: "v0.5.1", sha, cargoToml, contract: activated}), /self-update has been removed/);
assert.throws(() => resolveReleaseContext({eventName: "push", ref: "refs/tags/v0.5.2", refName: "v0.5.2", sha, cargoToml, contract: activated}), /self-update has been removed/);
});

test("manual runs from another ref or version are rejected", () => {
Expand All @@ -72,7 +72,7 @@ test("manual runs from another ref or version are rejected", () => {
contract,
};
assert.throws(
() => resolveReleaseContext({ ...common, ref: "refs/heads/topic", requestedVersion: "0.5.1" }),
() => resolveReleaseContext({ ...common, ref: "refs/heads/topic", requestedVersion: "0.5.2" }),
/must run from main/,
);
assert.throws(
Expand Down Expand Up @@ -107,7 +107,7 @@ test("source and contract version drift is rejected", () => {
ref: "refs/heads/main",
refName: "main",
sha,
requestedVersion: "0.5.1",
requestedVersion: "0.5.2",
cargoToml,
contract: drifted,
}),
Expand Down
2 changes: 1 addition & 1 deletion scripts/test_package_release.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@


class PackageReleaseTest(unittest.TestCase):
version = "0.5.1"
version = "0.5.2"
target = "aarch64-apple-darwin"
source_date_epoch = 1_788_566_400

Expand Down
2 changes: 1 addition & 1 deletion scripts/validate-distribution-contract.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export function validateDistributionContract(contract, cargoToml) {
invariant(contract.product?.publishedCargoPackage === "stack-diagram-cli", "published Cargo package must be stack-diagram-cli");
invariant(contract.availability?.state === "available", "distribution must be available after the verified stable release");
invariant(
contract.availability?.message?.includes(`Stack CLI ${cargoVersion}`) &&
contract.availability?.message?.includes(`Stack CLI ${contract.product.currentReleaseVersion}`) &&
contract.availability.message.includes("GitHub Releases") &&
contract.availability.message.includes("Homebrew") &&
contract.availability.message.includes("Aqua"),
Expand Down
Loading