- ship: no interactive override of the untested-commit guard; the tag targets the pinned commit the artifacts were built from (never the branch head); a tagged-but-incomplete train is found and resumed instead of vanishing from open-train detection; a fully shipped train reports as such - start: a failed edge→rc advance fails the command loudly (both start and the advance are idempotent) instead of opening a train against stale rc - rc trigger: bootstraps the server's rc worktree on first use, so a host set up before the rc branch existed can run its first RC build - advance-channel: fast-ring packages are excluded from edge→rc (the stable build replicated by parity is authoritative for rc — same filename, other bytes); differing destination bytes abort instead of warn; a package whose signature copy was interrupted gets its .sig restored on resume - the release lock now also covers direct promote/update/clean/remove/sync invocations, not just release/advance/upload-prebuilt
251 lines
6.4 KiB
Bash
Executable File
251 lines
6.4 KiB
Bash
Executable File
#!/bin/bash
|
|
# Omarchy Repository Cleaner
|
|
# Removes old package versions keeping only the latest
|
|
|
|
set -e
|
|
|
|
# Source common functions
|
|
BUILD_ROOT=$(realpath "${BASH_SOURCE[0]%/*}/..")
|
|
source "$BUILD_ROOT/helpers/message-helpers.sh"
|
|
source "$BUILD_ROOT/helpers/paths.sh"
|
|
source "$BUILD_ROOT/helpers/lock-helpers.sh"
|
|
|
|
# Repository configuration
|
|
KEEP_VERSIONS=2
|
|
|
|
# Function to clean old packages
|
|
clean_packages() {
|
|
local keep=$1
|
|
local dry_run=$2
|
|
|
|
print_info "Cleaning old packages (keeping $keep versions)..."
|
|
|
|
cd "$REPO_DIR"
|
|
|
|
# Group packages by name
|
|
declare -A packages
|
|
|
|
for pkg in *.pkg.tar.*; do
|
|
[[ -f "$pkg" ]] || continue
|
|
|
|
# Skip signature files
|
|
[[ "$pkg" == *.sig ]] && continue
|
|
|
|
# Extract package name (remove version and architecture)
|
|
# Format: name-version-release-arch.pkg.tar.*
|
|
local pkgname=$(echo "$pkg" | sed -E 's/-[0-9]+.*-(any|x86_64|i686)\.pkg\.tar\..*//')
|
|
|
|
# Add to array
|
|
if [[ -n "${packages[$pkgname]}" ]]; then
|
|
packages[$pkgname]="${packages[$pkgname]} $pkg"
|
|
else
|
|
packages[$pkgname]="$pkg"
|
|
fi
|
|
done
|
|
|
|
# Process each package group
|
|
local total_removed=0
|
|
local space_freed=0
|
|
|
|
for pkgname in "${!packages[@]}"; do
|
|
# Convert string to array and sort by modification time (newest first)
|
|
IFS=' ' read -ra pkg_files <<<"${packages[$pkgname]}"
|
|
|
|
# Sort by modification time
|
|
local sorted_files=($(ls -t "${pkg_files[@]}" 2>/dev/null))
|
|
local count=${#sorted_files[@]}
|
|
|
|
if [[ $count -gt $keep ]]; then
|
|
echo " -> Processing $pkgname ($count versions found)"
|
|
|
|
# Remove old versions
|
|
for ((i = $keep; i < $count; i++)); do
|
|
local file="${sorted_files[$i]}"
|
|
local size=$(stat -c%s "$file" 2>/dev/null || echo 0)
|
|
space_freed=$((space_freed + size))
|
|
|
|
if [[ "$dry_run" == true ]]; then
|
|
echo " Would remove: $file ($(numfmt --to=iec-i --suffix=B $size))"
|
|
else
|
|
echo " Removing: $file ($(numfmt --to=iec-i --suffix=B $size))"
|
|
rm -f "$file"
|
|
rm -f "${file}.sig" 2>/dev/null || true
|
|
fi
|
|
|
|
total_removed=$((total_removed + 1))
|
|
done
|
|
fi
|
|
done
|
|
|
|
# Summary
|
|
if [[ $total_removed -gt 0 ]]; then
|
|
if [[ "$dry_run" == true ]]; then
|
|
echo " -> Would remove $total_removed old package(s)"
|
|
echo " -> Would free $(numfmt --to=iec-i --suffix=B $space_freed)"
|
|
else
|
|
echo " -> Removed $total_removed old package(s)"
|
|
echo " -> Freed $(numfmt --to=iec-i --suffix=B $space_freed)"
|
|
fi
|
|
else
|
|
echo " -> No old packages to remove"
|
|
fi
|
|
}
|
|
|
|
# Function to remove all packages
|
|
remove_all_packages() {
|
|
local dry_run=$1
|
|
|
|
print_error "WARNING: Removing ALL packages from repository!"
|
|
|
|
if [[ "$dry_run" != true ]]; then
|
|
read -p "Are you sure? Type 'yes' to confirm: " confirm
|
|
if [[ "$confirm" != "yes" ]]; then
|
|
print_warning "Cancelled."
|
|
exit 0
|
|
fi
|
|
fi
|
|
|
|
cd "$REPO_DIR"
|
|
|
|
local count=$(ls -1 *.pkg.tar.* 2>/dev/null | wc -l)
|
|
|
|
if [[ $count -eq 0 ]]; then
|
|
print_warning "No packages found to remove"
|
|
return
|
|
fi
|
|
|
|
if [[ "$dry_run" == true ]]; then
|
|
print_warning "Would remove $count package(s):"
|
|
ls -1 *.pkg.tar.* 2>/dev/null | while read -r pkg; do
|
|
echo " - $pkg"
|
|
done
|
|
else
|
|
rm -f *.pkg.tar.*
|
|
rm -f *.db* *.files*
|
|
echo "Removed $count package(s) and database files"
|
|
fi
|
|
}
|
|
|
|
# Function to show repository disk usage
|
|
show_disk_usage() {
|
|
print_info "Repository Disk Usage:"
|
|
|
|
cd "$REPO_DIR"
|
|
|
|
local total_size=$(du -sh . 2>/dev/null | cut -f1)
|
|
local package_count=$(ls -1 *.pkg.tar.* 2>/dev/null | grep -v '\.sig$' | wc -l)
|
|
|
|
echo " -> Total size: $total_size"
|
|
echo " -> Package count: $package_count"
|
|
|
|
if [[ $package_count -gt 0 ]]; then
|
|
local avg_size=$(du -b *.pkg.tar.* 2>/dev/null | awk '{sum+=$1; count++} END {printf "%.0f", sum/count}')
|
|
echo " -> Average package size: $(numfmt --to=iec-i --suffix=B $avg_size 2>/dev/null || echo "N/A")"
|
|
fi
|
|
}
|
|
|
|
# Main execution
|
|
main() {
|
|
print_header "Omarchy Repository Cleaner"
|
|
|
|
# Parse command line arguments
|
|
DRY_RUN=false
|
|
REMOVE_ALL=false
|
|
SHOW_USAGE=false
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case $1 in
|
|
--arch)
|
|
ARCH="$2"
|
|
update_arch_paths
|
|
shift 2
|
|
;;
|
|
--mirror)
|
|
MIRROR="$2"
|
|
require_valid_mirror "$MIRROR"
|
|
update_arch_paths
|
|
shift 2
|
|
;;
|
|
--keep)
|
|
KEEP_VERSIONS="$2"
|
|
shift 2
|
|
;;
|
|
--dry-run)
|
|
DRY_RUN=true
|
|
shift
|
|
;;
|
|
--all)
|
|
REMOVE_ALL=true
|
|
shift
|
|
;;
|
|
--usage)
|
|
SHOW_USAGE=true
|
|
shift
|
|
;;
|
|
-h | --help)
|
|
echo "Usage: $0 [OPTIONS]"
|
|
echo ""
|
|
echo "Options:"
|
|
echo " --arch <arch> Target architecture (x86_64 or aarch64, default: x86_64)"
|
|
echo " --mirror <mirror> Mirror to use (edge, rc, or stable, default: edge)"
|
|
echo " --keep N Keep N versions of each package (default: 2)"
|
|
echo " --dry-run Preview what would be removed without removing"
|
|
echo " --all Remove ALL packages (dangerous!)"
|
|
echo " --usage Show disk usage statistics"
|
|
echo " -h, --help Show this help message"
|
|
echo ""
|
|
echo "Examples:"
|
|
echo " $0 # Keep 2 versions (default)"
|
|
echo " $0 --keep 3 # Keep 3 versions"
|
|
echo " $0 --dry-run # Preview cleanup"
|
|
echo " $0 --all --dry-run # Preview complete removal"
|
|
exit 0
|
|
;;
|
|
*)
|
|
print_error "Unknown option: $1"
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
print_info "Mirror: $MIRROR"
|
|
print_info "Architecture: $ARCH"
|
|
print_info "Repository: $REPO_DIR"
|
|
echo ""
|
|
|
|
# Validate keep versions
|
|
if ! [[ "$KEEP_VERSIONS" =~ ^[0-9]+$ ]] || [[ "$KEEP_VERSIONS" -lt 1 ]]; then
|
|
print_error "Error: --keep must be a positive integer"
|
|
exit 1
|
|
fi
|
|
|
|
# Show dry run notice
|
|
if [[ "$DRY_RUN" == true ]]; then
|
|
print_warning "DRY RUN MODE - No changes will be made"
|
|
fi
|
|
|
|
if [[ "$DRY_RUN" != true && "$SHOW_USAGE" != true ]]; then
|
|
acquire_release_lock || exit 1
|
|
fi
|
|
|
|
# Execute based on options
|
|
if [[ "$SHOW_USAGE" == true ]]; then
|
|
show_disk_usage
|
|
elif [[ "$REMOVE_ALL" == true ]]; then
|
|
remove_all_packages "$DRY_RUN"
|
|
else
|
|
clean_packages "$KEEP_VERSIONS" "$DRY_RUN"
|
|
|
|
# Update database after cleaning (unless dry run)
|
|
if [[ "$DRY_RUN" != true ]]; then
|
|
# Moved to release workflow
|
|
:
|
|
fi
|
|
|
|
show_disk_usage
|
|
fi
|
|
}
|
|
|
|
# Run main function
|
|
main "$@"
|