#!/usr/bin/env bash # This script downloads the build artifacts along with the signatures, verifies the signatures and # creates a GitHub draft release. This should be run after `3-verify-build`. # This will also publish new version metadata set -eu SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" cd "$SCRIPT_DIR" if [ $# -lt 3 ]; then echo "Please provide the following arguments:" echo " $(basename "$0") \\" echo " \\" echo " \\" echo " " echo "" echo "Note that the metadata server SSH destination is part of the rsync command executed on the build server and will be checked against the SSH config of build@\$buildserver_host." exit 1 fi # Duplicated from /scripts/utils/gh-ready-check if ! command -v gh > /dev/null; then echo "gh (GitHub CLI) is required to run this script" exit 1 fi if ! gh auth status > /dev/null; then echo "Authentication through gh (GitHub CLI) is required to run this script" exit 1 fi PRODUCT_VERSION=$1 BUILDSERVER_HOST=$2 CDN_HOST=$3 ARTIFACT_DIR="./artifacts" URL_BASE="https://releases.mullvad.net/desktop/releases" rm -rf $ARTIFACT_DIR mkdir -p $ARTIFACT_DIR function download_and_verify { # Find GnuPG command to use. Prefer gpg2 gpg_cmd=$(command -v gpg2 || command -v gpg) for ext in .exe _arm64.exe _x64.exe _amd64.deb _arm64.deb _x86_64.rpm _aarch64.rpm .pkg; do pkg_filename="MullvadVPN-${PRODUCT_VERSION}${ext}" pkg_path="$ARTIFACT_DIR/$pkg_filename" url="$URL_BASE/$PRODUCT_VERSION/$pkg_filename" echo ">>> Downloading $pkg_filename - $url" curl -o "$pkg_path" --progress-bar --fail "$url" curl -o "$pkg_path.asc" --progress-bar --fail "$url.asc" echo "" echo ">>> Verifying integrity of $pkg_filename" if ! $gpg_cmd --verify "$pkg_path.asc" "$pkg_path"; then echo "" echo "!!! INTEGRITY CHECKING FAILED !!!" rm "$pkg_path" "$pkg_path.asc" exit 1 fi echo "" echo "GOOD SIGNATURE FOR $pkg_filename" echo "" done } function publish_metadata { local platforms platforms=(windows macos linux) local signed_dir="signed/" rm -rf currently_published/ echo ">>> Fetching current version metadata" meta pull --assume-yes "${platforms[@]}" echo "" echo ">>> Backing up released data" cp -r $signed_dir currently_published/ echo "" echo ">>> Replacing work/ directory with latest published data" cp -rf signed/ work/ echo "" echo ">>> Adding new release $$PRODUCT_VERSION (rollout = 1)" meta add-release "$PRODUCT_VERSION" "${platforms[@]}" echo "" echo ">>> Signing $PRODUCT_VERSION metadata" meta sign "${platforms[@]}" echo "" echo ">>> Verifying signed metadata" meta verify "${platforms[@]}" echo "" echo ">>> New metadata including $$PRODUCT_VERSION" git --no-pager diff --no-index -- currently_published/ $signed_dir || true echo "" read -rp "Press enter to upload if the diff looks good " ./publish-metadata-to-api $signed_dir "$BUILDSERVER_HOST" "$CDN_HOST" } function publish_release { echo ">>> Downloading changelog" local changelog_path changelog_path=$(mktemp) curl -o "$changelog_path" --progress-bar \ "https://raw.githubusercontent.com/mullvad/mullvadvpn-app/refs/tags/$PRODUCT_VERSION/CHANGELOG.md" changelog_end_version_pattern="20[0-9]\{2\}\.[0-9]\{1,2\}" if [[ $PRODUCT_VERSION == *-beta* ]]; then changelog_end_version_pattern=".*" fi changelog_extract=$(sed -n "/^## \[$PRODUCT_VERSION\]/,/^## \[$changelog_end_version_pattern\]/p" "$changelog_path") changelog=$(echo "$changelog_extract" | sed '$d' | \ awk 'NF { last = last ? last ORS $0 : $0 } END { print last }') release_flags=( --draft --repo "git@github.com:mullvad/mullvadvpn-app" --verify-tag --notes-file - --title "$PRODUCT_VERSION" ) previous_release=$(echo "$changelog_extract" | tail -1 | grep -oP '## \[\K[^\]]+') body="This release is for desktop only." if [[ $PRODUCT_VERSION == *-beta* ]]; then body+="\n\nHere is a list of all changes since last release [$previous_release](https://github.com/mullvad/mullvadvpn-app/releases/tag/$previous_release):" release_flags+=(--prerelease) else body+="\n\nHere is a list of all changes since last stable release [$previous_release](https://github.com/mullvad/mullvadvpn-app/releases/tag/$previous_release):" release_flags+=(--latest) fi version_count=$(echo "$changelog" | grep -c "^## ") if [ "$version_count" -eq 1 ]; then changelog=$(echo "$changelog" | tail -n +2) fi body+="\n$changelog" echo "" echo ">>> Creating GitHub release" # shellcheck disable=SC2059 # shellcheck disable=SC2046 printf "$body" | gh release create "${release_flags[@]}" "$PRODUCT_VERSION" $(printf "%s " "$ARTIFACT_DIR"/*) echo "" echo "The above URL contains the text \"untagged\", but don't worry it is tagged properly and everything will look correct once it's published." } download_and_verify # TODO: Uncomment before releasing installer downloader # publish_metadata publish_release