mirror of
https://github.com/sudosylabs/vnidrop.git
synced 2026-08-05 10:29:58 +02:00
ci: add coordinated release pipeline
This commit is contained in:
169
packaging/release/assemble-release.sh
Executable file
169
packaging/release/assemble-release.sh
Executable file
@@ -0,0 +1,169 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
repo_root="$(cd "$script_dir/../.." && pwd)"
|
||||
resolver="$repo_root/packaging/version/resolve-version.sh"
|
||||
input_dir="${VNIDROP_RELEASE_INPUT_DIR:-$repo_root/build/release/downloads}"
|
||||
output_dir="${VNIDROP_RELEASE_OUTPUT_DIR:-$repo_root/build/release/final}"
|
||||
source_commit="${GITHUB_SHA:-local}"
|
||||
source_tag="${GITHUB_REF_NAME:-v$("$resolver" product)}"
|
||||
|
||||
find_single() {
|
||||
local directory=$1
|
||||
local pattern=$2
|
||||
local label=$3
|
||||
local matches=()
|
||||
local match
|
||||
while IFS= read -r match; do
|
||||
matches+=("$match")
|
||||
done < <(find "$directory" -type f -name "$pattern" -print)
|
||||
[[ ${#matches[@]} == 1 ]] || {
|
||||
printf 'Expected exactly one %s under %s, found %s\n' \
|
||||
"$label" "$directory" "${#matches[@]}" >&2
|
||||
exit 1
|
||||
}
|
||||
printf '%s' "${matches[0]}"
|
||||
}
|
||||
|
||||
file_size() {
|
||||
if stat -c '%s' "$1" >/dev/null 2>&1; then
|
||||
stat -c '%s' "$1"
|
||||
else
|
||||
stat -f '%z' "$1"
|
||||
fi
|
||||
}
|
||||
|
||||
verify_checksum_file() {
|
||||
local checksum_file=$1
|
||||
(
|
||||
cd "$(dirname "$checksum_file")"
|
||||
sha256sum --check "$(basename "$checksum_file")"
|
||||
)
|
||||
}
|
||||
|
||||
version="$("$resolver" product)"
|
||||
android_code="$("$resolver" android-code)"
|
||||
apple_build="$("$resolver" apple-build)"
|
||||
windows_package="$("$resolver" windows-package)"
|
||||
"$resolver" verify >/dev/null
|
||||
[[ $source_tag == "v$version" ]] || {
|
||||
printf 'Release tag %s does not match canonical version v%s\n' \
|
||||
"$source_tag" "$version" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
deb="$(find_single "$input_dir/deb" '*.deb' 'Debian package')"
|
||||
rpm="$(find_single "$input_dir/rpm" '*.rpm' 'RPM package')"
|
||||
dmg="$(find_single "$input_dir/macos" '*.dmg' 'macOS DMG')"
|
||||
appcast="$(find_single "$input_dir/macos" 'appcast.xml' 'Sparkle appcast')"
|
||||
play_apk="$(find_single "$input_dir/play" '*-play-universal.apk' 'Play-signed APK')"
|
||||
play_metadata="$(find_single "$input_dir/play" 'play-release.json' 'Play release metadata')"
|
||||
msix="$(find_single "$input_dir/windows" '*.msix' 'Windows MSIX')"
|
||||
msixupload="$(find_single "$input_dir/windows" '*.msixupload' 'Windows MSIX upload')"
|
||||
windows_metadata="$(find_single "$input_dir/windows" '*.build-info.json' 'Windows build metadata')"
|
||||
|
||||
[[ $(basename "$deb") == "vnidrop_${version}-1_amd64.deb" ]]
|
||||
[[ $(basename "$rpm") == "vnidrop-${version}-1.x86_64.rpm" ]]
|
||||
[[ $(basename "$dmg") == "VniDrop-${version}.dmg" ]]
|
||||
[[ $(basename "$play_apk") == "VniDrop-${version}-${android_code}-play-universal.apk" ]]
|
||||
[[ $(basename "$msix") == "VniDrop_${version}_x64.msix" ]]
|
||||
[[ $(basename "$msixupload") == "VniDrop_${version}_x64.msixupload" ]]
|
||||
|
||||
deb_checksum="$(find_single "$input_dir/deb" '*.sha256' 'Debian checksum')"
|
||||
rpm_checksum="$(find_single "$input_dir/rpm" '*.sha256' 'RPM checksum')"
|
||||
windows_checksums="$(find_single "$input_dir/windows" 'SHA256SUMS' 'Windows checksums')"
|
||||
play_checksums="$(find_single "$input_dir/play" 'SHA256SUMS' 'Play APK checksums')"
|
||||
verify_checksum_file "$deb_checksum"
|
||||
verify_checksum_file "$rpm_checksum"
|
||||
verify_checksum_file "$windows_checksums"
|
||||
verify_checksum_file "$play_checksums"
|
||||
|
||||
[[ $(jq -r '.releaseStatus' "$play_metadata") == draft ]]
|
||||
[[ $(jq -r '.releaseName' "$play_metadata") == "$version" ]]
|
||||
[[ $(jq -r '.versionCode' "$play_metadata") == "$android_code" ]]
|
||||
play_track="$(jq -r '.track' "$play_metadata")"
|
||||
normalized_play_track="$(printf '%s' "$play_track" | tr '[:upper:]' '[:lower:]')"
|
||||
[[ $normalized_play_track != production && $normalized_play_track != *:production ]]
|
||||
[[ $(jq -r '.appVersion' "$windows_metadata") == "$version" ]]
|
||||
[[ $(jq -r '.packageVersion' "$windows_metadata") == "$windows_package" ]]
|
||||
grep -F "VniDrop-${version}.dmg" "$appcast" >/dev/null
|
||||
|
||||
mkdir -p "$output_dir"
|
||||
[[ -z $(find "$output_dir" -mindepth 1 -maxdepth 1 -print -quit) ]] || {
|
||||
printf 'Release output directory must be empty: %s\n' "$output_dir" >&2
|
||||
exit 1
|
||||
}
|
||||
cp "$deb" "$rpm" "$dmg" "$appcast" "$play_apk" "$output_dir/"
|
||||
|
||||
payloads=(
|
||||
"$output_dir/$(basename "$deb")"
|
||||
"$output_dir/$(basename "$rpm")"
|
||||
"$output_dir/$(basename "$dmg")"
|
||||
"$output_dir/$(basename "$appcast")"
|
||||
"$output_dir/$(basename "$play_apk")"
|
||||
)
|
||||
files_json="$(
|
||||
for file in "${payloads[@]}"; do
|
||||
jq -n \
|
||||
--arg name "$(basename "$file")" \
|
||||
--arg sha256 "$(sha256sum "$file" | awk '{print $1}')" \
|
||||
--argjson bytes "$(file_size "$file")" \
|
||||
'{name: $name, sha256: $sha256, bytes: $bytes}'
|
||||
done | jq -s .
|
||||
)"
|
||||
|
||||
jq -n \
|
||||
--arg productVersion "$version" \
|
||||
--arg releaseChannel "$("$resolver" channel)" \
|
||||
--arg tag "$source_tag" \
|
||||
--arg commit "$source_commit" \
|
||||
--arg androidVersionCode "$android_code" \
|
||||
--arg appleBuildNumber "$apple_build" \
|
||||
--arg windowsPackageVersion "$windows_package" \
|
||||
--arg windowsMsixUpload "$(basename "$msixupload")" \
|
||||
--arg windowsMsixUploadSha256 "$(sha256sum "$msixupload" | awk '{print $1}')" \
|
||||
--arg playTrack "$play_track" \
|
||||
--arg playBundleSha256 "$(jq -r '.bundleSha256' "$play_metadata")" \
|
||||
--arg playCertificateSha256 "$(jq -r '.appSigningCertificateSha256' "$play_metadata")" \
|
||||
--argjson files "$files_json" \
|
||||
'{
|
||||
productVersion: $productVersion,
|
||||
releaseChannel: $releaseChannel,
|
||||
tag: $tag,
|
||||
sourceCommit: $commit,
|
||||
platformVersions: {
|
||||
androidVersionCode: ($androidVersionCode | tonumber),
|
||||
appleBuildNumber: $appleBuildNumber,
|
||||
windowsPackageVersion: $windowsPackageVersion
|
||||
},
|
||||
play: {
|
||||
track: $playTrack,
|
||||
status: "draft",
|
||||
bundleSha256: $playBundleSha256,
|
||||
appSigningCertificateSha256: $playCertificateSha256
|
||||
},
|
||||
windowsStore: {
|
||||
publicReleaseAsset: false,
|
||||
msixUpload: $windowsMsixUpload,
|
||||
sha256: $windowsMsixUploadSha256
|
||||
},
|
||||
files: $files
|
||||
}' > "$output_dir/release-manifest.json"
|
||||
|
||||
(
|
||||
cd "$output_dir"
|
||||
sha256sum \
|
||||
"$(basename "$deb")" \
|
||||
"$(basename "$rpm")" \
|
||||
"$(basename "$dmg")" \
|
||||
"$(basename "$appcast")" \
|
||||
"$(basename "$play_apk")" \
|
||||
release-manifest.json \
|
||||
> SHA256SUMS
|
||||
)
|
||||
|
||||
printf 'Assembled public release assets in %s\n' "$output_dir"
|
||||
printf 'Windows Store submission retained as workflow artifact: %s\n' \
|
||||
"$(basename "$msixupload")"
|
||||
Reference in New Issue
Block a user