diff --git a/Makefile b/Makefile index c2c177163..51f4d59a1 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ COVERAGE=coverage.out MCLI_SOURCE_FILES?=./cmd/mongocli MCLI_BINARY_NAME=mongocli -MCLI_VERSION?=$(shell git describe --match "mongocli/v*" | cut -d "v" -f 2) +MCLI_VERSION?=$(shell ./build/package/git-version.sh describe) MCLI_GIT_SHA?=$(shell git rev-parse HEAD) MCLI_DESTINATION=./bin/$(MCLI_BINARY_NAME) MCLI_INSTALL_PATH="${GOPATH}/bin/$(MCLI_BINARY_NAME)" diff --git a/RELEASING.md b/RELEASING.md index 65de08d07..acbe402b6 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -2,10 +2,10 @@ ## Daily snapshots -We generate a snapshot build via the `goreleaser_snaphot` evergreen task, +We generate a snapshot build via the `package_goreleaser` evergreen task (in the `goreleaser_mongocli_snapshot` variant), this task runs on master and can be patched at any time. -- **goreleaser_snaphot:** used with `goreleaser` to generate linux, mac and windows builds, the mac build will also be signed and notarized, and the windows msi is generated on a Windows host spawned via evergreen's `host.create` +- **package_goreleaser:** used with `goreleaser` to generate linux, mac and windows builds, the mac build will also be signed and notarized, and the windows msi is generated on a Windows host spawned via evergreen's `host.create` ## Stable release @@ -15,28 +15,13 @@ Use the instructions bellow as a fallback. ## Package Managers -Package Managers are published after a stable release happens, in which binaries are stored in github releases and also uploaded to our download center (https://www.mongodb.com/try/download/atlascli and https://www.mongodb.com/try/download/mongocli). +Package Managers are published after a stable release happens, in which binaries are stored in github releases and also uploaded to our download center (https://www.mongodb.com/try/download/mongocli). * [Chocolatey](http://chocolatey.org) release is triggered in https://github.com/mongodb-forks/chocolatey-packages/, the Github Action will trigger every weekday at 4pm (UTC) to check if there are any new releases in https://github.com/mongodb/mongodb-cli/releases/. * [Homebrew](http://brew.sh/) release is triggered in https://github.com/Homebrew/homebrew-core/, which is not maintained by MongoDB rather by homebrew community. -* Yum and Apt are handled internally via evergreen tasks `push_stable_atlascli_generate` and `push_stable_mongocli_generate`. - -## Docker Image -Our Docker image release for AtlasCLI is managed through the [docker-release.yml](.github/workflows/docker-release.yml) workflow. This process is automated to run daily, ensuring the latest versions of the image dependencies are updated. -![github_action](https://github.com/mongodb/mongodb-cli/assets/5663078/fd54ccda-7794-4139-af92-dbde0c278e78) -### Release Steps -#### Step 1: Build and Stage -The AtlasCLI Docker image is built from the ([Dockerfile](Dockerfile)) and tagged in three ways: `latest`, `vX.Y.Z` (reflecting the latest release version, e.g., `v1.22.0`), and `vX.Y.Z-date` (adding the current date, e.g., `v1.22.0-2024-01-01`). This image is initially published to a staging registry to prepare for signature in the next step. - -#### Step 2: Sign and Publish -We retrieve the image from the staging registry and use its [OCI index](https://github.com/opencontainers/image-spec/blob/main/image-index.md) to identify the three relevant digests. Each digest is signed using [cosign](https://github.com/sigstore/cosign), and the corresponding signature is stored in the MongoDB cosign repository. The signed image is then pushed to the public repository. - -#### Step 3: Verify Signature -The final step involves verifying the Docker image's signature to confirm its authenticity. - - +* Yum and Apt are handled internally via evergreen task `push_stable_mongocli_generate`. ## Deprecated _**Note:** This action will only publish a release for [maintainers of the cli](https://github.com/orgs/mongodb/teams/mongocli)_ @@ -45,14 +30,14 @@ To manually generate a new stable release you can run: ```bash -./scripts/release.sh atlascli/v1.0.0 +./scripts/release.sh v1.0.0 ``` -**Note:** Please use the `atlascli/vX.Y.Z` or `mongocli/vX.Y.Z` format for the version to release +**Note:** Please use the `vX.Y.Z` format for the version to release. The legacy `atlascli/vX.Y.Z` / `mongocli/vX.Y.Z` prefix is no longer used to trigger releases. This will do the following things: -1. Tag a new version, ie: `git tag -a -s atlascli/v1.0.0 -m "atlascli/v1.0.0"` -2. Publish the new tag, ie `git push origin atlascli/v1.0.0` +1. Tag a new version, ie: `git tag -a -s v1.0.0 -m "v1.0.0"` +2. Publish the new tag, ie `git push origin v1.0.0` 3. The [evergreen](build/ci/release.yml) release task will run after a tag event from master. 4. If everything goes smoothly the release will be published in the [releases page](https://github.com/mongodb/mongodb-cli/releases), and [download center](https://www.mongodb.com/try/download/mongocli). @@ -60,20 +45,8 @@ This will do the following things: # Generate the SBOM The Software Bill of Materials (SBOM) is a description of the components that make up a software artifact. -## Atlas CLI Binary -We use `go version` to generate the SBOM for Atlas CLI binaries. You can generate the SBOM via the following command: -```bash -go version -m -``` - ## MongoCLI Binary We use `go version` to generate the SBOM for MongoCLI binaries. You can generate the SBOM via the following command: ```bash go version -m ``` - -## Atlas CLI Docker image -We use `docker sbom` to generate the SBOM for the AtlasCLI docker image. You can generate the SBOM via the following command: -```bash -docker sbom mongodb/atlas:latest -``` diff --git a/build/ci/release.yml b/build/ci/release.yml index d68c46b5f..a933ae897 100644 --- a/build/ci/release.yml +++ b/build/ci/release.yml @@ -38,7 +38,12 @@ functions: script: | set -Eeou pipefail - curl -sfL ${goreleaser_pro_tar_gz} | tar zx + curl -fL --retry 5 --retry-all-errors --retry-delay 2 \ + -o goreleaser.tar.gz \ + "https://github.com/goreleaser/goreleaser/releases/download/v2.18.2/goreleaser_Linux_x86_64.tar.gz" + test -s goreleaser.tar.gz + tar xzf goreleaser.tar.gz + rm -f goreleaser.tar.gz "install macos notarization service": - command: shell.exec type: setup @@ -94,7 +99,6 @@ functions: - notary_service_key_id - notary_service_secret - notary_service_url - - goreleaser_key - goreleaser_config - changelog_file - github_app_id diff --git a/build/package/.goreleaser.yml b/build/package/.goreleaser.yml index d4b230add..35af35917 100644 --- a/build/package/.goreleaser.yml +++ b/build/package/.goreleaser.yml @@ -1,8 +1,6 @@ +version: 2 project_name: mongocli -monorepo: - tag_prefix: mongocli/ - before: hooks: - go mod tidy @@ -51,28 +49,26 @@ gomod: # https://goreleaser.com/customization/verifiable_builds/ archives: - id: linux_archives name_template: mongocli_{{ .Version }}_{{ .Os }}_{{- if eq .Arch "amd64" }}x86_64{{- else }}{{ .Arch }}{{ end }} - builds: [linux] + ids: [linux] <<: &archive_defaults files: - README.md - LICENSE - third_party_notices/**/* wrap_in_directory: true - format: tar.gz - rlcp: false + formats: [tar.gz] - id: macos name_template: mongocli_{{ .Version }}_{{- if eq .Os "darwin" }}macos{{- else }}{{ .Os }}{{ end }}_{{- if eq .Arch "amd64" }}x86_64{{- else }}{{ .Arch }}{{ end }} - builds: [macos] + ids: [macos] <<: *archive_defaults - format: zip + formats: [zip] wrap_in_directory: false - id: windows name_template: mongocli_{{ .Version }}_{{ .Os }}_{{- if eq .Arch "amd64" }}x86_64{{- else }}{{ .Arch }}{{ end }} - builds: [windows] + ids: [windows] <<: *archive_defaults wrap_in_directory: false - format: zip - rlcp: false + formats: [zip] nfpms: - id: linux_package package_name: mongocli @@ -83,14 +79,14 @@ nfpms: description: MongoDB Command Line Interface (mongocli) is a tool for managing your MongoDB cloud services, like MongoDB Atlas, MongoDB Cloud Manager, and MongoDB Ops Manager. license: Apache 2.0 bindir: /usr - builds: [linux] + ids: [linux] formats: [deb,rpm] checksum: name_template: checksums.txt extra_files: - glob: ./bin/*.msi snapshot: - name_template: "{{ .Env.VERSION_GIT }}-next" + version_template: "{{ .Env.VERSION_GIT }}-next" changelog: sort: asc filters: diff --git a/build/package/docker/docker-build.sh b/build/package/docker/docker-build.sh index 6646547b0..ca415bc4a 100755 --- a/build/package/docker/docker-build.sh +++ b/build/package/docker/docker-build.sh @@ -16,7 +16,7 @@ set -Eeou pipefail -VERSION="$(git tag --list "mongocli/v*" --sort=taggerdate | tail -1 | cut -d "v" -f 2)" +VERSION="$("$(dirname "${BASH_SOURCE[0]}")/git-version.sh")" FILE_EXT=deb if [[ "${image-}" =~ "rpm" ]]; then diff --git a/build/package/generate-download-archive-manifest.sh b/build/package/generate-download-archive-manifest.sh index cf09c2a55..7d33289ef 100755 --- a/build/package/generate-download-archive-manifest.sh +++ b/build/package/generate-download-archive-manifest.sh @@ -15,7 +15,7 @@ # limitations under the License. set -Eeou pipefail -VERSION="$(git tag --list "mongocli/v*" --sort=taggerdate | tail -1 | cut -d "v" -f 2)" +VERSION="$("$(dirname "${BASH_SOURCE[0]}")/git-version.sh")" if [[ ${VERSION} =~ "-pre" ]]; then echo "Skipping generate download center manifest for pre-release version: ${VERSION}" diff --git a/build/package/git-version.sh b/build/package/git-version.sh new file mode 100755 index 000000000..dab1e12fe --- /dev/null +++ b/build/package/git-version.sh @@ -0,0 +1,52 @@ +#!/usr/bin/env bash +# Copyright 2026 MongoDB Inc +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -Eeou pipefail + +# Single source of truth for deriving the MongoCLI version from git tags, so +# the tag format lives in one place. Both the legacy "mongocli/vX.Y.Z" tags and +# the new "vX.Y.Z" tags are supported during the tag-format migration; the +# newest matching tag wins. +# +# Usage: +# git-version.sh [version|tag|describe] +# +# version (default) latest released version, e.g. 2.0.9 +# tag latest release tag, e.g. mongocli/v2.0.9 or v2.1.0 +# describe version from `git describe`, including the commit +# distance for unreleased builds, e.g. 2.0.9-6-g228d3df + +tag_patterns=('mongocli/v*' 'v*') + +# Strips the optional "mongocli/" prefix and the leading "v" from a tag. +version_from_tag() { + cut -d "v" -f 2 +} + +case "${1:-version}" in + tag) + git tag --list "${tag_patterns[@]}" --sort=-creatordate | head -1 + ;; + describe) + git describe --match 'mongocli/v*' --match 'v*' | version_from_tag + ;; + version) + git tag --list "${tag_patterns[@]}" --sort=-creatordate | head -1 | version_from_tag + ;; + *) + echo "usage: $(basename "$0") [version|tag|describe]" >&2 + exit 2 + ;; +esac diff --git a/build/package/mac_notarize.sh b/build/package/mac_notarize.sh index a15da2f1b..fe8e53f73 100755 --- a/build/package/mac_notarize.sh +++ b/build/package/mac_notarize.sh @@ -20,9 +20,10 @@ set -Eeou pipefail # This depends on binaries being generated in a goreleaser manner and gon being set up. # goreleaser should already take care of calling this script as a hook. -if [[ -f "./dist/macos_darwin_amd64_v1/bin/mongocli" && -f "./dist/macos_darwin_arm64/bin/mongocli" && ! -f "./dist/mongocli_macos_signed.zip" ]]; then +if [[ -f "./dist/macos_darwin_amd64_v1/bin/mongocli" && -f "./dist/macos_darwin_arm64_v8.0/bin/mongocli" && ! -f "./dist/mongocli_macos_signed.zip" ]]; then echo "notarizing macOs binaries" - zip -r ./dist/mongocli_amd64_arm64_bin.zip ./dist/macos_darwin_amd64_v1/bin/mongocli ./dist/macos_darwin_arm64/bin/mongocli # The Notarization Service takes an archive as input + # goreleaser v2 names build dirs after the target (e.g. darwin_arm64_v8.0) + zip -r ./dist/mongocli_amd64_arm64_bin.zip ./dist/macos_darwin_amd64_v1/bin/mongocli ./dist/macos_darwin_arm64_v8.0/bin/mongocli # The Notarization Service takes an archive as input ./linux_amd64/macnotary \ -f ./dist/mongocli_amd64_arm64_bin.zip \ -m notarizeAndSign -u https://dev.macos-notary.build.10gen.cc/api \ @@ -31,5 +32,5 @@ if [[ -f "./dist/macos_darwin_amd64_v1/bin/mongocli" && -f "./dist/macos_darwin_ echo "replacing original files" unzip -oj ./dist/mongocli_macos_signed.zip dist/macos_darwin_amd64_v1/bin/mongocli -d ./dist/macos_darwin_amd64_v1/bin/ - unzip -oj ./dist/mongocli_macos_signed.zip dist/macos_darwin_arm64/bin/mongocli -d ./dist/macos_darwin_arm64/bin/ + unzip -oj ./dist/mongocli_macos_signed.zip dist/macos_darwin_arm64_v8.0/bin/mongocli -d ./dist/macos_darwin_arm64_v8.0/bin/ fi diff --git a/build/package/package.sh b/build/package/package.sh index f47e1f428..c6d801ab0 100755 --- a/build/package/package.sh +++ b/build/package/package.sh @@ -22,7 +22,6 @@ export GITHUB_APP_PEM=${github_app_pem:?} export NOTARY_SERVICE_URL=${notary_service_url:?} export MACOS_NOTARY_KEY=${notary_service_key_id:?} export MACOS_NOTARY_SECRET=${notary_service_secret:?} -export GORELEASER_KEY=${goreleaser_key:?} export VERSION_GIT echo "$GITHUB_APP_PEM" > app.pem @@ -31,14 +30,14 @@ GITHUB_TOKEN=$(gh-token generate --app-id "$GITHUB_APP_ID" --key ./app.pem --ins rm -rf app.pem export GITHUB_TOKEN -VERSION_GIT="$(git tag --list "mongocli/v*" --sort=taggerdate | tail -1 | cut -d "v" -f 2)" +VERSION_GIT="$("$(dirname "${BASH_SOURCE[0]}")/git-version.sh")" if [[ "${unstable-}" == "-unstable" ]]; then # avoid race conditions on the notarization step by using `-p 1` - ./bin/goreleaser --config "${goreleaser_config:?}" --rm-dist --release-notes "${changelog_file:?}" -p 1 --snapshot + ./bin/goreleaser --config "${goreleaser_config:?}" --clean --release-notes "${changelog_file:?}" -p 1 --snapshot else # avoid race conditions on the notarization step by using `-p 1` - ./bin/goreleaser --config "${goreleaser_config:?}" --rm-dist --release-notes "${changelog_file:?}" -p 1 + ./bin/goreleaser --config "${goreleaser_config:?}" --clean --release-notes "${changelog_file:?}" -p 1 fi gh-token revoke -t "$GITHUB_TOKEN" diff --git a/build/package/rename-pkg.sh b/build/package/rename-pkg.sh index 859d9d0a4..ad95d5ac2 100755 --- a/build/package/rename-pkg.sh +++ b/build/package/rename-pkg.sh @@ -16,7 +16,7 @@ set -Eeou pipefail -VERSION="$(git tag --list "mongocli/v*" --sort=taggerdate | tail -1 | cut -d "v" -f 2)" +VERSION="$("$(dirname "${BASH_SOURCE[0]}")/git-version.sh")" if [[ "${unstable-}" == "-unstable" ]]; then VERSION="${VERSION}-next" diff --git a/build/package/send-slack-notification.sh b/build/package/send-slack-notification.sh index 50f4fe6dc..3a968d848 100755 --- a/build/package/send-slack-notification.sh +++ b/build/package/send-slack-notification.sh @@ -20,7 +20,7 @@ if [[ "${unstable-}" == "-unstable" ]]; then exit 0 fi -VERSION="$(git tag --list "mongocli/v*" --sort=taggerdate | tail -1 | cut -d "v" -f 2)" +VERSION="$("$(dirname "${BASH_SOURCE[0]}")/git-version.sh")" TOOL_NAME_MESSAGE="MongoDB CLI" diff --git a/build/package/windows_build_msi.sh b/build/package/windows_build_msi.sh index bd8221649..470fd9821 100755 --- a/build/package/windows_build_msi.sh +++ b/build/package/windows_build_msi.sh @@ -19,7 +19,7 @@ keyfile="${keyfile:-./build/ci/ssh_id}" user="${user:-Administrator}" hostsfile="${hostsfile:-./build/ci/hosts.json}" -VERSION_GIT="$(git tag --list "mongocli/v*" --sort=taggerdate | tail -1 | cut -d "v" -f 2)" +VERSION_GIT="$("$(dirname "${BASH_SOURCE[0]}")/git-version.sh")" VERSION_NAME="$VERSION_GIT" if [[ "${unstable-}" == "-unstable" ]]; then VERSION_NAME="$VERSION_GIT-next" diff --git a/scripts/release.sh b/scripts/release.sh index 8fcaeec2f..90cfbf82d 100755 --- a/scripts/release.sh +++ b/scripts/release.sh @@ -19,12 +19,12 @@ set -euo pipefail VERSION="${1-}" if [[ -z "${VERSION}" ]]; then - echo "Please provide a tag version in the format 'mongocli/vX.Y.Z'" + echo "Please provide a tag version in the format 'vX.Y.Z'" exit 1 fi -if [[ "${VERSION}" != mongocli/v* ]]; then - echo "Please provide a tag version in the format 'mongocli/vX.Y.Z'" +if [[ "${VERSION}" != v* ]]; then + echo "Please provide a tag version in the format 'vX.Y.Z'" exit 1 fi diff --git a/tools/release/main.go b/tools/release/main.go index e3c1b65e5..6e012f8d4 100644 --- a/tools/release/main.go +++ b/tools/release/main.go @@ -111,7 +111,7 @@ func generateFile(name, version string) error { ReleaseDate: time.Now().UTC(), Version: version, ManualLink: manualLink, - PreviousReleasesLink: "https://github.com/mongodb/mongodb-cli/mongocli/v2/releases", + PreviousReleasesLink: "https://github.com/mongodb/mongodb-cli/releases", ReleaseNotesLink: releaseNotesLink, TutorialLink: tutorialLink, Platform: []Platform{