summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDavid Lönnhager <david.l@mullvad.net>2025-03-20 15:09:41 +0100
committerDavid Lönnhager <david.l@mullvad.net>2025-03-20 15:09:41 +0100
commitf9c44d63533bcaaa91435b92abec1ba8cea25925 (patch)
treed10bc627761d75f73a7dd73f70a671f3df9daf9c
parente5b0413051697ef6bfec7518b05a07537dbc31f5 (diff)
parent45c92e37b9fd0c1f40e817d49b5de19e4922aa39 (diff)
downloadmullvadvpn-f9c44d63533bcaaa91435b92abec1ba8cea25925.tar.xz
mullvadvpn-f9c44d63533bcaaa91435b92abec1ba8cea25925.zip
Merge branch 'add-upload-option-build-sh'
-rw-r--r--Cargo.lock2
-rwxr-xr-xci/buildserver-upload.sh29
-rw-r--r--installer-downloader/Cargo.toml3
-rwxr-xr-xinstaller-downloader/build.sh98
4 files changed, 117 insertions, 15 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 5d4adf2281..dbf52a96cb 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2022,7 +2022,7 @@ dependencies = [
[[package]]
name = "installer-downloader"
-version = "1.0.0"
+version = "0.1.0"
dependencies = [
"anyhow",
"async-trait",
diff --git a/ci/buildserver-upload.sh b/ci/buildserver-upload.sh
index fde7c192b8..f09ae11ea0 100755
--- a/ci/buildserver-upload.sh
+++ b/ci/buildserver-upload.sh
@@ -1,7 +1,7 @@
#!/usr/bin/env bash
set -eu
-shopt -s nullglob
+shopt -s nullglob globstar
CODE_SIGNING_KEY_FINGERPRINT="A1198702FC3E0A09A9AE5B75D5A1D4F266DE8DDF"
@@ -23,35 +23,42 @@ function rsync_upload {
while true; do
sleep 10
- for checksums_path in *.sha256; do
+ for checksums_path in **/*.sha256; do
sleep 1
+ checksums_dir=$(dirname "$checksums_path")
+ checksums_filename=$(basename "$checksums_path")
+
# Parse the platform name and version out of the filename of the checksums file.
- platform="$(echo "$checksums_path" | cut -d + -f 1)"
- version="$(echo "$checksums_path" | cut -d + -f 3,4 | sed 's/\.sha256//')"
- if ! sha256sum --quiet -c "$checksums_path"; then
+ platform="$(echo "$checksums_filename" | cut -d + -f 1)"
+ version="$(echo "$checksums_filename" | cut -d + -f 3,4 | sed 's/\.sha256//')"
+ if ! (cd "$checksums_dir" && sha256sum --quiet -c "$checksums_filename"); then
echo "Failed to verify checksums for $version"
continue
fi
- if [[ $version == *"-dev-"* ]]; then
+ if [[ "$platform" == "installer-downloader" ]]; then
+ upload_path="desktop/installer-downloader"
+ elif [[ $version == *"-dev-"* ]]; then
upload_path="$platform/builds"
else
upload_path="$platform/releases"
fi
- files=$(awk '{print $2}' < "$checksums_path")
- for file in $files; do
+ readarray -t files < <(cut -f 2- -d ' ' < "$checksums_path" | sed 's/^\*\(.*\)/\1/')
+ for filename in "${files[@]}"; do
+ file="$checksums_dir/$filename"
+
file_upload_dir="$upload_path/$version"
- if [[ $platform == "desktop" && ! $file == MullvadVPN-* ]]; then
+ if [[ $platform == "desktop" && ! $filename == MullvadVPN-* ]]; then
file_upload_dir="$file_upload_dir/additional-files"
- elif [[ $platform == "android" && ! $file =~ MullvadVPN-"$version"(.apk|.play.apk|.play.aab) ]]; then
+ elif [[ $platform == "android" && ! $filename =~ MullvadVPN-"$version"(.apk|.play.apk|.play.aab) ]]; then
file_upload_dir="$file_upload_dir/additional-files"
fi
rsync_upload "$file" "$file_upload_dir/" || continue
- if [[ $file == MullvadVPN-* ]]; then
+ if [[ $filename == MullvadVPN-* || $filename == Install* ]]; then
rm -f "$file.asc"
gpg -u $CODE_SIGNING_KEY_FINGERPRINT --pinentry-mode loopback --sign --armor --detach-sign "$file"
rsync_upload "$file.asc" "$file_upload_dir/" || continue
diff --git a/installer-downloader/Cargo.toml b/installer-downloader/Cargo.toml
index b88ed18a0c..98a6182b86 100644
--- a/installer-downloader/Cargo.toml
+++ b/installer-downloader/Cargo.toml
@@ -1,7 +1,8 @@
[package]
name = "installer-downloader"
description = "A secure minimal web installer for the Mullvad app"
-version = "1.0.0"
+version = "0.1.0"
+publish = false
authors.workspace = true
repository.workspace = true
license.workspace = true
diff --git a/installer-downloader/build.sh b/installer-downloader/build.sh
index efa060ae22..08a4d28d74 100755
--- a/installer-downloader/build.sh
+++ b/installer-downloader/build.sh
@@ -28,15 +28,19 @@ CARGO_TARGET_DIR=${CARGO_TARGET_DIR:-"../target"}
export CARGO_TARGET_DIR
# Temporary build directory
-BUILD_DIR="./build"
+BUILD_DIR="$SCRIPT_DIR/build"
# Successfully built (and signed) artifacts
-DIST_DIR="../dist"
+DIST_DIR="$SCRIPT_DIR/../dist"
BUNDLE_NAME="MullvadVPNInstaller"
BUNDLE_ID="net.mullvad.$BUNDLE_NAME"
FILENAME="Install Mullvad VPN"
+# When --upload is passed, git verify-tag looks for a signed tag with the prefix below.
+# The signed tag must be named $TAG_PREFIX/<version>.
+TAG_PREFIX="desktop/installer-downloader/"
+
rm -rf "$BUILD_DIR"
mkdir -p "$BUILD_DIR"
@@ -45,6 +49,9 @@ mkdir -p "$DIST_DIR"
# Whether to sign and notarized produced binaries
SIGN="false"
+# Whether to upload signed binaries
+UPLOAD="false"
+
# Temporary keychain to store the .p12 in.
# This is automatically created/replaced when signing on macOS.
SIGN_KEYCHAIN_PATH="$HOME/Library/Keychains/mv-metadata-keychain-db"
@@ -55,6 +62,9 @@ while [[ "$#" -gt 0 ]]; do
--sign)
SIGN="true"
;;
+ --upload)
+ UPLOAD="true"
+ ;;
*)
log_error "Unknown parameter: $1"
exit 1
@@ -63,6 +73,11 @@ while [[ "$#" -gt 0 ]]; do
shift
done
+if [[ "$UPLOAD" == "true" && "$SIGN" != "true" ]]; then
+ log_error "'--upload' requires '--sign' to be specified"
+ exit 1
+fi
+
# Check that we have the correct environment set for signing
function assert_can_sign {
if [[ "$(uname -s)" == "Darwin" ]]; then
@@ -305,6 +320,76 @@ function dist_windows_app {
mv "$BUILD_DIR/$FILENAME.exe" "$DIST_DIR/"
}
+# Upload whatever matches the first argument to the Linux build server
+# Arguments:
+# - local file
+# - version
+function upload_sftp {
+ local local_path=$1
+ local version=$2
+ echo "Uploading \"$local_path\" to app-build-linux:upload/installer-downloader/$version"
+ sftp app-build-linux <<EOF
+mkdir upload/installer-downloader
+mkdir upload/installer-downloader/$version
+chmod 770 upload/installer-downloader
+chmod 770 upload/installer-downloader/$version
+cd upload/installer-downloader/$version
+put "$local_path"
+bye
+EOF
+}
+
+# Upload latest build and checksum in the dist directory to Linux build server
+# The artifacts MUST have been built already
+# The working directory MUST be $DIST_DIR
+#
+# Arguments:
+# - version
+function upload {
+ local version=$1
+ local files=( "$FILENAME."* )
+
+ local checksums_path
+ checksums_path="installer-downloader+$(hostname)+$version.sha256"
+
+ sha256sum "${files[@]}" > "$checksums_path"
+
+ for file in "${files[@]}"; do
+ upload_sftp "$file" "$version" || return 1
+ done
+ upload_sftp "$checksums_path" "$version" || return 1
+}
+
+# Check if the current commit has a signed tag
+#
+# Arguments:
+# - version
+function verify_version_tag {
+ local version=$1
+
+ local expect_tag="${TAG_PREFIX}${version}"
+ log_info "Current commit must have tag: $expect_tag"
+
+ local tag
+ set +e
+ tag=$(git describe --exact-match --tags)
+ local describe_exit=$?
+ set -e
+
+ if [[ $describe_exit -ne 0 ]]; then
+ log_error "'git describe' failed for the current commit (no tag?). Expected tag $expect_tag"
+ exit 1
+ fi
+
+ if [[ "$tag" != "$expect_tag" ]]; then
+ log_error "Unexpected tag found for current commit. Expected $expect_tag. Found: $tag"
+ exit 1
+ fi
+
+ log_info "Verifying tag $tag..."
+ git verify-tag "$tag"
+}
+
function main {
if [[ "$SIGN" != "false" ]]; then
assert_can_sign
@@ -327,6 +412,15 @@ function main {
build_executable
dist_windows_app
fi
+
+ if [[ "$UPLOAD" == "true" ]]; then
+ local version
+ version=$(product_version)
+
+ verify_version_tag "$version"
+
+ (cd "$DIST_DIR" && upload "$version") || return 1
+ fi
}
main