summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorOskar <oskar@mullvad.net>2025-10-28 09:33:33 +0100
committerOskar <oskar@mullvad.net>2025-10-28 09:33:33 +0100
commit9e3e825e8c20870457410fd1a9568a4899ad93d8 (patch)
tree3c078834ddd21250cf3c931cb108f42c0cf53102
parentbbb3ffea3df68d5e08bed6dd7e5c4fc8bdc05129 (diff)
parenteae849668022e5a9e478a71746e5b896b9aaac1f (diff)
downloadmullvadvpn-ios-min-17.tar.xz
mullvadvpn-ios-min-17.zip
Merge branch 'run-release-utilities-from-repo'ios-min-17
-rw-r--r--.github/CODEOWNERS3
-rwxr-xr-xdesktop/scripts/release/1-prepare-release13
-rwxr-xr-xdesktop/scripts/release/2-create-and-push-tag3
-rwxr-xr-xdesktop/scripts/release/3-verify-build3
-rwxr-xr-xdesktop/scripts/release/4-make-release39
-rwxr-xr-xdesktop/scripts/release/5-update-and-publish-metadata77
-rwxr-xr-xdesktop/scripts/release/6-modify-rollout63
-rwxr-xr-xdesktop/scripts/release/download-release-artifacts9
-rw-r--r--desktop/scripts/release/release-config.sh9
-rwxr-xr-xdesktop/scripts/release/verify-version-is-release8
-rw-r--r--mullvad-update/mullvad-release/src/main.rs11
-rw-r--r--mullvad-update/mullvad-release/src/platform.rs15
-rwxr-xr-xscripts/utils/commit-verification14
13 files changed, 141 insertions, 126 deletions
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 513a1d3845..73768f8feb 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -18,6 +18,9 @@
/ci/buildserver* @faern @raksooo
/ci/linux-repository-builder/ @faern @raksooo
+# Desktop release config specifying code signing key fingerprint
+/desktop/scripts/release/release-config.sh
+
# Cargo deny config must be approved by tech lead or desktop team lead
**/deny.toml @faern @raksooo
diff --git a/desktop/scripts/release/1-prepare-release b/desktop/scripts/release/1-prepare-release
index b76487d5cb..1a0fc302bb 100755
--- a/desktop/scripts/release/1-prepare-release
+++ b/desktop/scripts/release/1-prepare-release
@@ -10,10 +10,11 @@ cd "$SCRIPT_DIR"
REPO_ROOT=../../../
+$REPO_ROOT/scripts/utils/commit-verification
+
source $REPO_ROOT/scripts/utils/log
source $REPO_ROOT/scripts/utils/print-and-run
-
for argument in "$@"; do
case "$argument" in
-*)
@@ -48,15 +49,6 @@ function checks {
fi
}
-function check_commit_signature {
- if ! git verify-commit HEAD; then
- log_error \
- "Current commit lacks valid signature. Releases can only be made from signed commits."
- exit 1
- fi
- echo ""
-}
-
function check_changelog {
previous_version=$(grep -oP '## \[\K[^\]]+' $changelog_path | head -2 | tail -1)
@@ -104,7 +96,6 @@ function update_product_version {
}
checks
-check_commit_signature
check_changelog
update_changelog
update_copyright_year
diff --git a/desktop/scripts/release/2-create-and-push-tag b/desktop/scripts/release/2-create-and-push-tag
index 17ff71edd6..eebec4e4e2 100755
--- a/desktop/scripts/release/2-create-and-push-tag
+++ b/desktop/scripts/release/2-create-and-push-tag
@@ -12,6 +12,8 @@ PRODUCT_VERSION_PATH=$REPO_ROOT/dist-assets/desktop-product-version.txt
PRODUCT_VERSION=$(cat $PRODUCT_VERSION_PATH)
BASE_URL="https://releases.mullvad.net/desktop/releases/$PRODUCT_VERSION"
+$REPO_ROOT/scripts/utils/commit-verification
+
source $REPO_ROOT/scripts/utils/print-and-run
source $REPO_ROOT/scripts/utils/log
@@ -53,7 +55,6 @@ function wait_for_build {
log_success "\nAll artifacts are now available"
}
-git verify-commit HEAD
push_tag
log_success "Follow build progress here: $BASE_URL"
diff --git a/desktop/scripts/release/3-verify-build b/desktop/scripts/release/3-verify-build
index f5156b2420..f9f07f24e9 100755
--- a/desktop/scripts/release/3-verify-build
+++ b/desktop/scripts/release/3-verify-build
@@ -14,6 +14,9 @@ PRODUCT_VERSION_PATH=$REPO_ROOT/dist-assets/desktop-product-version.txt
PRODUCT_VERSION=$(cat $PRODUCT_VERSION_PATH)
$REPO_ROOT/scripts/utils/gh-ready-check
+$REPO_ROOT/scripts/utils/commit-verification
+"$SCRIPT_DIR/verify-version-is-release"
+
source $REPO_ROOT/scripts/utils/log
WAIT="false"
diff --git a/desktop/scripts/release/4-make-release b/desktop/scripts/release/4-make-release
index 7274e50056..9766223ec0 100755
--- a/desktop/scripts/release/4-make-release
+++ b/desktop/scripts/release/4-make-release
@@ -8,43 +8,30 @@ set -eu
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd "$SCRIPT_DIR"
-if [ $# -ne 1 ]; then
- echo "Please provide the following arguments:"
- echo " $(basename "$0") \\"
- echo " <product version>"
- exit 1
-fi
+REPO_ROOT=../../../
+PRODUCT_VERSION_PATH=$REPO_ROOT/dist-assets/desktop-product-version.txt
+PRODUCT_VERSION=$(cat $PRODUCT_VERSION_PATH)
+CHANGELOG_PATH=$REPO_ROOT/CHANGELOG.md
-# 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
+$REPO_ROOT/scripts/utils/gh-ready-check
+$REPO_ROOT/scripts/utils/commit-verification
+"$SCRIPT_DIR/verify-version-is-release"
# shellcheck source=desktop/scripts/release/release-config.sh
source "$SCRIPT_DIR/release-config.sh"
+source $REPO_ROOT/scripts/utils/log
rm -rf "$ARTIFACT_DIR" && mkdir -p "$ARTIFACT_DIR" || exit 1
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"
+ log_header "Downloading changelog"
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_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 }')
@@ -75,14 +62,12 @@ function publish_release {
body+="\n$changelog"
- echo ""
- echo ">>> Creating GitHub release"
+ log_header "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."
+ log_success "\nThe above URL contains the text \"untagged\", but don't worry it is tagged properly and everything will look correct once it's published."
}
./download-release-artifacts "$PRODUCT_VERSION" "$ARTIFACT_DIR"
diff --git a/desktop/scripts/release/5-update-and-publish-metadata b/desktop/scripts/release/5-update-and-publish-metadata
index 0da2bde1ec..0805ff7c7b 100755
--- a/desktop/scripts/release/5-update-and-publish-metadata
+++ b/desktop/scripts/release/5-update-and-publish-metadata
@@ -10,10 +10,16 @@ set -eu
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd "$SCRIPT_DIR"
-if [ $# -ne 3 ]; then
+REPO_ROOT=../../../
+PRODUCT_VERSION_PATH=$REPO_ROOT/dist-assets/desktop-product-version.txt
+PRODUCT_VERSION=$(cat $PRODUCT_VERSION_PATH)
+
+$REPO_ROOT/scripts/utils/commit-verification
+"$SCRIPT_DIR/verify-version-is-release"
+
+if [ $# -ne 2 ]; then
echo "Please provide the following arguments:"
echo " $(basename "$0") \\"
- echo " <product version> \\"
echo " <build server SSH destination> \\"
echo " <metadata server SSH destination>"
echo ""
@@ -21,72 +27,67 @@ if [ $# -ne 3 ]; then
exit 1
fi
-PRODUCT_VERSION=$1
# The hostname (can be the alias in your ~/.ssh/config) of the build server
-BUILDSERVER_HOST=$2
+BUILDSERVER_HOST=$1
# The server to upload the metadata to *from* the build server (argument above)
-METADATA_SERVER_HOST=$3
+METADATA_SERVER_HOST=$2
# shellcheck source=desktop/scripts/release/release-config.sh
source "$SCRIPT_DIR/release-config.sh"
+source $REPO_ROOT/scripts/utils/log
function publish_metadata {
local platforms
platforms=(windows macos linux)
- local signed_dir="signed/"
- local work_dir="work/"
- local published_dir="currently_published/"
- local upload_dir="upload/"
- local latest_path="latest.json"
+ local signed_dir="$DATA_DIR/signed/"
+ local work_dir="$DATA_DIR/work/"
+ local published_dir="$DATA_DIR/currently_published/"
+ local upload_dir="$DATA_DIR/upload/"
+ local latest_filename="latest.json"
+
+ local mullvad_release="cargo run -q --package mullvad-release --"
rm -rf "$signed_dir"
rm -rf "$work_dir"
rm -rf "$published_dir"
rm -rf "$upload_dir"
- echo ">>> Fetching current version metadata"
- mullvad-release pull --assume-yes --latest-file "${platforms[@]}"
- echo ""
+ mkdir -p "$DATA_DIR"
- echo ">>> Backing up released data"
- cp -r $signed_dir $published_dir
- cp "$latest_path" "$published_dir"
- echo ""
+ log_header "Fetching current version metadata"
+ $mullvad_release pull --assume-yes --latest-file "${platforms[@]}"
+
+ log_header "Backing up released data"
+ cp -r "$signed_dir" "$published_dir"
+ cp "$DATA_DIR/$latest_filename" "$published_dir"
- echo ">>> Replacing $work_dir directory with latest published data"
+ log_header "Replacing $work_dir directory with latest published data"
cp -rf "$signed_dir" "$work_dir"
- echo ""
- echo ">>> Adding new release $PRODUCT_VERSION (rollout = 1)"
- mullvad-release add-release "$PRODUCT_VERSION" --rollout 1 "${platforms[@]}"
- echo ""
+ log_header "Adding new release $PRODUCT_VERSION (rollout = 1)"
+ $mullvad_release add-release "$PRODUCT_VERSION" --rollout 1 "${platforms[@]}"
- echo ">>> Signing $PRODUCT_VERSION metadata. Reading signing key from clipboard"
- xclip -sensitive | mullvad-release sign "${platforms[@]}"
- echo ""
+ log_header "Signing $PRODUCT_VERSION metadata. Reading signing key from clipboard"
+ xclip -sensitive | $mullvad_release sign "${platforms[@]}"
- echo ">>> Verifying signed metadata"
- mullvad-release verify "${platforms[@]}"
- echo ""
+ log_header "Verifying signed metadata"
+ $mullvad_release verify "${platforms[@]}"
- echo ">>> Creating upload dir"
+ log_header "Creating upload dir"
cp -rf "$signed_dir" "$upload_dir"
- echo ""
- echo ">>> Generating $latest_path for current version metadata"
- mullvad-release query-latest "${platforms[@]}" > "$upload_dir/$latest_path"
- echo ""
+ log_header "Generating $latest_filename for current version metadata"
+ $mullvad_release query-latest "${platforms[@]}" > "$upload_dir/$latest_filename"
- echo ">>> New metadata including $PRODUCT_VERSION"
- git --no-pager diff --no-index -- $published_dir $upload_dir || true
- echo ""
+ log_header "New metadata including $PRODUCT_VERSION"
+ git --no-pager diff --no-index -- "$published_dir" "$upload_dir" || true
read -rp "Press enter to upload if the diffs look good "
- ./publish-metadata-to-api $upload_dir "$BUILDSERVER_HOST" "$METADATA_SERVER_HOST"
+ ./publish-metadata-to-api "$upload_dir" "$BUILDSERVER_HOST" "$METADATA_SERVER_HOST"
}
function remove_release_artifacts {
- echo ">>> Cleaning up $ARTIFACT_DIR"
+ log_header "Cleaning up $ARTIFACT_DIR"
rm -r "$ARTIFACT_DIR"
}
diff --git a/desktop/scripts/release/6-modify-rollout b/desktop/scripts/release/6-modify-rollout
index b3993f50dc..8278dabe16 100755
--- a/desktop/scripts/release/6-modify-rollout
+++ b/desktop/scripts/release/6-modify-rollout
@@ -12,6 +12,9 @@ set -eu
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd "$SCRIPT_DIR"
+REPO_ROOT=../../../
+$REPO_ROOT/scripts/utils/commit-verification
+
if [ $# -lt 5 ]; then
echo "Please provide the following arguments:"
echo " $(basename "$0") \\"
@@ -39,61 +42,55 @@ PLATFORMS=("$@")
# shellcheck source=desktop/scripts/release/release-config.sh
source "$SCRIPT_DIR/release-config.sh"
+source $REPO_ROOT/scripts/utils/log
function modify_rollout {
- local signed_dir="signed/"
- local work_dir="work/"
- local published_dir="currently_published/"
- local upload_dir="upload/"
- local latest_file="latest.json"
+ local signed_dir="$DATA_DIR/signed/"
+ local work_dir="$DATA_DIR/work/"
+ local published_dir="$DATA_DIR/currently_published/"
+ local upload_dir="$DATA_DIR/upload/"
+ local latest_filename="latest.json"
local all_platforms=(linux macos windows)
+ local mullvad_release="cargo run -q --package mullvad-release --"
+
rm -rf "$signed_dir"
rm -rf "$work_dir"
rm -rf "$published_dir"
rm -rf "$upload_dir"
- echo ">>> Platforms:" "${PLATFORMS[@]}"
+ log_info "Platforms:" "${PLATFORMS[@]}"
- echo ">>> Fetching current version metadata"
- mullvad-release pull --latest-file --assume-yes "${all_platforms[@]}"
- echo ""
+ log_header "Fetching current version metadata"
+ $mullvad_release pull --latest-file --assume-yes "${all_platforms[@]}"
- echo ">>> Backing up released data"
- cp -r $signed_dir $published_dir
- mv "./$latest_file" "$published_dir/$latest_file"
- echo ""
+ log_header "Backing up released data"
+ cp -r "$signed_dir" "$published_dir"
+ mv "$DATA_DIR/$latest_filename" "$published_dir/$latest_filename"
- echo ">>> Replacing $work_dir directory with latest published data"
+ log_header "Replacing $work_dir directory with latest published data"
cp -rf "$signed_dir" "$work_dir"
- echo ""
- echo ">>> Setting rollout = $ROLLOUT for $PRODUCT_VERSION"
- mullvad-release modify-release "$PRODUCT_VERSION" --rollout "$ROLLOUT" "${PLATFORMS[@]}"
- echo ""
+ log_header "Setting rollout = $ROLLOUT for $PRODUCT_VERSION"
+ $mullvad_release modify-release "$PRODUCT_VERSION" --rollout "$ROLLOUT" "${PLATFORMS[@]}"
- echo ">>> Signing $PRODUCT_VERSION metadata. Reading signing key from clipboard"
- xclip -sensitive | mullvad-release sign "${PLATFORMS[@]}"
- echo ""
+ log_header "Signing $PRODUCT_VERSION metadata. Reading signing key from clipboard"
+ xclip -sensitive | $mullvad_release sign "${PLATFORMS[@]}"
- echo ">>> Verifying signed metadata"
- mullvad-release verify "${all_platforms[@]}"
- echo ""
+ log_header "Verifying signed metadata"
+ $mullvad_release verify "${all_platforms[@]}"
- echo ">>> Creating upload dir"
+ log_header "Creating upload dir"
cp -rf "$signed_dir" "$upload_dir"
- echo ""
- echo ">>> Generating $latest_file for current version metadata"
- mullvad-release query-latest "${all_platforms[@]}" > "$upload_dir/$latest_file"
- echo ""
+ log_header "Generating $latest_filename for current version metadata"
+ $mullvad_release query-latest "${all_platforms[@]}" > "$upload_dir/$latest_filename"
- echo ">>> New metadata including $PRODUCT_VERSION"
- git --no-pager diff --no-index -- $published_dir $upload_dir || true
- echo ""
+ log_header "New metadata including $PRODUCT_VERSION"
+ git --no-pager diff --no-index -- "$published_dir" "$upload_dir" || true
read -rp "Press enter to upload if the diffs look good "
- ./publish-metadata-to-api $upload_dir "$BUILDSERVER_HOST" "$METADATA_SERVER_HOST"
+ ./publish-metadata-to-api "$upload_dir" "$BUILDSERVER_HOST" "$METADATA_SERVER_HOST"
}
modify_rollout
diff --git a/desktop/scripts/release/download-release-artifacts b/desktop/scripts/release/download-release-artifacts
index aec0fbfe3e..4a83ac672f 100755
--- a/desktop/scripts/release/download-release-artifacts
+++ b/desktop/scripts/release/download-release-artifacts
@@ -22,10 +22,13 @@ ARTIFACT_DIR=$2
URL_BASE="https://releases.mullvad.net/desktop/releases"
+# shellcheck source-path=desktop/scripts/release
+source ./release-config.sh
+
mkdir -p "$ARTIFACT_DIR"
-# The signer key file "mullvad-code-signing-key.asc" is expected to exist in the current working directory.
-SIGNER_KEY_FILE="./mullvad-code-signing-key.asc"
+fingerprint_in_file=$(sq keyring list "$MULLVAD_CODE_SIGNING_KEY_PATH" | awk '{print $2}')
+test "$fingerprint_in_file" = "$MULLVAD_CODE_SIGNING_KEY_FINGERPRINT"
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}"
@@ -50,7 +53,7 @@ for ext in .exe _arm64.exe _x64.exe _amd64.deb _arm64.deb _x86_64.rpm _aarch64.r
echo ">>> Verifying integrity of $pkg_filename"
# We prefer sqv for PGP key verification as it a strict and easy-to-use implementation of PGP.
# gpg is also not suitable for use in scripting.
- if ! sqv --keyring "$SIGNER_KEY_FILE" "$pkg_path.asc" "$pkg_path"; then
+ if ! sqv --keyring "$MULLVAD_CODE_SIGNING_KEY_PATH" "$pkg_path.asc" "$pkg_path"; then
echo ""
echo "!!! INTEGRITY CHECKING FAILED !!!"
rm "$pkg_path" "$pkg_path.asc"
diff --git a/desktop/scripts/release/release-config.sh b/desktop/scripts/release/release-config.sh
index 3e053da880..3b412f35f7 100644
--- a/desktop/scripts/release/release-config.sh
+++ b/desktop/scripts/release/release-config.sh
@@ -2,7 +2,14 @@
# Configuration variables shared between the release scripts in this directory.
+# Where the release scripts and programs store temporary data
+export DATA_DIR="$HOME/.local/share/mullvad-release"
+
# Where to download app installers locally during the release process.
# This value is also hardcoded into the `mullvad-release` binary and
# has to be in sync with that value
-export ARTIFACT_DIR="artifacts"
+export ARTIFACT_DIR="$DATA_DIR/artifacts"
+
+# Mullvad code signing key and fingerprint
+export MULLVAD_CODE_SIGNING_KEY_PATH="../../../ci/keys/1.mullvad_signing.pub"
+export MULLVAD_CODE_SIGNING_KEY_FINGERPRINT="A1198702FC3E0A09A9AE5B75D5A1D4F266DE8DDF"
diff --git a/desktop/scripts/release/verify-version-is-release b/desktop/scripts/release/verify-version-is-release
new file mode 100755
index 0000000000..80fa12ec60
--- /dev/null
+++ b/desktop/scripts/release/verify-version-is-release
@@ -0,0 +1,8 @@
+#!/usr/bin/env bash
+
+set -eu
+
+version=$(cargo run -q --bin mullvad-version)
+if [[ "$version" == *-dev-* ]]; then
+ exit 1
+fi
diff --git a/mullvad-update/mullvad-release/src/main.rs b/mullvad-update/mullvad-release/src/main.rs
index 5089dbeb09..e9692d2577 100644
--- a/mullvad-update/mullvad-release/src/main.rs
+++ b/mullvad-update/mullvad-release/src/main.rs
@@ -5,7 +5,7 @@
use anyhow::{Context, bail};
use clap::Parser;
-use std::{path::Path, str::FromStr};
+use std::{path::PathBuf, str::FromStr};
use tokio::fs;
use config::Config;
@@ -172,7 +172,8 @@ async fn main() -> anyhow::Result<()> {
if latest_file {
match HttpVersionInfoProvider::get_latest_versions_file().await {
Ok(json_str) => {
- let path = Path::new(LATEST_FILENAME);
+ let path_buf = get_data_dir().join(LATEST_FILENAME);
+ let path = path_buf.as_path();
if !assume_yes && path.exists() {
let msg = format!(
@@ -336,3 +337,9 @@ fn all_platforms_if_empty(platforms: Vec<Platform>) -> Vec<Platform> {
}
platforms
}
+
+pub fn get_data_dir() -> PathBuf {
+ std::env::home_dir()
+ .expect("No home dir found")
+ .join(".local/share/mullvad-release")
+}
diff --git a/mullvad-update/mullvad-release/src/platform.rs b/mullvad-update/mullvad-release/src/platform.rs
index d7114e484a..caa81c7b81 100644
--- a/mullvad-update/mullvad-release/src/platform.rs
+++ b/mullvad-update/mullvad-release/src/platform.rs
@@ -8,17 +8,12 @@ use mullvad_update::{
MIN_VERIFY_METADATA_VERSION, Rollout, VersionArchitecture, VersionInfo, VersionParameters,
},
};
-use std::{
- cmp::Ordering,
- fmt,
- path::{Path, PathBuf},
- str::FromStr,
-};
+use std::{cmp::Ordering, fmt, path::PathBuf, str::FromStr};
use strum::IntoEnumIterator;
use tokio::{fs, io};
use crate::{
- artifacts,
+ artifacts, get_data_dir,
io_util::{create_dir_and_write, wait_for_confirm},
};
@@ -76,17 +71,17 @@ impl Platform {
/// Path to WIP file in `work/` for this platform
pub fn work_path(&self) -> PathBuf {
- Path::new("work").join(self.local_filename())
+ get_data_dir().join("work").join(self.local_filename())
}
/// Path to signed file in `signed/` for this platform
pub fn signed_path(&self) -> PathBuf {
- Path::new("signed").join(self.local_filename())
+ get_data_dir().join("signed").join(self.local_filename())
}
/// Expected artifacts in `artifacts/` directory
pub fn artifact_filenames(&self, version: &mullvad_version::Version) -> Artifacts {
- let artifacts_dir = Path::new("artifacts");
+ let artifacts_dir = get_data_dir().join("artifacts");
match self {
Platform::Windows => Artifacts {
x86_artifacts: vec![artifacts_dir.join(format!("MullvadVPN-{version}_x64.exe"))],
diff --git a/scripts/utils/commit-verification b/scripts/utils/commit-verification
new file mode 100755
index 0000000000..ffd38043fd
--- /dev/null
+++ b/scripts/utils/commit-verification
@@ -0,0 +1,14 @@
+#!/usr/bin/env bash
+
+set -eu
+
+SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+cd "$SCRIPT_DIR"
+
+# shellcheck disable=SC1091
+source ./log
+
+if ! git verify-commit HEAD; then
+ log_error "Current commit failed signature check"
+ exit 1
+fi