diff --git a/AGENTS.md b/AGENTS.md index c99ce88..6bd8b4d 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -192,8 +192,8 @@ same for the completion scripts. ## Compatibility and the changelog Command names, flags, the two output modes and the exit codes are promises; -the Mapbox APIs' own response bodies are not. The rules are in -[CONTRIBUTING.md](CONTRIBUTING.md#compatibility). +the Mapbox APIs' own response bodies, and commands marked beta, are not. The +rules are in [CONTRIBUTING.md](CONTRIBUTING.md#compatibility). [CHANGELOG.md](CHANGELOG.md) is written by hand, newest first, because the commit subject rarely explains why a change matters. A user-visible change diff --git a/CHANGELOG.md b/CHANGELOG.md index 11c1878..1c3b761 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,21 +4,26 @@ What changed, and what it means for scripts that already use this tool. Newest first, written by hand — the commit subject rarely explains why a change matters. -Versions follow [semantic versioning](https://semver.org/). Pre-1.0 rule: -while the version starts with `0.`, a breaking change raises the minor -number (`0.1.0` → `0.2.0`); everything else raises the patch. What counts as -breaking is [written down in CONTRIBUTING.md](CONTRIBUTING.md#compatibility) — briefly, -command names, flags, the two output modes and the exit codes are promises; -the Mapbox APIs' own response bodies are not. +Versions follow [semantic versioning](https://semver.org/): a breaking +change raises the major number (`1.0.0` → `2.0.0`), a new feature the minor, +and a fix the patch. Before 1.0, a breaking change raised the minor number +instead. What counts as breaking is [written down in +CONTRIBUTING.md](CONTRIBUTING.md#compatibility) — briefly, command names, +flags, the two output modes and the exit codes are promises; the Mapbox APIs' +own response bodies, and commands marked beta, are not. Cutting a release adds a `## - ` heading below `## Unreleased`, which stays in place so the next change has somewhere to go. +`tests/changelog.rs` fails while `Cargo.toml` names a version with no such +heading. Dev-channel builds (`v0.1.3-dev.`) are published straight from a branch that may never merge. They are not releases and are not listed here. ## Unreleased +## 1.0.0 - 2026-10-22 + - New `mapbox report ""` sends feedback about the CLI itself to the Mapbox CLI team, with the CLI's version and OS appended. It is filed under Mapbox's account, not yours. It is sent with the CLI's own token, @@ -330,13 +335,12 @@ that may never merge. They are not releases and are not listed here. only part of this that makes a request — the same precedent `auth whoami --verify` sets. -- A native `aarch64-pc-windows-msvc` build. Windows on Arm ran the x64 build - under emulation before this — including inside a VM on Apple Silicon, the - larger of the two populations this serves — which `install.ps1` already - said out loud and now no longer has reason to. `install.ps1` already asked - the manifest for this target before falling back to the x64 one, and - `.cargo/config.toml` already named it, so publishing the artifact was the - whole client-side change. +- A native `aarch64-pc-windows-msvc` build. Windows on Arm, including in a + VM on Apple Silicon, ran the x64 build under emulation before this, which + `install.ps1` already said out loud and now no longer has reason to. + `install.ps1` already asked the manifest for this target before falling + back to the x64 one, and `.cargo/config.toml` already named it, so + publishing the artifact was the whole client-side change. - `install.sh`/`install.ps1` now document a convention for `MAPBOX_CLI_INSTALL_SOURCE` when a coding agent invokes the installer on someone's behalf: `agent-` @@ -346,6 +350,15 @@ that may never merge. They are not releases and are not listed here. which would have collapsed `agent/claude-code` into `agentclaude-code` and lost the separator. Comment-only: neither installer's behavior changed. +- `rustls-webpki` moved to 0.103.16 and `webpki-roots` to 1.0.10, fixing + [RUSTSEC-2026-0382](https://rustsec.org/advisories/RUSTSEC-2026-0382) and + [RUSTSEC-2026-0381](https://rustsec.org/advisories/RUSTSEC-2026-0381) + (CVE-2026-111943): certificate verification could accept a path through + distrusted emSign intermediates, whose private keys are now public. Both + are reached through `reqwest`, so every HTTPS request this CLI makes used + the affected versions; nothing in the crate itself had to change. Fixed in + [mapbox/mapbox-cli#106](https://github.com/mapbox/mapbox-cli/pull/106). + ## 0.3.0 - 2026-09-22 ### Added diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ebb0b81..4e69488 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -93,13 +93,17 @@ and data-flow diagram (OAuth login, credential storage, API requests). ## Compatibility -While this is `0.x`, a breaking change bumps the minor version -(`0.1.5` → `0.2.0`); everything else bumps the patch. From 1.0 on, plain -[semver](https://semver.org/). Breaking: a command/flag removed, renamed, +Versions follow [semver](https://semver.org/): a breaking change bumps the +major version (`1.4.2` → `2.0.0`), a new feature the minor, and a fix the +patch. Breaking: a command/flag removed, renamed, or given a new default; an exit code or stdout/stderr change; a `--schema` field removed or repurposed. Not breaking: new commands, new API response fields, new `--schema` fields, and any wording. +A command marked beta is outside this promise until the label is removed: +it says so in its help and on every run, and it may change or be removed in +any release. + Deprecated commands and endpoints print a warning before the request goes out, and are marked `[deprecated]` in `--help` and `--schema`. diff --git a/Cargo.lock b/Cargo.lock index dce78d6..d793bcd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -784,7 +784,7 @@ checksum = "4050469837a6ff301cd14c1f8f24f88549e6d548f24f64e2148eb0f72cebc51f" [[package]] name = "mapbox-cli" -version = "0.3.0" +version = "1.0.0" dependencies = [ "anyhow", "base64 0.22.1", diff --git a/Cargo.toml b/Cargo.toml index 51cfd7e..3d747ca 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mapbox-cli" -version = "0.3.0" +version = "1.0.0" edition = "2021" description = "A command-line interface for Mapbox APIs, with commands generated at build time from OpenAPI specs." repository = "https://github.com/mapbox/mapbox-cli" diff --git a/README.md b/README.md index 18edc2c..8dc1f0b 100644 --- a/README.md +++ b/README.md @@ -80,11 +80,11 @@ taking the newest, with or without the leading `v`, so the version `mapbox --version` prints can be pasted straight in: ```sh -curl -fsSL https://cli.mapbox.com/install.sh | MAPBOX_CLI_VERSION=0.3.0 sh +curl -fsSL https://cli.mapbox.com/install.sh | MAPBOX_CLI_VERSION=1.0.0 sh ``` ```powershell -$env:MAPBOX_CLI_VERSION = '0.3.0'; irm https://cli.mapbox.com/install.ps1 | iex +$env:MAPBOX_CLI_VERSION = '1.0.0'; irm https://cli.mapbox.com/install.ps1 | iex ``` Both scripts put the install directory on your `PATH`: `install.sh` adds a @@ -139,7 +139,7 @@ Six targets are published: `aarch64-apple-darwin`, `x86_64-apple-darwin`, then extract: ```sh -version=v0.3.0 +version=v1.0.0 file=mapbox-${version}-aarch64-apple-darwin.tar.gz curl -fsSLO "https://cli.mapbox.com/${version}/${file}" @@ -154,7 +154,7 @@ On Windows the archive is a `.zip`, and PowerShell can read the manifest directly: ```powershell -$version = 'v0.3.0' +$version = 'v1.0.0' $target = 'x86_64-pc-windows-msvc' $manifest = Invoke-RestMethod "https://cli.mapbox.com/$version/manifest.json" diff --git a/tests/changelog.rs b/tests/changelog.rs new file mode 100644 index 0000000..adf010e --- /dev/null +++ b/tests/changelog.rs @@ -0,0 +1,45 @@ +//! Holds CHANGELOG.md to the version in `Cargo.toml`. +//! +//! A release bumps the version and moves the `## Unreleased` entries under a +//! `## - ` heading in the same commit. Nothing in the release +//! pipeline reads the changelog, so a tag cut from a commit that bumped the +//! version but skipped the heading would ship with every entry still under +//! Unreleased. Between releases the version names the last one, whose heading +//! is already there, so this only bites on the commit that bumps it. + +/// The heading's date is checked for shape only. Whether it is the day the +/// release actually went out is not something a test can know. +fn is_iso_date(text: &str) -> bool { + let bytes = text.as_bytes(); + bytes.len() == 10 + && bytes.iter().enumerate().all(|(i, b)| match i { + 4 | 7 => *b == b'-', + _ => b.is_ascii_digit(), + }) +} + +#[test] +fn the_current_version_has_a_dated_changelog_heading() { + let version = env!("CARGO_PKG_VERSION"); + let path = concat!(env!("CARGO_MANIFEST_DIR"), "/CHANGELOG.md"); + let changelog = std::fs::read_to_string(path).expect("read CHANGELOG.md"); + let prefix = format!("## {version} - "); + let found = changelog + .lines() + .filter_map(|line| line.strip_prefix(&prefix)) + .any(is_iso_date); + assert!( + found, + "Cargo.toml says {version}, but CHANGELOG.md has no `## {version} - YYYY-MM-DD` \ + heading. A version bump moves the Unreleased entries under that heading in the \ + same commit." + ); +} + +#[test] +fn is_iso_date_takes_only_that_shape() { + assert!(is_iso_date("2026-09-22")); + assert!(!is_iso_date("")); + assert!(!is_iso_date("2026-9-22")); + assert!(!is_iso_date("2026-09-22 (yanked)")); +}