103 lines
3.1 KiB
Bash
Executable File
103 lines
3.1 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
umask 077
|
|
|
|
ROOT=$(CDPATH='' cd -- "$(dirname -- "$0")/.." && pwd)
|
|
|
|
if [[ -n "$(git -C "$ROOT" status --porcelain --untracked-files=normal)" ]]; then
|
|
echo "Refusing to package a release from a dirty checkout." >&2
|
|
exit 1
|
|
fi
|
|
|
|
commit=$(git -C "$ROOT" rev-parse --verify HEAD)
|
|
short_commit=${commit:0:12}
|
|
artifact_root=${WNH_PRODUCTION_RELEASE_ARTIFACT_ROOT:-"$ROOT/output/releases"}
|
|
case "$artifact_root" in
|
|
/*) ;;
|
|
*)
|
|
echo "WNH_PRODUCTION_RELEASE_ARTIFACT_ROOT must be an absolute path." >&2
|
|
exit 2
|
|
;;
|
|
esac
|
|
mkdir -p "$artifact_root"
|
|
artifact_root=$(realpath --canonicalize-existing "$artifact_root")
|
|
release_dir="$artifact_root/$commit"
|
|
bundle="$release_dir/who_need_help-$commit.bundle"
|
|
checksum="$bundle.sha256"
|
|
manifest="$release_dir/manifest.txt"
|
|
|
|
if [[ -e "$release_dir" ]]; then
|
|
[[ ! -L "$release_dir" && -d "$release_dir" &&
|
|
"$(stat -c '%u' "$release_dir")" == "$(id -u)" &&
|
|
"$(stat -c '%a' "$release_dir")" == 700 ]] || {
|
|
echo "Existing release directory must be an owned mode-0700 directory: $release_dir" >&2
|
|
exit 2
|
|
}
|
|
else
|
|
install -d -m 700 "$release_dir"
|
|
fi
|
|
|
|
if [[ -e "$bundle" || -e "$checksum" || -e "$manifest" ]]; then
|
|
echo "Release package already exists; verifying it instead of overwriting it."
|
|
else
|
|
git -C "$ROOT" bundle create "$bundle" HEAD
|
|
chmod 600 "$bundle"
|
|
hash=$(sha256sum "$bundle" | awk '{print $1}')
|
|
printf '%s %s\n' "$hash" "$(basename -- "$bundle")" >"$checksum"
|
|
{
|
|
printf 'commit=%s\n' "$commit"
|
|
printf 'short_commit=%s\n' "$short_commit"
|
|
printf 'created_at=%s\n' "$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
|
printf 'bundle_sha256=%s\n' "$hash"
|
|
} >"$manifest"
|
|
chmod 600 "$checksum" "$manifest"
|
|
fi
|
|
|
|
(
|
|
cd "$release_dir"
|
|
sha256sum --check "$(basename -- "$checksum")" >/dev/null
|
|
)
|
|
git -C "$ROOT" bundle verify "$bundle" >/dev/null
|
|
|
|
bundle_hash=$(sha256sum "$bundle" | awk '{print $1}')
|
|
expected_checksum="$bundle_hash $(basename -- "$bundle")"
|
|
if [[ "$(cat -- "$checksum")" != "$expected_checksum" ]]; then
|
|
echo "Release bundle checksum metadata does not name the exact bundle." >&2
|
|
exit 1
|
|
fi
|
|
|
|
manifest_value() {
|
|
local key=$1
|
|
awk -F= -v key="$key" '
|
|
$1 == key { count += 1; value = substr($0, length(key) + 2) }
|
|
END {
|
|
if (count != 1) exit 1
|
|
print value
|
|
}
|
|
' "$manifest"
|
|
}
|
|
|
|
[[ "$(manifest_value commit)" == "$commit" ]] || {
|
|
echo "Release manifest commit does not match the current commit." >&2
|
|
exit 1
|
|
}
|
|
[[ "$(manifest_value short_commit)" == "$short_commit" ]] || {
|
|
echo "Release manifest short commit does not match the current commit." >&2
|
|
exit 1
|
|
}
|
|
[[ "$(manifest_value bundle_sha256)" == "$bundle_hash" ]] || {
|
|
echo "Release manifest bundle checksum does not match the bundle." >&2
|
|
exit 1
|
|
}
|
|
|
|
bundle_head=$(git -C "$ROOT" bundle list-heads "$bundle" | awk '$2 == "HEAD" {print $1}')
|
|
if [[ "$bundle_head" != "$commit" ]]; then
|
|
echo "Release bundle HEAD does not match the current commit." >&2
|
|
exit 1
|
|
fi
|
|
|
|
printf 'Release commit: %s\n' "$commit"
|
|
printf 'Bundle: %s\n' "$bundle"
|
|
printf 'Checksum: %s\n' "$checksum"
|
|
printf 'Manifest: %s\n' "$manifest"
|