From 4df5b98c5c9620d9ed18ff45a5d32bfece574f8e Mon Sep 17 00:00:00 2001 From: Felipe Gasper Date: Wed, 10 Sep 2025 14:05:31 -0400 Subject: [PATCH 01/13] add download script --- README.md | 6 ++++ download_latest.sh | 74 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100755 download_latest.sh diff --git a/README.md b/README.md index ac735138ab..52c31e58df 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,12 @@ Once downloaded, you will have to extract the binary and add it to your PATH variable. For detailed instructions for each of our supported platforms, please visit [installation documentation](https://www.mongodb.com/docs/mongodb-shell/install#mdb-shell-install). +You can also run `download_latest.sh` to download a `mongosh` binary. You can use +this script without cloning the repository thus: +``` +curl -sSL https://raw.githubusercontent.com/mongodb-js/mongosh/refs/heads/main/download_latest.sh | sh +``` + ## CLI Usage diff --git a/download_latest.sh b/download_latest.sh new file mode 100755 index 0000000000..9ea70e6af1 --- /dev/null +++ b/download_latest.sh @@ -0,0 +1,74 @@ +#!/bin/sh + +set -o errexit + +for tool in jq curl; do + which "$tool" >/dev/null || { + echo >&2 "This script requires '$tool'." + exit 1 + } +done + +os=$(uname -o | tr '[:upper:]' '[:lower:]') +arch=$(uname -m) + +case "$os" in + *linux) + ext=tgz + os=linux + ;; + darwin) + ext=zip + ;; + *) + echo >&2 "This script does not support this OS ($os). Download mongosh manually." + exit 1 +esac + +case "$arch" in + amd64|x86_64) + arch=x64 + ;; + aarch64) + arch=arm64 +esac + +urls=$(curl -fsSL https://api.github.com/repos/mongodb-js/mongosh/releases/latest | jq -r '.assets[] | .browser_download_url' | grep -v -e \.sig -e shared -e openssl) +url=$(printf "%s" "$urls" | grep "\-${os}-${arch}" ||:) + +if [ -z "$url" ]; then + cat < "$file" + echo "Downloaded $ext file; extracting mongosh …" + + unzip -j "$file" '*/mongosh' + ;; + tgz) + echo "Downloading & extracting from $url …" + + curl -fsSL "$url" | tar -xzf - \ + --transform "s/.*\///" \ + --wildcards "**/mongosh" + + ;; + *) + echo >&2 "Bad file extension: $ext" + exit 1 +esac + +echo "Success! 'mongosh' is now saved in this directory." From c1ec95ae1f85677650a09dc7aa1b057b374fb5f9 Mon Sep 17 00:00:00 2001 From: Felipe Gasper Date: Thu, 11 Sep 2025 09:00:11 -0400 Subject: [PATCH 02/13] =?UTF-8?q?Anna=E2=80=99s=20review=20feedback?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- download_latest.sh | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/download_latest.sh b/download_latest.sh index 9ea70e6af1..c3d54bc9f0 100755 --- a/download_latest.sh +++ b/download_latest.sh @@ -2,6 +2,8 @@ set -o errexit +MONGOSH_RELEASES_URL=https://downloads.mongodb.com/compass/mongosh.json + for tool in jq curl; do which "$tool" >/dev/null || { echo >&2 "This script requires '$tool'." @@ -25,24 +27,33 @@ case "$os" in exit 1 esac +# normalize $arch: case "$arch" in - amd64|x86_64) - arch=x64 + amd64|x64) + arch=x86_64 ;; aarch64) arch=arm64 + ;; + *) + # Use uname’s reported architecture in the jq query. esac -urls=$(curl -fsSL https://api.github.com/repos/mongodb-js/mongosh/releases/latest | jq -r '.assets[] | .browser_download_url' | grep -v -e \.sig -e shared -e openssl) -url=$(printf "%s" "$urls" | grep "\-${os}-${arch}" ||:) +jq_query=$(cat <&2 "No download found for $os on $arch; download manually." exit 1 fi From 588c5e2275b17198048e152a100769569f5e1100 Mon Sep 17 00:00:00 2001 From: Felipe Gasper Date: Thu, 11 Sep 2025 10:46:00 -0400 Subject: [PATCH 03/13] Update README.md Co-authored-by: Anna Henningsen --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 52c31e58df..cae6cc24a3 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ variable. For detailed instructions for each of our supported platforms, please You can also run `download_latest.sh` to download a `mongosh` binary. You can use this script without cloning the repository thus: ``` -curl -sSL https://raw.githubusercontent.com/mongodb-js/mongosh/refs/heads/main/download_latest.sh | sh +curl -fsSL https://raw.githubusercontent.com/mongodb-js/mongosh/refs/heads/main/download_latest.sh | sh ``` ## CLI Usage From 50bddd8890cbe31a5d9c595a912d10e52db0e8b3 Mon Sep 17 00:00:00 2001 From: Felipe Gasper Date: Thu, 11 Sep 2025 10:46:08 -0400 Subject: [PATCH 04/13] Update download_latest.sh Co-authored-by: Anna Henningsen --- download_latest.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/download_latest.sh b/download_latest.sh index c3d54bc9f0..4c9b926371 100755 --- a/download_latest.sh +++ b/download_latest.sh @@ -62,7 +62,7 @@ case "$ext" in file=$(mktemp) echo "Downloading $url to $file …" - trap 'rm -f $file' EXIT + trap 'rm -f "$file"' EXIT curl -fsSL "$url" > "$file" echo "Downloaded $ext file; extracting mongosh …" From e8d4af8298a5f1ef0ed8c86e8466c889ce11b67e Mon Sep 17 00:00:00 2001 From: Felipe Gasper Date: Fri, 12 Sep 2025 09:32:55 -0400 Subject: [PATCH 05/13] Extract the crypto library as well. --- download_latest.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/download_latest.sh b/download_latest.sh index c3d54bc9f0..7a31133499 100755 --- a/download_latest.sh +++ b/download_latest.sh @@ -67,14 +67,15 @@ case "$ext" in curl -fsSL "$url" > "$file" echo "Downloaded $ext file; extracting mongosh …" - unzip -j "$file" '*/mongosh' + unzip -vj "$file" '*/bin/mongosh*' ;; tgz) echo "Downloading & extracting from $url …" curl -fsSL "$url" | tar -xzf - \ --transform "s/.*\///" \ - --wildcards "**/mongosh" + --wildcards "**/bin/mongosh*" \ + | sed -E 's/^.*[/]//' ;; *) @@ -82,4 +83,4 @@ case "$ext" in exit 1 esac -echo "Success! 'mongosh' is now saved in this directory." +echo "Success! 'mongosh' and its crypto library are now saved in this directory." From 9fad15ddfe496cb8af21143bbca00066d4a306d7 Mon Sep 17 00:00:00 2001 From: Felipe Gasper Date: Fri, 12 Sep 2025 09:41:24 -0400 Subject: [PATCH 06/13] prettify & add manual download link --- download_latest.sh | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/download_latest.sh b/download_latest.sh index 741df36b30..d396f59dec 100755 --- a/download_latest.sh +++ b/download_latest.sh @@ -4,6 +4,12 @@ set -o errexit MONGOSH_RELEASES_URL=https://downloads.mongodb.com/compass/mongosh.json +show_download_link() { + echo >&2 "Download mongosh manually from:" + echo >&2 + printf >&2 "\t%s\n", 'https://www.mongodb.com/try/download/shell' +} + for tool in jq curl; do which "$tool" >/dev/null || { echo >&2 "This script requires '$tool'." @@ -23,7 +29,9 @@ case "$os" in ext=zip ;; *) - echo >&2 "This script does not support this OS ($os). Download mongosh manually." + echo >&2 "❌ This script does not support this OS ($os)." + show_download_link + exit 1 esac @@ -53,7 +61,8 @@ EOF url=$(curl -fsSL $MONGOSH_RELEASES_URL | jq -r "$jq_query") if [ -z "$url" ]; then - echo >&2 "No download found for $os on $arch; download manually." + echo >&2 "❓ No download found for $os on $arch." + show_download_link exit 1 fi @@ -80,7 +89,8 @@ case "$ext" in ;; *) echo >&2 "Bad file extension: $ext" + show_download_link exit 1 esac -echo "Success! 'mongosh' and its crypto library are now saved in this directory." +echo "✅ Success! 'mongosh' and its crypto library are now saved in this directory." From 3e1404b9cc91d326c08915d9ac428e8ed8d49feb Mon Sep 17 00:00:00 2001 From: Felipe Gasper Date: Mon, 8 Dec 2025 11:50:45 -0500 Subject: [PATCH 07/13] Always output to stderr --- download_latest.sh | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/download_latest.sh b/download_latest.sh index d396f59dec..b2477a8c79 100755 --- a/download_latest.sh +++ b/download_latest.sh @@ -4,15 +4,24 @@ set -o errexit MONGOSH_RELEASES_URL=https://downloads.mongodb.com/compass/mongosh.json +say() { + echo >&2 "$@" +} + +sayf() { + # shellcheck disable=SC2059 + printf >&2 "$@" +} + show_download_link() { - echo >&2 "Download mongosh manually from:" - echo >&2 - printf >&2 "\t%s\n", 'https://www.mongodb.com/try/download/shell' + say "Download mongosh manually from:" + say + sayf "\t%s\n" 'https://www.mongodb.com/try/download/shell' } for tool in jq curl; do which "$tool" >/dev/null || { - echo >&2 "This script requires '$tool'." + say "This script requires '$tool'." exit 1 } done @@ -29,7 +38,7 @@ case "$os" in ext=zip ;; *) - echo >&2 "❌ This script does not support this OS ($os)." + say "❌ This script does not support this OS ($os)." show_download_link exit 1 @@ -61,7 +70,7 @@ EOF url=$(curl -fsSL $MONGOSH_RELEASES_URL | jq -r "$jq_query") if [ -z "$url" ]; then - echo >&2 "❓ No download found for $os on $arch." + say "❓ No download found for $os on $arch." show_download_link exit 1 fi @@ -70,16 +79,16 @@ case "$ext" in zip) file=$(mktemp) - echo "Downloading $url to $file …" + say "Downloading $url to $file …" trap 'rm -f "$file"' EXIT curl -fsSL "$url" > "$file" - echo "Downloaded $ext file; extracting mongosh …" + say "Downloaded $ext file; extracting mongosh …" unzip -vj "$file" '*/bin/mongosh*' ;; tgz) - echo "Downloading & extracting from $url …" + say "Downloading & extracting from $url …" curl -fsSL "$url" | tar -xzf - \ --transform "s/.*\///" \ @@ -88,9 +97,9 @@ case "$ext" in ;; *) - echo >&2 "Bad file extension: $ext" + say "Bad file extension: $ext" show_download_link exit 1 esac -echo "✅ Success! 'mongosh' and its crypto library are now saved in this directory." +say "✅ Success! 'mongosh' and its crypto library are now saved in this directory." From c47eb0978dea7956dc27561340c285d13ea5093c Mon Sep 17 00:00:00 2001 From: Felipe Gasper Date: Mon, 8 Dec 2025 11:55:29 -0500 Subject: [PATCH 08/13] Update README change to mention `npx mongosh`. --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index cae6cc24a3..a340c44df4 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,9 @@ Once downloaded, you will have to extract the binary and add it to your PATH variable. For detailed instructions for each of our supported platforms, please visit [installation documentation](https://www.mongodb.com/docs/mongodb-shell/install#mdb-shell-install). -You can also run `download_latest.sh` to download a `mongosh` binary. You can use +Alternatively: +- Run `npx mongosh` to run mongosh without a full installation. +- Run `download_latest.sh` to download a `mongosh` binary. You can use this script without cloning the repository thus: ``` curl -fsSL https://raw.githubusercontent.com/mongodb-js/mongosh/refs/heads/main/download_latest.sh | sh From 5dcb55eee3729e26cdbcfe5f6e74fe6a0a8b994b Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Tue, 9 Dec 2025 14:21:55 +0100 Subject: [PATCH 09/13] fixup: code review comments --- README.md | 7 ++++--- download_latest.sh | 12 +++++++++++- packages/build/src/download-center/config.ts | 1 + 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index a340c44df4..0087d094fc 100644 --- a/README.md +++ b/README.md @@ -23,10 +23,11 @@ variable. For detailed instructions for each of our supported platforms, please [installation documentation](https://www.mongodb.com/docs/mongodb-shell/install#mdb-shell-install). Alternatively: -- Run `npx mongosh` to run mongosh without a full installation. +- Run `npx mongosh` to run mongosh without a full installation. This is + easiest if you already have npm installed. - Run `download_latest.sh` to download a `mongosh` binary. You can use -this script without cloning the repository thus: -``` + the following script: +```sh curl -fsSL https://raw.githubusercontent.com/mongodb-js/mongosh/refs/heads/main/download_latest.sh | sh ``` diff --git a/download_latest.sh b/download_latest.sh index b2477a8c79..880c388291 100755 --- a/download_latest.sh +++ b/download_latest.sh @@ -56,12 +56,22 @@ case "$arch" in # Use uname’s reported architecture in the jq query. esac +if [ "$os" = "linux" ]; then + if ldd $(which curl) | grep -q libssl.so.3 ; then + openssl_query='.sharedOpenssl == "openssl3"' + else + openssl_query='(has("sharedOpenssl") | not)' + fi +else + openssl_query='' +fi + jq_query=$(cat < semver.rcompare(a.version, b.version)); return { From 9290f20ab9feb8a757801cd96ceea9318ae400ef Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Tue, 9 Dec 2025 15:25:31 +0100 Subject: [PATCH 10/13] fixup: run build-info before finishing script --- download_latest.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/download_latest.sh b/download_latest.sh index 880c388291..bee70fc193 100755 --- a/download_latest.sh +++ b/download_latest.sh @@ -112,4 +112,10 @@ case "$ext" in exit 1 esac +./mongosh --build-info >/dev/null 2>&1 || { + say "❌ Downloaded mongosh is not executable." + ./mongosh --build-info + exit 1 +} + say "✅ Success! 'mongosh' and its crypto library are now saved in this directory." From 170aea3fd665ed3628bb80435450c3e7c9545acf Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Tue, 9 Dec 2025 15:37:46 +0100 Subject: [PATCH 11/13] fixup: add explicit semver ordering test --- .../build/src/download-center/config.spec.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/packages/build/src/download-center/config.spec.ts b/packages/build/src/download-center/config.spec.ts index 43d70cca91..2a0f2a27cd 100644 --- a/packages/build/src/download-center/config.spec.ts +++ b/packages/build/src/download-center/config.spec.ts @@ -205,6 +205,24 @@ describe('DownloadCenter config', function () { tutorial_link: 'test', }); }); + + it('the list is sorted by semver even if versions are added out of order', function () { + const getVersionConfig1x = sinon.stub().returns({ version: '1.2.2' }); + const getVersionConfig2x = sinon.stub().returns({ version: '2.0.0' }); + const existingDownloadCenterConfig = + createDownloadCenterConfig(getVersionConfig2x); + expect(existingDownloadCenterConfig.versions).to.have.lengthOf(1); + + const updatedConfig = getUpdatedDownloadCenterConfig( + existingDownloadCenterConfig, + getVersionConfig1x + ); + + expect(updatedConfig.versions).to.deep.equal([ + { version: '2.0.0' }, + { version: '1.2.2' }, + ]); + }); }); context( From c7ed4655a72e4c428f5bf12c4f50183ed8eb4a1a Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Tue, 9 Dec 2025 16:46:41 +0100 Subject: [PATCH 12/13] fixup: macOS fixes --- download_latest.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/download_latest.sh b/download_latest.sh index bee70fc193..b133db9723 100755 --- a/download_latest.sh +++ b/download_latest.sh @@ -58,9 +58,9 @@ esac if [ "$os" = "linux" ]; then if ldd $(which curl) | grep -q libssl.so.3 ; then - openssl_query='.sharedOpenssl == "openssl3"' + openssl_query='and .sharedOpenssl == "openssl3"' else - openssl_query='(has("sharedOpenssl") | not)' + openssl_query='and (has("sharedOpenssl") | not)' fi else openssl_query='' @@ -70,7 +70,7 @@ jq_query=$(cat < "$file" say "Downloaded $ext file; extracting mongosh …" - unzip -vj "$file" '*/bin/mongosh*' + unzip -j "$file" '*/bin/mongosh*' ;; tgz) say "Downloading & extracting from $url …" From 52c0d6265e0a0f6c64e0bb82ff4ceb70a78fd72a Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Tue, 9 Dec 2025 16:52:02 +0100 Subject: [PATCH 13/13] fixup: GHA test --- .github/workflows/test-download-latest.yml | 36 ++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 .github/workflows/test-download-latest.yml diff --git a/.github/workflows/test-download-latest.yml b/.github/workflows/test-download-latest.yml new file mode 100644 index 0000000000..8c1f61c39c --- /dev/null +++ b/.github/workflows/test-download-latest.yml @@ -0,0 +1,36 @@ +name: "Test download_latest script" +on: + push: + branches: + - main + pull_request: + +permissions: + contents: read + +jobs: + smoke-tests: + name: "OS: ${{ matrix.runner }}, node@${{ matrix.node }}" + strategy: + matrix: + runner: [ubuntu, macos] + node: [24.x] + fail-fast: false + runs-on: ${{ matrix.runner }}-latest + timeout-minutes: 30 # Installing dependencies on windows can take a while + env: + npm_config_loglevel: verbose + npm_config_foreground_scripts: "true" + PUPPETEER_SKIP_DOWNLOAD: "true" + steps: + - uses: actions/checkout@v5 + - uses: actions/setup-node@v6 + with: + check-latest: true + node-version: ${{ matrix.node }} + + - name: Install mongosh through download_latest.sh + run: ./download_latest.sh + + - name: Run smoke tests + run: npx -y mongodb-runner -- exec -- sh -c 'env MONGOSH_SMOKE_TEST_SERVER=$MONGODB_URI ./mongosh --smokeTests'