- helpers/paths.sh: validate_mirror/require_valid_mirror for the edge|rc|stable set, and REPO_ROOT (OMARCHY_REPO_ROOT override) so a secondary checkout like the rc branch worktree publishes into the same channel tree as the primary - validate --mirror everywhere it previously accepted any string (sync-repo, promote-build, update-repo, clean-repo, remove-package) and widen the edge|stable checks in build, deploy, push-build, auto-release - build/Dockerfile: rc builds compile against rc-mirror.omarchy.org
196 lines
5.7 KiB
Bash
Executable File
196 lines
5.7 KiB
Bash
Executable File
#!/bin/bash
|
|
# Promote packages from build-output to pkgs.omarchy.org
|
|
|
|
set -e
|
|
|
|
BUILD_ROOT=$(realpath "${BASH_SOURCE[0]%/*}/..")
|
|
source "$BUILD_ROOT/helpers/message-helpers.sh"
|
|
source "$BUILD_ROOT/helpers/paths.sh"
|
|
|
|
print_header "Promote Build to Production"
|
|
|
|
# Parse arguments
|
|
DRY_RUN=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
|
|
;;
|
|
--dry-run)
|
|
DRY_RUN=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 " --dry-run Show what would be copied without copying"
|
|
echo " -h, --help Show this help message"
|
|
echo ""
|
|
echo "This script promotes packages from build-output/ to pkgs.omarchy.org/"
|
|
exit 0
|
|
;;
|
|
*)
|
|
print_error "Unknown option: $1"
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
print_info "Mirror: $MIRROR"
|
|
print_info "Build output: $BUILD_OUTPUT_DIR"
|
|
print_info "Final output: $REPO_DIR"
|
|
|
|
# Check if build output exists
|
|
if [[ ! -d "$BUILD_OUTPUT_DIR" ]]; then
|
|
print_error "Build output directory not found: $BUILD_OUTPUT_DIR"
|
|
print_warning "Run bin/repo build first"
|
|
exit 1
|
|
fi
|
|
|
|
# Count packages in build output
|
|
cd "$BUILD_OUTPUT_DIR"
|
|
PACKAGE_COUNT=$(ls -1 *.pkg.tar.* 2>/dev/null | grep -v '\.sig$' | grep -v 'omarchy-build\.db' | wc -l)
|
|
|
|
if [[ $PACKAGE_COUNT -eq 0 ]]; then
|
|
print_warning "No packages found in build output"
|
|
exit 0
|
|
fi
|
|
|
|
print_info "Found $PACKAGE_COUNT package(s) to promote"
|
|
|
|
if [[ "$DRY_RUN" == true ]]; then
|
|
print_warning "DRY RUN MODE - No files will be copied"
|
|
echo ""
|
|
print_info "Packages that would be promoted:"
|
|
ls -1 *.pkg.tar.* 2>/dev/null | grep -v 'omarchy-build\.db' | grep -v 'omarchy-build\.files' | while read -r pkg; do
|
|
echo " - $pkg"
|
|
done
|
|
else
|
|
echo ""
|
|
mkdir -p "$REPO_DIR"
|
|
|
|
echo "==> Verifying all packages have signatures..."
|
|
MISSING_SIGS=()
|
|
for pkg_file in *.pkg.tar.*; do
|
|
# Skip build database files
|
|
[[ "$pkg_file" == omarchy-build.db* ]] && continue
|
|
[[ "$pkg_file" == omarchy-build.files* ]] && continue
|
|
# Skip signature files themselves
|
|
[[ "$pkg_file" == *.sig ]] && continue
|
|
[[ ! -f "$pkg_file" ]] && continue
|
|
|
|
# Check if signature exists
|
|
if [[ ! -f "$pkg_file.sig" ]]; then
|
|
MISSING_SIGS+=("$pkg_file")
|
|
fi
|
|
done
|
|
|
|
if [[ ${#MISSING_SIGS[@]} -gt 0 ]]; then
|
|
echo ""
|
|
print_error "ERROR: The following packages are missing signatures:"
|
|
for pkg in "${MISSING_SIGS[@]}"; do
|
|
echo " - $pkg (missing $pkg.sig)"
|
|
done
|
|
echo ""
|
|
print_error "All packages must be signed before promotion!"
|
|
echo ""
|
|
echo "To fix this, run:"
|
|
echo " bin/repo sign --mirror $MIRROR --arch $ARCH"
|
|
exit 1
|
|
fi
|
|
|
|
# VCS packages (omarchy-dev and friends) are versioned off the upstream commit,
|
|
# so rebuilding the same commit produces the same filename. That is harmless
|
|
# when the artifact is identical — a run that promoted but died before the
|
|
# database was updated leaves exactly this state, and failing here would wedge
|
|
# every later run. Re-promoting *different* content under a published filename
|
|
# is the real hazard, so only that aborts.
|
|
echo "==> Checking for existing files in production..."
|
|
CONFLICTS=()
|
|
declare -A ALREADY_PROMOTED=()
|
|
for pkg_file in *.pkg.tar.*; do
|
|
# Skip build database files
|
|
[[ "$pkg_file" == omarchy-build.db* ]] && continue
|
|
[[ "$pkg_file" == omarchy-build.files* ]] && continue
|
|
[[ "$pkg_file" == *.sig ]] && continue
|
|
[[ ! -f "$pkg_file" ]] && continue
|
|
|
|
if [[ -f "$REPO_DIR/$pkg_file" ]]; then
|
|
if cmp -s "$pkg_file" "$REPO_DIR/$pkg_file"; then
|
|
ALREADY_PROMOTED["$pkg_file"]=1
|
|
else
|
|
CONFLICTS+=("$pkg_file")
|
|
fi
|
|
fi
|
|
done
|
|
|
|
# Signatures carry a timestamp, so a re-signed package never matches byte for
|
|
# byte. Judge them by the package they sign and keep the published signature.
|
|
for pkg_file in *.pkg.tar.*.sig; do
|
|
[[ ! -f "$pkg_file" ]] && continue
|
|
[[ -f "$REPO_DIR/$pkg_file" ]] || continue
|
|
|
|
if [[ -n "${ALREADY_PROMOTED[${pkg_file%.sig}]:-}" ]]; then
|
|
ALREADY_PROMOTED["$pkg_file"]=1
|
|
else
|
|
CONFLICTS+=("$pkg_file")
|
|
fi
|
|
done
|
|
|
|
if [[ ${#CONFLICTS[@]} -gt 0 ]]; then
|
|
echo ""
|
|
print_error "ERROR: The following packages already exist in production with different contents:"
|
|
for conflict in "${CONFLICTS[@]}"; do
|
|
echo " - $conflict"
|
|
done
|
|
echo ""
|
|
print_error "Refusing to replace published packages in pkgs.omarchy.org!"
|
|
exit 1
|
|
fi
|
|
|
|
if [[ ${#ALREADY_PROMOTED[@]} -gt 0 ]]; then
|
|
print_info "Already in production (identical, skipping): ${#ALREADY_PROMOTED[@]} file(s)"
|
|
for promoted in "${!ALREADY_PROMOTED[@]}"; do
|
|
echo " - $promoted"
|
|
done
|
|
fi
|
|
|
|
print_info "Moving packages to production..."
|
|
|
|
MOVED=0
|
|
for pkg_file in *.pkg.tar.*; do
|
|
# Skip build database files
|
|
[[ "$pkg_file" == omarchy-build.db* ]] && continue
|
|
[[ "$pkg_file" == omarchy-build.files* ]] && continue
|
|
[[ ! -f "$pkg_file" ]] && continue
|
|
[[ -n "${ALREADY_PROMOTED[$pkg_file]:-}" ]] && continue
|
|
|
|
# Use mv to prevent race condition caused by cp
|
|
if mv -v "$pkg_file" "$REPO_DIR/"; then
|
|
MOVED=$((MOVED + 1))
|
|
else
|
|
print_error "Failed to move $pkg_file"
|
|
exit 1
|
|
fi
|
|
done
|
|
|
|
echo ""
|
|
print_success "Promoted $MOVED file(s) to pkgs.omarchy.org"
|
|
|
|
print_info "Cleaning up build directory..."
|
|
cd "$BUILD_OUTPUT_DIR"
|
|
rm -f *.pkg.tar.* omarchy-build.db* omarchy-build.files*
|
|
print_success "Build directory cleaned"
|
|
fi
|