diff --git a/build/ci/release.yml b/build/ci/release.yml index 528e80e14e..ad961330f1 100644 --- a/build/ci/release.yml +++ b/build/ci/release.yml @@ -3,10 +3,6 @@ variables: go_root: "/opt/golang/go1.24" go_bin: "/opt/golang/go1.24/bin" go_base_path: "" - - &go_windows_version - go_root: "c:\\golang\\go1.24" - go_bin: "c:\\golang\\go1.24\\bin" - go_base_path: "c:" - &go_env XDG_CONFIG_HOME: ${go_base_path}${workdir} GO111MODULE: "on" @@ -126,6 +122,7 @@ functions: ARTIFACTORY_PASSWORD: ${artifactory_password} GRS_USERNAME: ${garasign_username} GRS_PASSWORD: ${garasign_password} + AUTHENTICODE_KEY_NAME: ${authenticode_key_name} GITHUB_TOKEN: ${github_token} include_expansions_in_env: - go_base_path @@ -136,38 +133,6 @@ functions: - goreleaser_key - unstable binary: build/package/package.sh - "install go-msi": - - command: subprocess.exec - type: setup - params: - working_dir: src/github.com/mongodb/mongodb-atlas-cli - command: choco install -y "go-msi" --force - "uninstall go-msi": - - command: subprocess.exec - type: setup - params: - working_dir: src/github.com/mongodb/mongodb-atlas-cli - command: choco uninstall -y "go-msi" - "generate msi": - - command: subprocess.exec - type: test - params: - <<: *go_options - add_to_path: - - ${go_bin} - - ${go_base_path}${workdir}/bin - - ${go_base_path}${workdir}/src/github.com/mongodb/mongodb-atlas-cli/bin - - "/cygdrive/c/Program Files/go-msi" - - "/cygdrive/c/wixtools/bin" - env: - <<: *go_env - SECRET_API_KEY: ${chocolatey_api_key} - ARTIFACTORY_USERNAME: ${artifactory_username} - ARTIFACTORY_PASSWORD: ${artifactory_password} - GRS_USERNAME: ${garasign_username} - GRS_PASSWORD: ${garasign_password} - unstable: ${unstable} - command: bash.exe -c build/package/generate-msi.sh "rename pkg": - command: subprocess.exec type: test @@ -368,74 +333,39 @@ functions: shell: bash script: | ./run-copybara.sh + "create-windows-host": + - command: host.create + params: + distro: windows-vsCurrent-small + - command: host.list + params: + wait: true + num_hosts: 1 + path: ${workdir}/src/github.com/mongodb/mongodb-atlas-cli/build/ci/hosts.json + - command: shell.exec + params: + <<: *go_options + script: | + set -Eeou pipefail + echo "${__project_aws_ssh_key_value}" > ./build/ci/ssh_id + chmod 0600 ./build/ci/ssh_id tasks: - - name: package_msi - tags: ["packaging"] - depends_on: - - name: compile - variant: "code_health" - commands: - - func: "install go-msi" - - func: "generate msi" - vars: - unstable: ${unstable} - - func: "uninstall go-msi" - - command: s3.put - params: - aws_key: ${aws_key} - aws_secret: ${aws_secret} - local_files_include_filter: - - src/github.com/mongodb/mongodb-atlas-cli/bin/*.exe - - src/github.com/mongodb/mongodb-atlas-cli/dist/*.msi - remote_file: ${project}/dist/${revision}_${created_at}/unsigned_ - bucket: mongodb-mongocli-build - permissions: public-read - content_type: ${content_type|application/octet-stream} - display_name: unsigned - name: package_goreleaser tags: ["packaging"] depends_on: - name: compile variant: "code_health" commands: + - func: "create-windows-host" - func: "generate sbom" - func: "run silkbomb" - func: "generate notices" - func: "install goreleaser" - func: "install macos notarization service" - func: "install gh-token" - - command: subprocess.exec - type: test - params: - working_dir: src/github.com/mongodb/mongodb-atlas-cli - include_expansions_in_env: - - project - - revision - - created_at - env: - BUCKET: mongodb-mongocli-build - unstable: ${unstable} - binary: build/package/download-win-binaries.sh - - command: subprocess.exec - type: test - params: - include_expansions_in_env: - - unstable - env: - ARTIFACTORY_USERNAME: ${artifactory_username} - ARTIFACTORY_PASSWORD: ${artifactory_password} - GRS_USERNAME: ${garasign_username} - GRS_PASSWORD: ${garasign_password} - AUTHENTICODE_KEY_NAME: ${authenticode_key_name} - working_dir: src/github.com/mongodb/mongodb-atlas-cli - binary: build/package/windows_notarize.sh - func: "package" vars: unstable: ${unstable} - ARTIFACTORY_USERNAME: ${artifactory_username} - ARTIFACTORY_PASSWORD: ${artifactory_password} - GRS_USERNAME: ${garasign_username} - GRS_PASSWORD: ${garasign_password} - func: "rename pkg" vars: unstable: ${unstable} @@ -561,15 +491,6 @@ tasks: gh_token: ${cloud_docs_token} workflow: cloud-docs buildvariants: - - name: go_atlascli_msi_snapshot - display_name: "Packaging AtlasCLI (go-msi)" - run_on: - - windows-vsCurrent-small - expansions: - <<: *go_windows_version - unstable: -unstable - tasks: - - name: package_msi - name: goreleaser_atlascli_snapshot display_name: "Packaging AtlasCLI (goreleaser)" run_on: @@ -584,9 +505,6 @@ buildvariants: unstable: -unstable tasks: - name: package_goreleaser - depends_on: - - name: package_msi - variant: "go_atlascli_msi_snapshot" - name: publish_atlascli_snapshot display_name: "Publish AtlasCLI Snapshot" run_on: @@ -609,9 +527,6 @@ buildvariants: meta_package_name: "mongodb-atlas" tasks: - name: package_goreleaser - depends_on: - - name: package_msi - variant: release_atlascli_msi - name: copybara display_name: "Copybara" git_tag_only: true @@ -623,17 +538,6 @@ buildvariants: <<: *go_linux_version tasks: - name: copybara - - name: release_atlascli_msi - display_name: "Release AtlasCLI (go-msi)" - run_on: - - windows-vsCurrent-small - git_tag_only: true - tags: - - foliage_health - expansions: - <<: *go_windows_version - tasks: - - name: package_msi - name: release_atlascli_publish display_name: "Publish AtlasCLI Generator" run_on: diff --git a/build/ci/ssh-ready.sh b/build/ci/ssh-ready.sh new file mode 100755 index 0000000000..f7fa302398 --- /dev/null +++ b/build/ci/ssh-ready.sh @@ -0,0 +1,65 @@ +#!/bin/bash + +# Copyright 2025 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 -euo pipefail + +declare -i attempts +declare -i connection_attempts +declare -ri timeout=10 + +while getopts 'i:h:t:u:' opt; do + case ${opt} in + i) keyfile="${OPTARG}" ;; # SSH identity file + u) user="${OPTARG}" ;; # Username on the remote host + h) hostsfile="${OPTARG}" ;; # Output of Evergreen host.list + t) connection_attempts="${OPTARG}" ;; # How many times to attempt to connect via SSH + *) + echo "Invalid option" + exit 1 + ;; + esac +done + +hosts=$( + cat </dev/null; do + if [[ "${attempts}" -ge "${connection_attempts}" ]]; then + echo 'Connect to spawn host failed' + exit 1 + fi + ((attempts++)) + + echo "SSH connection attempt $attempts/$connection_attempts failed. Retrying ($host)..." + # sleep for Permission denied (publickey) errors + sleep "$timeout" + done + set -e +done diff --git a/build/package/.goreleaser.yml b/build/package/.goreleaser.yml index 45d02830d7..ca03a7f25a 100644 --- a/build/package/.goreleaser.yml +++ b/build/package/.goreleaser.yml @@ -28,13 +28,16 @@ builds: - cmd: ./build/package/mac_notarize.sh output: true - <<: *build_defaults - builder: prebuilt id: windows goos: [windows] goarch: [amd64] goamd64: [v1] - prebuilt: - path: ./bin/atlas.exe + hooks: + post: + - cmd: ./build/package/windows_notarize.sh + output: true + - cmd: ./build/package/windows_build_msi.sh + output: true gomod: # https://goreleaser.com/customization/verifiable_builds/ # Proxy a module from proxy.golang.org, making the builds verifiable. # This will only be effective if running against a tag. Snapshots will ignore diff --git a/build/package/generate-msi.sh b/build/package/generate-msi.sh deleted file mode 100755 index 044fe8ce51..0000000000 --- a/build/package/generate-msi.sh +++ /dev/null @@ -1,42 +0,0 @@ -#!/usr/bin/env bash -# Copyright 2020 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 - -GOCACHE="$(cygpath --mixed "${workdir:?}\.gocache")" -CGO_ENABLED=0 -export GOCACHE -export CGO_ENABLED - -go-msi check-env - -VERSION_GIT="$(git tag --list "atlascli/v*" --sort=taggerdate | tail -1 | cut -d "v" -f 2)" -VERSION_NAME="$VERSION_GIT" -if [[ "${unstable-}" == "-unstable" ]]; then - VERSION_NAME="$VERSION_GIT-next" -fi - -COMMIT=$(git log -n1 --format=format:"%H") - -SOURCE_FILES=./cmd/atlas -PACKAGE_NAME=mongodb-atlas-cli_${VERSION_NAME}_windows_x86_64.msi -OUTPUT=./bin/atlas.exe -LINKER_FLAGS="-s -w -X github.com/mongodb/mongodb-atlas-cli/atlascli/internal/version.Version=${VERSION_GIT} -X github.com/mongodb/mongodb-atlas-cli/atlascli/internal/version.GitCommit=${COMMIT}" -WIX_MANIFEST_FILE="./build/package/wix/atlascli.json" - -env GOOS=windows GOARCH=amd64 go build \ - -ldflags "${LINKER_FLAGS}" -o ${OUTPUT} "${SOURCE_FILES}" - -go-msi make --path "${WIX_MANIFEST_FILE}" --msi "dist/${PACKAGE_NAME}" --version "${VERSION_GIT}" diff --git a/build/package/msi/generate-msi.sh b/build/package/msi/generate-msi.sh new file mode 100755 index 0000000000..d0b196109a --- /dev/null +++ b/build/package/msi/generate-msi.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash +# Copyright 2020 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 + +GOROOT="$(cygpath --unix "c:\\golang\\go1.24")" +PATH="${PATH}:$(cygpath --unix "c:\\golang\\go1.24\\bin"):$(cygpath --unix "c:\\Program Files\\go-msi"):$(cygpath --unix "c:\\wixtools\\bin")" +GOCACHE="$(cygpath --unix "c:\\Users\\Administrator\\.cache")" +CGO_ENABLED=0 + +export GOROOT PATH GOCACHE CGO_ENABLED + +choco install -y "go-msi" --force + +go-msi make --path "wix.json" --msi "out.msi" --version "$(cat version.txt)" + +choco uninstall -y "go-msi" --force + +rm -rf "$GOCACHE" diff --git a/build/package/wix/atlascli.json b/build/package/msi/wix.json similarity index 93% rename from build/package/wix/atlascli.json rename to build/package/msi/wix.json index 994ece83e4..fb1594f385 100644 --- a/build/package/wix/atlascli.json +++ b/build/package/msi/wix.json @@ -7,7 +7,7 @@ "guid": "cac1e5b1-6547-4c47-a68c-17a5b84dd87b", "items": [ "bin/atlas.exe", - "build/package/msi/installer" + "installer" ] }, "env": { diff --git a/build/package/windows_build_msi.sh b/build/package/windows_build_msi.sh new file mode 100755 index 0000000000..3a9e131341 --- /dev/null +++ b/build/package/windows_build_msi.sh @@ -0,0 +1,78 @@ +#!/usr/bin/env bash +# Copyright 2020 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 + +keyfile="${keyfile:-./build/ci/ssh_id}" +user="${user:-Administrator}" +hostsfile="${hostsfile:-./build/ci/hosts.json}" + +echo "Packaging $PWD/build/package/msi.zip" +mkdir -p ./build/package/msi/bin +cp ./dist/windows_windows_amd64_v1/bin/atlas.exe ./build/package/msi/bin/atlas.exe +cp ./LICENSE ./build/package/msi/LICENSE +git tag --list 'atlascli/v*' --sort=-taggerdate | head -1 | cut -d 'v' -f 2 > ./build/package/msi/version.txt +cd ./build/package +zip -r msi.zip msi +rm -rf ./msi/version.txt ./msi/bin/atlas.exe ./msi/LICENSE +cd ../.. + +echo "Waiting for the Windows host to become available..." +build/ci/ssh-ready.sh -u "$user" -i "$keyfile" -h "$hostsfile" +host=$(jq -r '.[0].dns_name' "$hostsfile") + +echo "Uploading $PWD/build/package/msi.zip to ${user}@${host}:/cygdrive/c/Users/Administrator/msi.zip" +scp -i "$keyfile" -o ConnectTimeout=10 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no "${PWD}/build/package/msi.zip" "${user}@${host}:/cygdrive/c/Users/Administrator/msi.zip" +rm -rf ./build/package/msi.zip + +echo "Building MSI on ${user}@${host}..." +ssh -i "$keyfile" -o ConnectTimeout=10 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no "${user}@${host}" "echo 'extracting msi.zip to /cygdrive/c/Users/Administrator/msi'; +unzip -o '/cygdrive/c/Users/Administrator/msi.zip' -d '/cygdrive/c/Users/Administrator'; +rm -rf '/cygdrive/c/Users/Administrator/msi.zip'; +echo 'running generate-msi.sh in /cygdrive/c/Users/Administrator/msi'; +cd '/cygdrive/c/Users/Administrator/msi'; +./generate-msi.sh; +" + +VERSION_GIT="$(git tag --list "atlascli/v*" --sort=taggerdate | tail -1 | cut -d "v" -f 2)" +VERSION_NAME="$VERSION_GIT" +if [[ "${unstable-}" == "-unstable" ]]; then + VERSION_NAME="$VERSION_GIT-next" +fi +MSI_FILE="${PWD}/bin/mongodb-atlas-cli_${VERSION_NAME}_windows_x86_64.msi" + +echo "Downloading from ${user}@${host}:/cygdrive/c/Users/Administrator/msi/out.msi to ${MSI_FILE}" +scp -i "$keyfile" -o ConnectTimeout=10 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no "${user}@${host}:/cygdrive/c/Users/Administrator/msi/out.msi" "${MSI_FILE}" +chmod 644 "${MSI_FILE}" + +echo "Cleaning up ${user}@${host}:/cygdrive/c/Users/Administrator/msi" +ssh -i "$keyfile" -o ConnectTimeout=10 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -tt "${user}@${host}" "rm -rf '/cygdrive/c/Users/Administrator/msi'" + +echo "Notarizing ${MSI_FILE}" +echo "${ARTIFACTORY_PASSWORD}" | podman login --password-stdin --username "${ARTIFACTORY_USERNAME}" artifactory.corp.mongodb.com + +echo "GRS_CONFIG_USER1_USERNAME=${GRS_USERNAME}" > .env +echo "GRS_CONFIG_USER1_PASSWORD=${GRS_PASSWORD}" >> .env + +echo "signing $MSI_FILE" +podman run \ + --env-file=.env \ + --rm \ + -v "$(pwd):$(pwd)" \ + -w "$(pwd)" \ + artifactory.corp.mongodb.com/release-tools-container-registry-local/garasign-jsign \ + /bin/bash -c "jsign --tsaurl http://timestamp.digicert.com -a ${AUTHENTICODE_KEY_NAME} \"$MSI_FILE\"" + +rm .env diff --git a/build/package/windows_notarize.sh b/build/package/windows_notarize.sh index 5da9ddc47e..5516f54cac 100755 --- a/build/package/windows_notarize.sh +++ b/build/package/windows_notarize.sh @@ -16,16 +16,9 @@ set -Eeou pipefail -VERSION_GIT="$(git tag --list "atlascli/v*" --sort=taggerdate | tail -1 | cut -d "v" -f 2)" -VERSION_NAME="$VERSION_GIT" -if [[ "${unstable-}" == "-unstable" ]]; then - VERSION_NAME="$VERSION_GIT-next" -fi - -EXE_FILE="bin/atlas.exe" -MSI_FILE="bin/mongodb-atlas-cli_${VERSION_NAME}_windows_x86_64.msi" +EXE_FILE="dist/windows_windows_amd64_v1/bin/atlas.exe" -if [[ -f "$EXE_FILE" && -f "$MSI_FILE" ]]; then +if [[ -f "$EXE_FILE" ]]; then echo "${ARTIFACTORY_PASSWORD}" | podman login --password-stdin --username "${ARTIFACTORY_USERNAME}" artifactory.corp.mongodb.com echo "GRS_CONFIG_USER1_USERNAME=${GRS_USERNAME}" > .env @@ -40,14 +33,5 @@ if [[ -f "$EXE_FILE" && -f "$MSI_FILE" ]]; then artifactory.corp.mongodb.com/release-tools-container-registry-local/garasign-jsign \ /bin/bash -c "jsign --tsaurl http://timestamp.digicert.com -a ${AUTHENTICODE_KEY_NAME} \"$EXE_FILE\"" - echo "signing $MSI_FILE" - podman run \ - --env-file=.env \ - --rm \ - -v "$(pwd):$(pwd)" \ - -w "$(pwd)" \ - artifactory.corp.mongodb.com/release-tools-container-registry-local/garasign-jsign \ - /bin/bash -c "jsign --tsaurl http://timestamp.digicert.com -a ${AUTHENTICODE_KEY_NAME} \"$MSI_FILE\"" - rm .env fi