ops(web): bound immutable release history
This commit is contained in:
72
vehicle-data-platform/deploy/prepare-web-release-tree.sh
Executable file
72
vehicle-data-platform/deploy/prepare-web-release-tree.sh
Executable file
@@ -0,0 +1,72 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
NEW_WEB=${1:?new web root is required}
|
||||
OLD_WEB=${2:?old web root is required}
|
||||
MAX_COMPATIBILITY_GENERATIONS=${3:-3}
|
||||
|
||||
case "$MAX_COMPATIBILITY_GENERATIONS" in
|
||||
''|*[!0-9]*) printf 'invalid compatibility generation limit: %s\n' "$MAX_COMPATIBILITY_GENERATIONS" >&2; exit 1 ;;
|
||||
esac
|
||||
test "$MAX_COMPATIBILITY_GENERATIONS" -ge 1 || { printf 'compatibility generation limit must be positive\n' >&2; exit 1; }
|
||||
test -f "$NEW_WEB/.release-assets" || { printf 'new release manifest is missing\n' >&2; exit 1; }
|
||||
test -f "$OLD_WEB/.release-assets" || { printf 'old release manifest is missing\n' >&2; exit 1; }
|
||||
mkdir -p "$NEW_WEB/assets" "$NEW_WEB/.compatibility-manifests"
|
||||
|
||||
validate_asset() {
|
||||
local asset=$1
|
||||
case "$asset" in
|
||||
''|/*|*/*|.|..) printf 'unsafe release asset: %s\n' "$asset" >&2; return 1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
while IFS= read -r asset || test -n "$asset"; do
|
||||
asset=${asset%$'\r'}
|
||||
test -n "$asset" || continue
|
||||
validate_asset "$asset"
|
||||
test -f "$NEW_WEB/assets/$asset" || { printf 'current asset is missing: %s\n' "$NEW_WEB/assets/$asset" >&2; exit 1; }
|
||||
done < "$NEW_WEB/.release-assets"
|
||||
|
||||
copy_manifest_assets() {
|
||||
local manifest=$1
|
||||
local asset source destination
|
||||
while IFS= read -r asset || test -n "$asset"; do
|
||||
asset=${asset%$'\r'}
|
||||
test -n "$asset" || continue
|
||||
validate_asset "$asset"
|
||||
source="$OLD_WEB/assets/$asset"
|
||||
destination="$NEW_WEB/assets/$asset"
|
||||
test -f "$source" || { printf 'compatibility asset is missing: %s\n' "$source" >&2; return 1; }
|
||||
if test -f "$destination"; then
|
||||
cmp -s "$source" "$destination" || { printf 'asset hash collision has different content: %s\n' "$asset" >&2; return 1; }
|
||||
else
|
||||
cp "$source" "$destination"
|
||||
fi
|
||||
done < "$manifest"
|
||||
}
|
||||
|
||||
cp "$OLD_WEB/.release-assets" "$NEW_WEB/.compatibility-manifests/1.assets"
|
||||
generation=2
|
||||
while test "$generation" -le "$MAX_COMPATIBILITY_GENERATIONS"; do
|
||||
previous=$((generation - 1))
|
||||
source_manifest="$OLD_WEB/.compatibility-manifests/$previous.assets"
|
||||
test -f "$source_manifest" || break
|
||||
cp "$source_manifest" "$NEW_WEB/.compatibility-manifests/$generation.assets"
|
||||
generation=$((generation + 1))
|
||||
done
|
||||
|
||||
compatibility_manifest="$NEW_WEB/.compatibility-assets"
|
||||
: > "$compatibility_manifest"
|
||||
for manifest in "$NEW_WEB"/.compatibility-manifests/*.assets; do
|
||||
test -f "$manifest" || continue
|
||||
copy_manifest_assets "$manifest"
|
||||
cat "$manifest" >> "$compatibility_manifest"
|
||||
done
|
||||
LC_ALL=C sort -u "$compatibility_manifest" -o "$compatibility_manifest"
|
||||
|
||||
current_count=$(awk 'NF { count += 1 } END { print count + 0 }' "$NEW_WEB/.release-assets")
|
||||
compatibility_count=$(awk 'NF { count += 1 } END { print count + 0 }' "$compatibility_manifest")
|
||||
generation_count=$(find "$NEW_WEB/.compatibility-manifests" -maxdepth 1 -type f -name '*.assets' | wc -l | tr -d ' ')
|
||||
served_count=$(find "$NEW_WEB/assets" -maxdepth 1 -type f | wc -l | tr -d ' ')
|
||||
printf 'web_release_tree=ok current_assets=%s compatibility_assets=%s compatibility_generations=%s served_assets=%s\n' "$current_count" "$compatibility_count" "$generation_count" "$served_count"
|
||||
Reference in New Issue
Block a user