mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-08-01 19:18:28 -04:00
ffd3840058
(cherry picked from commit 0fdfac366e)
171 lines
5.2 KiB
Bash
Executable File
171 lines
5.2 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
set -euo pipefail
|
|
|
|
usage() {
|
|
echo "usage: $0 download|publish" >&2
|
|
exit 2
|
|
}
|
|
|
|
require_env() {
|
|
local name
|
|
for name in "$@"; do
|
|
if [[ -z "${!name:-}" ]]; then
|
|
echo "error: $name is required" >&2
|
|
exit 2
|
|
fi
|
|
done
|
|
}
|
|
|
|
require_env R2_BUCKET R2_ENDPOINT R2_PREFIX REPOSITORY_DIR
|
|
|
|
aws_r2() {
|
|
aws --endpoint-url "$R2_ENDPOINT" "$@"
|
|
}
|
|
|
|
download() {
|
|
mkdir -p "$REPOSITORY_DIR/current" "$REPOSITORY_DIR/previous-current"
|
|
|
|
aws_r2 s3 sync \
|
|
"s3://${R2_BUCKET}/${R2_PREFIX}/current/" \
|
|
"$REPOSITORY_DIR/current/" \
|
|
--only-show-errors
|
|
|
|
cp -a "$REPOSITORY_DIR/current/." "$REPOSITORY_DIR/previous-current/"
|
|
}
|
|
|
|
build_manifest() {
|
|
local packages='[]'
|
|
local file filename pkgver name version revision sha size
|
|
|
|
for file in "$REPOSITORY_DIR"/current/*.xbps; do
|
|
filename="$(basename "$file")"
|
|
pkgver="$(xbps-uhelper binpkgver "$filename")"
|
|
name="$(xbps-uhelper getpkgname "$pkgver")"
|
|
version="$(xbps-uhelper getpkgversion "$pkgver")"
|
|
revision="$(xbps-uhelper getpkgrevision "$pkgver")"
|
|
version="${version%_"${revision}"}"
|
|
sha="$(sha256sum "$file" | cut -d' ' -f1)"
|
|
size="$(stat -c '%s' "$file")"
|
|
packages="$(jq \
|
|
--arg name "$name" \
|
|
--arg version "$version" \
|
|
--arg revision "$revision" \
|
|
--arg filename "$filename" \
|
|
--arg sha256 "$sha" \
|
|
--argjson size "$size" \
|
|
'. + [{name: $name, version: $version, revision: $revision, filename: $filename, sha256: $sha256, size: $size}]' \
|
|
<<<"$packages")"
|
|
done
|
|
|
|
jq -n \
|
|
--arg repository "$R2_PREFIX" \
|
|
--arg source_commit "$SOURCE_COMMIT" \
|
|
--arg published_at "$PUBLISHED_AT" \
|
|
--argjson packages "$packages" \
|
|
'{schema: 1, repository: $repository, source_commit: $source_commit, published_at: $published_at, packages: $packages}' \
|
|
> "$REPOSITORY_DIR/current/manifest.json"
|
|
}
|
|
|
|
verify_immutable_packages() {
|
|
local file previous
|
|
|
|
for file in "$REPOSITORY_DIR"/current/*.xbps "$REPOSITORY_DIR"/current/*.sig2; do
|
|
previous="$REPOSITORY_DIR/previous-current/$(basename "$file")"
|
|
if [[ -f "$previous" ]] && ! cmp -s "$previous" "$file"; then
|
|
echo "error: refusing to replace immutable object $(basename "$file")" >&2
|
|
echo "bump the XBPS revision or version before publishing a changed build" >&2
|
|
exit 1
|
|
fi
|
|
done
|
|
}
|
|
|
|
archive_retired() {
|
|
local old filename
|
|
local archive_prefix="archive/${R2_PREFIX}/${PUBLISHED_AT//:/-}"
|
|
|
|
shopt -s nullglob
|
|
for old in "$REPOSITORY_DIR"/previous-current/*.xbps "$REPOSITORY_DIR"/previous-current/*.sig2; do
|
|
filename="$(basename "$old")"
|
|
if [[ ! -e "$REPOSITORY_DIR/current/$filename" ]]; then
|
|
aws_r2 s3 cp \
|
|
"$old" \
|
|
"s3://${R2_BUCKET}/${archive_prefix}/${filename}" \
|
|
--cache-control 'private,no-store' \
|
|
--only-show-errors
|
|
fi
|
|
done
|
|
}
|
|
|
|
upload_current() {
|
|
local file filename old
|
|
|
|
# Versioned package objects must exist before repodata can reference them.
|
|
for file in "$REPOSITORY_DIR"/current/*.xbps "$REPOSITORY_DIR"/current/*.sig2; do
|
|
filename="$(basename "$file")"
|
|
aws_r2 s3 cp \
|
|
"$file" \
|
|
"s3://${R2_BUCKET}/${R2_PREFIX}/current/${filename}" \
|
|
--cache-control 'public,max-age=31536000,immutable' \
|
|
--only-show-errors
|
|
done
|
|
|
|
aws_r2 s3 cp \
|
|
"$REPOSITORY_DIR/current/x86_64-repodata" \
|
|
"s3://${R2_BUCKET}/${R2_PREFIX}/current/x86_64-repodata" \
|
|
--cache-control 'no-cache' \
|
|
--only-show-errors
|
|
|
|
# The manifest is the publication marker and is always uploaded last.
|
|
aws_r2 s3 cp \
|
|
"$REPOSITORY_DIR/current/manifest.json" \
|
|
"s3://${R2_BUCKET}/${R2_PREFIX}/current/manifest.json" \
|
|
--cache-control 'no-cache' \
|
|
--only-show-errors
|
|
|
|
# Once the new index and marker are live, remove objects no longer referenced.
|
|
shopt -s nullglob
|
|
for old in "$REPOSITORY_DIR"/previous-current/*; do
|
|
filename="$(basename "$old")"
|
|
if [[ ! -e "$REPOSITORY_DIR/current/$filename" ]]; then
|
|
aws_r2 s3 rm \
|
|
"s3://${R2_BUCKET}/${R2_PREFIX}/current/${filename}" \
|
|
--only-show-errors
|
|
fi
|
|
done
|
|
}
|
|
|
|
publish() {
|
|
require_env SOURCE_COMMIT
|
|
PUBLISHED_AT="${PUBLISHED_AT:-$(date -u +'%Y-%m-%dT%H:%M:%SZ')}"
|
|
export PUBLISHED_AT
|
|
|
|
shopt -s nullglob
|
|
local packages=("$REPOSITORY_DIR"/current/*.xbps)
|
|
if (( ${#packages[@]} == 0 )); then
|
|
echo "error: refusing to publish an empty XBPS repository" >&2
|
|
exit 1
|
|
fi
|
|
[[ -s "$REPOSITORY_DIR/current/x86_64-repodata" ]] || {
|
|
echo "error: x86_64-repodata is missing or empty" >&2
|
|
exit 1
|
|
}
|
|
for file in "${packages[@]}"; do
|
|
[[ -s "${file}.sig2" ]] || {
|
|
echo "error: signature is missing for $(basename "$file")" >&2
|
|
exit 1
|
|
}
|
|
done
|
|
|
|
verify_immutable_packages
|
|
build_manifest
|
|
archive_retired
|
|
upload_current
|
|
}
|
|
|
|
case "${1:-}" in
|
|
download) download ;;
|
|
publish) publish ;;
|
|
*) usage ;;
|
|
esac
|