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
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,15 @@ the Mapbox APIs' own response bodies are not.
this release should be able to find it. Both are now covered by tests
against RFC 7636, which they were not before.

- Both installers now honour `MAPBOX_CLI_NO_TELEMETRY`, the name the binary
reads. They were left on the old `DISABLE_TELEMETRY` when the binary was
renamed, so neither name silenced both halves: the documented variable
stopped the CLI's markers but not the installer's, and the old one did the
reverse. `DISABLE_TELEMETRY` keeps working **in the installers only** — the
binary's break was announced, and a script fetched and run in one line has
no release notes in front of the reader, so breaking an opt-out there would
have happened silently. When both are set the new name wins.

## 0.1.8 - 2026-09-14

Initial beta release. The next release is `0.2.0`.
Expand Down
30 changes: 21 additions & 9 deletions scripts/install.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -86,21 +86,33 @@
# because this value comes from the environment and ends up in a header.
$InstallSource = $env:MAPBOX_CLI_INSTALL_SOURCE

# The switch src/http.rs honours for the CLI's own User-Agent, read here
# the same way, because someone who put DISABLE_TELEMETRY=1 in a Dockerfile
# and then runs `irm ... | iex` in the same file has already said which way
# they want it. The product token above survives it - the equivalent of
# The switch src/telemetry.rs honours for the CLI's own User-Agent, read
# here the same way, because someone who put it in a Dockerfile and then
# runs `irm ... | iex` in the same file has already said which way they
# want it. The product token above survives it - the equivalent of
# `mapbox-cli/<version>` going out either way - and the triple and the
# source tag are what it drops.
#
# Two names, and only the binary dropped the old one.
# MAPBOX_CLI_NO_TELEMETRY is the documented switch; DISABLE_TELEMETRY is
# what it was called before, and this script still honours it. The rename
# was announced as breaking for the binary; nothing announced it for the
# installers, which are fetched and run in one line with no release notes
# in front of the reader - and breaking an opt-out is the one change that
# must not happen quietly. So both work here, and the new name wins when
# both are set. See mapbox/mapbox-cli-private#140.
#
# Unset, empty or whitespace is a cleared variable. `0`, `f`, `false`, `n`,
# `no` and `off` are clap's false spellings, the same reading this script
# already gives MAPBOX_NO_MODIFY_PATH, so DISABLE_TELEMETRY=0 is someone
# declining the opt-out rather than taking it. Anything else opts out,
# including a spelling nobody planned for: the safe reading of a value we
# do not know, on a variable by that name, is the one that sends less.
# already gives MAPBOX_NO_MODIFY_PATH, so a `0` is someone declining the
# opt-out rather than taking it. Anything else opts out, including a
# spelling nobody planned for: the safe reading of a value we do not know,
# on a variable by that name, is the one that sends less.
$TelemetryAllowed = $true
$disableTelemetry = $env:DISABLE_TELEMETRY
$disableTelemetry = $env:MAPBOX_CLI_NO_TELEMETRY
if ($null -eq $disableTelemetry) {
$disableTelemetry = $env:DISABLE_TELEMETRY
}
if ($null -ne $disableTelemetry) {
$disableTelemetry = $disableTelemetry.Trim().ToLowerInvariant()
$TelemetryAllowed = (
Expand Down
45 changes: 33 additions & 12 deletions scripts/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -62,24 +62,45 @@ USER_AGENT='mapbox-cli-install/1'
# header.
INSTALL_SOURCE="${MAPBOX_CLI_INSTALL_SOURCE:-}"

# The switch `src/http.rs` honours for the CLI's own User-Agent, read here the
# same way, because someone who put DISABLE_TELEMETRY=1 in a Dockerfile and
# then pipes this script into sh in the same file has already said which way
# they want it. The product token above is what survives it — the equivalent of
# The switch `src/telemetry.rs` honours for the CLI's own User-Agent, read here
# the same way, because someone who put it in a Dockerfile and then pipes this
# script into sh in the same file has already said which way they want it. The
# product token above is what survives it — the equivalent of
# `mapbox-cli/<version>` going out either way — and everything appended below
# is what it drops.
#
# **Two names, and only the binary dropped the old one.**
# `MAPBOX_CLI_NO_TELEMETRY` is the documented switch; `DISABLE_TELEMETRY` is
# what it was called before, and this script still honours it. The rename was
# announced as breaking for the binary, so a `DISABLE_TELEMETRY=1` there
# genuinely stopped working and the changelog says so. Nothing announced it for
# the installers — this file is fetched and run in one line, so a reader has no
# release notes in front of them — and breaking an opt-out is the one change
# that must not happen quietly. So both work here, the new name wins when both
# are set, and the old one keeps working for the Dockerfile the comment above
# describes. See mapbox/mapbox-cli-private#140.
#
# Unset, empty, or whitespace: a cleared variable. `0`, `f`, `false`, `n`, `no`
# and `off` are clap's false spellings, so DISABLE_TELEMETRY=0 is someone
# declining the opt-out rather than taking it. Anything else opts out,
# including a spelling nobody planned for: the safe reading of a value we do
# not know, on a variable by that name, is the one that sends less.
# and `off` are clap's false spellings, so a `0` is someone declining the
# opt-out rather than taking it. Anything else opts out, including a spelling
# nobody planned for: the safe reading of a value we do not know, on a variable
# by that name, is the one that sends less.
telemetry_allowed() {
# ASCII-only on purpose, the way `to_ascii_lowercase` is in src/http.rs:
# [:upper:]/[:lower:] would bring the locale into a decision about six
# ASCII spellings, and this script sets no LC_ALL.
# Set at all — even to empty, which is how a shell clears one — means the
# new name is the answer. Otherwise fall back, so the two never have to be
# reconciled: an explicit `MAPBOX_CLI_NO_TELEMETRY=0` beats a stale
# `DISABLE_TELEMETRY=1` left in an image from before the rename.
if [ -n "${MAPBOX_CLI_NO_TELEMETRY+set}" ]; then
_telemetry_switch=$MAPBOX_CLI_NO_TELEMETRY
else
_telemetry_switch=${DISABLE_TELEMETRY-}
fi

# ASCII-only on purpose, the way `to_ascii_lowercase` is in
# src/telemetry.rs: [:upper:]/[:lower:] would bring the locale into a
# decision about six ASCII spellings, and this script sets no LC_ALL.
# shellcheck disable=SC2018,SC2019
case "$(printf '%s' "${DISABLE_TELEMETRY-}" |
case "$(printf '%s' "$_telemetry_switch" |
tr 'A-Z' 'a-z' |
sed 's/^[[:space:]]*//;s/[[:space:]]*$//')" in
'' | 0 | f | false | n | no | off) return 0 ;;
Expand Down
40 changes: 38 additions & 2 deletions scripts/test-install.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -386,9 +386,10 @@ function New-CaseEnv([string]$Name) {
Clear-Env 'MAPBOX_CLI_AUTH'
Clear-Env 'MAPBOX_TILESETS_CLI'
Clear-Env 'MAPBOX_CLI_INSTALL_SOURCE'
# A developer with this set in their own shell would otherwise turn every
# marker case into a failure that looks like the marker broke.
# A developer with either of these set in their own shell would otherwise
# turn every marker case into a failure that looks like the marker broke.
Clear-Env 'DISABLE_TELEMETRY'
Clear-Env 'MAPBOX_CLI_NO_TELEMETRY'
# What install.ps1 reads to decide where it is running. Set explicitly so
# the same case means the same thing on Windows and on the machine this is
# written on.
Expand Down Expand Up @@ -513,6 +514,41 @@ try {
Clear-Env 'DISABLE_TELEMETRY'
Clear-Env 'MAPBOX_CLI_INSTALL_SOURCE'

Start-Case 'MAPBOX_CLI_NO_TELEMETRY is honoured, and outranks the old name'
New-CaseEnv 'telemetry-new-name'
$env:MAPBOX_CLI_INSTALL_SOURCE = 'dockerfile'
# The documented name, which the binary reads and this script did not until
# mapbox/mapbox-cli-private#140.
$env:MAPBOX_CLI_NO_TELEMETRY = '1'
[IO.File]::WriteAllText($RequestLog, '')
Invoke-Installer
Expect-Status 0 'exits 0 - the install is not what is being switched off'
$logged = @([IO.File]::ReadAllLines($RequestLog) | Where-Object { $_ })
$bare = @($logged | Where-Object { $_ -like "* $InstallerUa" })
Expect-Equal '2' ([string]$logged.Count) 'still made both requests'
Expect-Equal '2' ([string]$bare.Count) 'each carries the product token and nothing else'
# Both set and disagreeing. The new name is the documented one, so an
# explicit 0 on it beats a DISABLE_TELEMETRY=1 left in an image from before
# the rename - otherwise the old variable could never be retired.
$env:MAPBOX_CLI_NO_TELEMETRY = '0'
$env:DISABLE_TELEMETRY = '1'
[IO.File]::WriteAllText($RequestLog, '')
Invoke-Installer
$logged = @([IO.File]::ReadAllLines($RequestLog) | Where-Object { $_ })
$marked = @($logged | Where-Object { $_ -like "* $InstallerUa ($Target) src/dockerfile" })
Expect-Equal '2' ([string]$marked.Count) 'the new name wins when the two disagree'
# And the other direction, so precedence is pinned rather than implied.
$env:MAPBOX_CLI_NO_TELEMETRY = '1'
$env:DISABLE_TELEMETRY = '0'
[IO.File]::WriteAllText($RequestLog, '')
Invoke-Installer
$logged = @([IO.File]::ReadAllLines($RequestLog) | Where-Object { $_ })
$bare = @($logged | Where-Object { $_ -like "* $InstallerUa" })
Expect-Equal '2' ([string]$bare.Count) 'and wins in the opt-out direction too'
Clear-Env 'MAPBOX_CLI_NO_TELEMETRY'
Clear-Env 'DISABLE_TELEMETRY'
Clear-Env 'MAPBOX_CLI_INSTALL_SOURCE'

Start-Case 'a checksum that does not match installs nothing'
New-CaseEnv 'bad-sha'
$env:MAPBOX_CLI_BASE_URL = "$($open.BaseUrl)/bad-sha-channel"
Expand Down
41 changes: 38 additions & 3 deletions scripts/test-install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -531,9 +531,9 @@ new_case_env() { # case-name
PATH="${CASE_SHIMS}:${SAFE_PATH}"
unset MAPBOX_CLI_VERSION MAPBOX_CLI_AUTH MAPBOX_INSTALL_TILESETS MAPBOX_TILESETS_CLI
unset MAPBOX_CLI_INSTALL_SOURCE
# A developer with this set in their own shell would otherwise turn every
# marker case into a failure that looks like the marker broke.
unset DISABLE_TELEMETRY
# A developer with either of these set in their own shell would otherwise
# turn every marker case into a failure that looks like the marker broke.
unset DISABLE_TELEMETRY MAPBOX_CLI_NO_TELEMETRY
export MAPBOX_CLI_BASE_URL MAPBOX_INSTALL_DIR PATH
}

Expand Down Expand Up @@ -658,6 +658,41 @@ expect_in_file "$CURL_LOG" "-A ${INSTALLER_UA} (${TARGET}" 'DISABLE_TELEMETRY=0
expect_in_file "$CURL_LOG" ' src/dockerfile' 'and the tag comes back with it'
unset MAPBOX_TEST_CURL_LOG DISABLE_TELEMETRY MAPBOX_CLI_INSTALL_SOURCE

start 'MAPBOX_CLI_NO_TELEMETRY is honoured, and outranks the old name'
new_case_env telemetry-new-name
export MAPBOX_INSTALL_TILESETS=no
export MAPBOX_CLI_INSTALL_SOURCE=dockerfile
shim curl-recording curl
CURL_LOG="${CASE_DIR}/curl-args"
export MAPBOX_TEST_CURL_LOG="$CURL_LOG"

# The documented name, which the binary reads and this script did not until
# mapbox/mapbox-cli-private#140.
: >"$CURL_LOG"
export MAPBOX_CLI_NO_TELEMETRY=1
run_piped && status=0 || status=$?
expect_status 0 "$status" 'exits 0 — the install is not what is being switched off'
expect_in_file "$CURL_LOG" "-A ${INSTALLER_UA} " 'still names the installer'
expect_not_in_file "$CURL_LOG" "${INSTALLER_UA} (" 'no platform rides behind it'
expect_not_in_file "$CURL_LOG" ' src/' 'and no source tag either'

# Both set, disagreeing. The new name is the documented one, so an explicit
# `0` on it beats a `DISABLE_TELEMETRY=1` left in an image from before the
# rename — otherwise the old variable could never be retired.
: >"$CURL_LOG"
export MAPBOX_CLI_NO_TELEMETRY=0
export DISABLE_TELEMETRY=1
run_piped || true
expect_in_file "$CURL_LOG" "-A ${INSTALLER_UA} (${TARGET}" 'the new name wins when the two disagree'

# And the other direction, so precedence is pinned rather than implied.
: >"$CURL_LOG"
export MAPBOX_CLI_NO_TELEMETRY=1
export DISABLE_TELEMETRY=0
run_piped || true
expect_not_in_file "$CURL_LOG" "${INSTALLER_UA} (" 'and wins in the opt-out direction too'
unset MAPBOX_TEST_CURL_LOG MAPBOX_CLI_NO_TELEMETRY DISABLE_TELEMETRY MAPBOX_CLI_INSTALL_SOURCE

start 'both installers send the same marker'
# The one thing about this marker that cannot be checked by watching a request:
# install.sh and install.ps1 each carry their own copy, because each is served
Expand Down
Loading