Skip to content

Commit

Permalink
Add APT repository preparation and upload scripts
Browse files Browse the repository at this point in the history
Build an apt/deb repository on builds and store locally on the build
server. Also push it to development infra instantly. Push to staging if
it's a release. And store locally for manual push to production later
  • Loading branch information
faern committed Oct 20, 2023
1 parent 2865b64 commit 32d182b
Show file tree
Hide file tree
Showing 4 changed files with 171 additions and 0 deletions.
18 changes: 18 additions & 0 deletions ci/buildserver-build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ UPLOAD_DIR="$SCRIPT_DIR/upload"

BRANCHES_TO_BUILD=("origin/main")

source "$SCRIPT_DIR/buildserver-config.sh"

# Ask for the passphrase to the signing keys
case "$(uname -s)" in
Darwin*|MINGW*|MSYS_NT*)
Expand All @@ -42,6 +44,21 @@ case "$(uname -s)" in
;;
esac

function publish_linux_repositories {
local artifact_dir=$1
local version=$2
local deb_repo_dir="$SCRIPT_DIR/deb/$version"

"$SCRIPT_DIR/prepare-apt-repository.sh" "$artifact_dir" "$version" "$deb_repo_dir"

"$SCRIPT_DIR/publish-linux-repositories.sh" --dev "$version" "$deb_repo_dir"
# If this is a release build, also push to staging.
# Publishing to production is done manually.
if [[ $version != *"-dev-"* ]]; then
"$SCRIPT_DIR/publish-linux-repositories.sh" --staging "$version" "$deb_repo_dir"
fi
}

# Uploads whatever matches the first argument to the Linux build server
function upload_sftp {
echo "Uploading Mullvad VPN installers to app-build-linux:upload/"
Expand Down Expand Up @@ -210,6 +227,7 @@ function build_ref {
fi
fi

publish_linux_repositories "$artifact_dir" "$version"
(cd "$artifact_dir" && upload "$version") || return 1
# shellcheck disable=SC2216
yes | rm -r "$artifact_dir"
Expand Down
18 changes: 18 additions & 0 deletions ci/buildserver-config.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/usr/bin/env bash
#
# Buildserver configuration. Runtime values are defined here instead of
# the scripts where they are used.

# Which gpg key to sign things with
export CODE_SIGNING_KEY_FINGERPRINT="A1198702FC3E0A09A9AE5B75D5A1D4F266DE8DDF"

# Debian codenames we support.
SUPPORTED_DEB_CODENAMES=("sid" "testing" "bookworm" "bullseye")
# Ubuntu codenames we support (latest two LTS + latest non-LTS)
SUPPORTED_DEB_CODENAMES+=("jammy" "focal" "lunar")
export SUPPORTED_DEB_CODENAMES

# Servers to upload Linux deb/rpm repositories to
export DEV_LINUX_REPOSITORY_SERVERS=("se-got-cdn-001.devmole.eu" "se-got-cdn-002.devmole.eu")
export STAGING_LINUX_REPOSITORY_SERVERS=("se-got-cdn-001.stagemole.eu" "se-got-cdn-002.stagemole.eu")
export PRODUCTION_LINUX_REPOSITORY_SERVERS=("se-got-cdn-111.mullvad.net" "se-mma-cdn-101.mullvad.net")
59 changes: 59 additions & 0 deletions ci/prepare-apt-repository.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#!/usr/bin/env bash
#
# Usage: ./prepare-apt-repository.sh <artifact dir> <app version> <repository dir>
#
# Will create a deb repository in <repository dir> and add all .deb files from
# <artifact dir> matching <app version> to the repository.

set -eu

SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

source "$SCRIPT_DIR/buildserver-config.sh"

artifact_dir=$1
version=$2
repo_dir=$3

function generate_repository_configuration {
local codename=$1

echo -e "Origin: repository.mullvad.net
Label: Mullvad apt repository
Description: Mullvad package repository for Debian/Ubuntu
Codename: $codename
Architectures: amd64 arm64
Components: main
SignWith: $CODE_SIGNING_KEY_FINGERPRINT"
}

function generate_deb_distributions_content {
local distributions=""
for codename in "${SUPPORTED_DEB_CODENAMES[@]}"; do
distributions+=$(generate_repository_configuration "$codename")$'\n'$'\n'
distributions+=$(generate_repository_configuration "$codename"-testing)$'\n'$'\n'
done
echo "$distributions"
}

function add_deb_to_repo {
local deb_path=$1
local codename=$2
echo "Adding $deb_path to repository $codename"
reprepro -V --basedir "$repo_dir" --component main includedeb "$codename" "$deb_path"
}

echo "Generating deb repository into $repo_dir/"
mkdir -p "$repo_dir/conf"

echo "Writing repository configuration to $repo_dir/conf/distributions"
generate_deb_distributions_content > "$repo_dir/conf/distributions"
echo ""

for deb_path in "$artifact_dir"/MullvadVPN-"$version"*.deb; do
for codename in "${SUPPORTED_DEB_CODENAMES[@]}"; do
add_deb_to_repo "$deb_path" "$codename"
echo ""
done
echo ""
done
76 changes: 76 additions & 0 deletions ci/publish-linux-repositories.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#!/usr/bin/env bash
#
# Usage: ./publish-linux-repositories.sh [--production/--staging] <app version> <deb repository dir>
#
# Rsyncs a locally prepared and stored apt repository to the dev/staging/production
# repository servers.

set -eu

SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

source "$SCRIPT_DIR/buildserver-config.sh"

while [ "$#" -gt 0 ]; do
case "$1" in
"--production")
repository_servers=("${PRODUCTION_LINUX_REPOSITORY_SERVERS[@]}")
;;
"--staging")
repository_servers=("${STAGING_LINUX_REPOSITORY_SERVERS[@]}")
;;
"--dev")
repository_servers=("${DEV_LINUX_REPOSITORY_SERVERS[@]}")
;;
-*)
echo "Unknown option \"$1\"" >&2
exit 1
;;
*)
if [[ -z ${version+x} ]]; then
version=$1
elif [[ -z ${deb_repo_dir+x} ]]; then
deb_repo_dir=$1
else
echo "Too many arguments" >&2
exit 1
fi
;;
esac
shift
done

if [[ -z ${version+x} ]]; then
echo "Please give the release version as an argument to this script" >&2
exit 1
fi
if [[ -z ${deb_repo_dir+x} ]]; then
echo "Please specify the deb repository directory as an argument to this script" >&2
exit 1
fi
if [[ -z ${repository_servers+x} ]]; then
echo "Pass either --dev, --staging or --production to select target servers" >&2
exit 1
fi

function rsync_repo {
local local_repo_dir=$1
local remote_repo_dir=$2

for server in "${repository_servers[@]}"; do
echo "Syncing to $server:$remote_repo_dir"
rsync -av --delete --mkpath --rsh='ssh -p 1122' \
"$local_repo_dir"/ \
build@"$server":"$remote_repo_dir"
done
}

if [[ ! -d "$deb_repo_dir" ]]; then
echo "$deb_repo_dir does not exist" >&2
exit 1
fi

rsync_repo "$deb_repo_dir" "deb/beta"
if [[ $version != *"-beta"* ]]; then
rsync_repo "$deb_repo_dir" "deb/stable"
fi

0 comments on commit 32d182b

Please sign in to comment.