|
| 1 | +#!/bin/bash |
| 2 | +set -e |
| 3 | + |
| 4 | +# Parse arguments |
| 5 | +PACKAGE_MANAGER="${1:-all}" # debian, rpm, alpine, or all (default) |
| 6 | + |
| 7 | +if [[ ! "$PACKAGE_MANAGER" =~ ^(debian|rpm|alpine|all)$ ]]; then |
| 8 | + echo "Usage: $0 [debian|rpm|alpine|all]" |
| 9 | + echo " Default: all" |
| 10 | + exit 1 |
| 11 | +fi |
| 12 | + |
| 13 | +echo "Package manager filter: $PACKAGE_MANAGER" |
| 14 | + |
| 15 | +# Required environment variables: |
| 16 | +# - VERSION: Version of the CLI being released (auto-detected from dist/ if not set) |
| 17 | +# - AWS credentials: Configured via AWS CLI or environment |
| 18 | +# - GPG_PRIVATE_KEY_FILE: Path to GPG private key file for signing Debian/RPM packages |
| 19 | +# OR GPG_PRIVATE_KEY: Base64-encoded GPG private key (legacy) |
| 20 | +# - RSA_PRIVATE_KEY_FILE: Path to RSA private key file for signing Alpine packages |
| 21 | +# OR RSA_PRIVATE_KEY: RSA private key content (legacy) |
| 22 | +# - RSA_PUBLIC_KEY_FILE: Path to RSA public key file for Alpine users |
| 23 | +# OR RSA_PUBLIC_KEY: RSA public key content (legacy) |
| 24 | + |
| 25 | +# Auto-detect VERSION from dist/ if not set |
| 26 | +if [ -z "$VERSION" ]; then |
| 27 | + VERSION=$(ls dist/*.deb 2>/dev/null | head -1 | sed -E 's/.*cli_(.+)_linux_.*/\1/') |
| 28 | + if [ -n "$VERSION" ]; then |
| 29 | + echo "Auto-detected VERSION: $VERSION" |
| 30 | + fi |
| 31 | +fi |
| 32 | + |
| 33 | +# Check required environment variables |
| 34 | +MISSING_VARS=() |
| 35 | + |
| 36 | +if [ -z "$VERSION" ]; then |
| 37 | + MISSING_VARS+=("VERSION") |
| 38 | +fi |
| 39 | + |
| 40 | +if [ -z "$GPG_PRIVATE_KEY_FILE" ] && [ -z "$GPG_PRIVATE_KEY" ]; then |
| 41 | + MISSING_VARS+=("GPG_PRIVATE_KEY_FILE or GPG_PRIVATE_KEY") |
| 42 | +fi |
| 43 | + |
| 44 | +if [ -z "$RSA_PRIVATE_KEY_FILE" ] && [ -z "$RSA_PRIVATE_KEY" ]; then |
| 45 | + MISSING_VARS+=("RSA_PRIVATE_KEY_FILE or RSA_PRIVATE_KEY") |
| 46 | +fi |
| 47 | + |
| 48 | +if [ -z "$RSA_PUBLIC_KEY_FILE" ] && [ -z "$RSA_PUBLIC_KEY" ]; then |
| 49 | + MISSING_VARS+=("RSA_PUBLIC_KEY_FILE or RSA_PUBLIC_KEY") |
| 50 | +fi |
| 51 | + |
| 52 | +if [ ${#MISSING_VARS[@]} -ne 0 ]; then |
| 53 | + echo "Error: The following required environment variables are not set:" |
| 54 | + for var in "${MISSING_VARS[@]}"; do |
| 55 | + echo " - $var" |
| 56 | + done |
| 57 | + exit 1 |
| 58 | +fi |
| 59 | + |
| 60 | +# AWS bucket for package repositories |
| 61 | +export AWS_BUCKET="${AWS_BUCKET:-public-repogen-repositories-upsun-com}" |
| 62 | + |
| 63 | +# Set AWS region |
| 64 | +export AWS_DEFAULT_REGION="${AWS_REGION:-eu-west-1}" |
| 65 | + |
| 66 | +# Create temporary directories for repository work |
| 67 | +WORK_DIR=$(mktemp -d) |
| 68 | +trap "rm -rf $WORK_DIR" EXIT |
| 69 | + |
| 70 | +# Handle GPG key - from file or environment variable |
| 71 | +if [ -n "$GPG_PRIVATE_KEY_FILE" ]; then |
| 72 | + GPG_KEY_FILE="$GPG_PRIVATE_KEY_FILE" |
| 73 | +else |
| 74 | + GPG_KEY_FILE="${WORK_DIR}/gpg-private-key.asc" |
| 75 | + echo "$GPG_PRIVATE_KEY" | base64 -d > "$GPG_KEY_FILE" |
| 76 | +fi |
| 77 | + |
| 78 | +# Import GPG key |
| 79 | +gpg --import "$GPG_KEY_FILE" |
| 80 | + |
| 81 | +# Handle RSA private key - from file or environment variable |
| 82 | +if [ -n "$RSA_PRIVATE_KEY_FILE" ]; then |
| 83 | + RSA_KEY_FILE="$RSA_PRIVATE_KEY_FILE" |
| 84 | +else |
| 85 | + RSA_KEY_FILE="${WORK_DIR}/rsa-private-key.pem" |
| 86 | + echo "$RSA_PRIVATE_KEY" > "$RSA_KEY_FILE" |
| 87 | +fi |
| 88 | + |
| 89 | +# Handle RSA public key - from file or environment variable |
| 90 | +if [ -n "$RSA_PUBLIC_KEY_FILE" ]; then |
| 91 | + RSA_PUB_KEY_FILE="$RSA_PUBLIC_KEY_FILE" |
| 92 | +else |
| 93 | + RSA_PUB_KEY_FILE="${WORK_DIR}/repositories-upsun-com.rsa.pub" |
| 94 | + echo "$RSA_PUBLIC_KEY" > "$RSA_PUB_KEY_FILE" |
| 95 | +fi |
| 96 | + |
| 97 | +# Packages are expected to be pre-built by goreleaser in the dist/ directory |
| 98 | +# goreleaser builds signed .deb, .rpm, and .apk packages via nfpm |
| 99 | +# Check that packages exist |
| 100 | +if [ ! -d "dist" ]; then |
| 101 | + echo "Error: dist/ directory not found. Run 'goreleaser release' or 'make snapshot' first." |
| 102 | + exit 1 |
| 103 | +fi |
| 104 | + |
| 105 | +# Create shared staging directories for all packages |
| 106 | +# Both platformsh and upsun packages go in the same directories so they're |
| 107 | +# processed together and appear in the same repository indexes |
| 108 | +PACKAGES_DEB_DIR="${WORK_DIR}/packages-deb" |
| 109 | +PACKAGES_RPM_DIR="${WORK_DIR}/packages-rpm" |
| 110 | +PACKAGES_APK_DIR="${WORK_DIR}/packages-apk" |
| 111 | +REPO_DIR="${WORK_DIR}/repo" |
| 112 | +mkdir -p "$PACKAGES_DEB_DIR" "$PACKAGES_RPM_DIR" "$PACKAGES_APK_DIR" "$REPO_DIR" |
| 113 | + |
| 114 | +echo "=== Copying packages to staging directories ===" |
| 115 | + |
| 116 | +# Copy Platform.sh packages |
| 117 | +cp dist/platformsh-cli_${VERSION}_linux_amd64.deb "$PACKAGES_DEB_DIR/" || true |
| 118 | +cp dist/platformsh-cli_${VERSION}_linux_arm64.deb "$PACKAGES_DEB_DIR/" || true |
| 119 | +cp dist/platformsh-cli_${VERSION}_linux_amd64.apk "$PACKAGES_APK_DIR/" || true |
| 120 | +cp dist/platformsh-cli_${VERSION}_linux_arm64.apk "$PACKAGES_APK_DIR/" || true |
| 121 | +cp dist/platformsh-cli_${VERSION}_linux_amd64.rpm "$PACKAGES_RPM_DIR/" || true |
| 122 | +cp dist/platformsh-cli_${VERSION}_linux_arm64.rpm "$PACKAGES_RPM_DIR/" || true |
| 123 | + |
| 124 | +# Copy Upsun packages |
| 125 | +cp dist/upsun-cli_${VERSION}_linux_amd64.deb "$PACKAGES_DEB_DIR/" || true |
| 126 | +cp dist/upsun-cli_${VERSION}_linux_arm64.deb "$PACKAGES_DEB_DIR/" || true |
| 127 | +cp dist/upsun-cli_${VERSION}_linux_amd64.apk "$PACKAGES_APK_DIR/" || true |
| 128 | +cp dist/upsun-cli_${VERSION}_linux_arm64.apk "$PACKAGES_APK_DIR/" || true |
| 129 | +cp dist/upsun-cli_${VERSION}_linux_amd64.rpm "$PACKAGES_RPM_DIR/" || true |
| 130 | +cp dist/upsun-cli_${VERSION}_linux_arm64.rpm "$PACKAGES_RPM_DIR/" || true |
| 131 | + |
| 132 | +echo "Packages staged:" |
| 133 | +ls -la "$PACKAGES_DEB_DIR" "$PACKAGES_RPM_DIR" "$PACKAGES_APK_DIR" 2>/dev/null || true |
| 134 | + |
| 135 | +# --- Debian Repository --- |
| 136 | +if [[ "$PACKAGE_MANAGER" == "all" || "$PACKAGE_MANAGER" == "debian" ]]; then |
| 137 | + echo "=== Processing Debian packages ===" |
| 138 | + DEB_REPO_DIR="${REPO_DIR}/debian" |
| 139 | + mkdir -p "$DEB_REPO_DIR" |
| 140 | + |
| 141 | + # Sync Debian metadata from S3 (if exists) |
| 142 | + aws s3 sync "s3://${AWS_BUCKET}/debian/dists" "${DEB_REPO_DIR}/dists" --delete 2>/dev/null || true |
| 143 | + |
| 144 | + # Run repogen for Debian packages |
| 145 | + repogen generate \ |
| 146 | + --input-dir "$PACKAGES_DEB_DIR" \ |
| 147 | + --output-dir "$DEB_REPO_DIR" \ |
| 148 | + --incremental \ |
| 149 | + --arch amd64,arm64 \ |
| 150 | + --codename stable \ |
| 151 | + --origin "Upsun" \ |
| 152 | + --label "Upsun CLI" \ |
| 153 | + --gpg-key "$GPG_KEY_FILE" |
| 154 | + |
| 155 | + # Sync Debian back to S3 |
| 156 | + aws s3 sync "${DEB_REPO_DIR}" "s3://${AWS_BUCKET}/debian" |
| 157 | + echo "=== Done processing Debian packages ===" |
| 158 | +fi |
| 159 | + |
| 160 | +# --- RPM Repository --- |
| 161 | +# Generates repos for multiple Fedora versions to support $releasever in yum/dnf configs |
| 162 | +if [[ "$PACKAGE_MANAGER" == "all" || "$PACKAGE_MANAGER" == "rpm" ]]; then |
| 163 | + echo "=== Processing RPM packages ===" |
| 164 | + |
| 165 | + # Fedora versions to support |
| 166 | + FEDORA_VERSIONS="40 41 42 43" |
| 167 | + |
| 168 | + for FEDORA_VER in $FEDORA_VERSIONS; do |
| 169 | + echo "--- Processing Fedora $FEDORA_VER ---" |
| 170 | + |
| 171 | + # Use a separate output directory per version to avoid repogen's ParseExistingMetadata |
| 172 | + # scanning all version directories and detecting conflicts |
| 173 | + RPM_REPO_DIR="${REPO_DIR}/fedora-${FEDORA_VER}" |
| 174 | + mkdir -p "$RPM_REPO_DIR" |
| 175 | + |
| 176 | + # Sync only repodata metadata from S3 (not packages) |
| 177 | + for arch in x86_64 aarch64; do |
| 178 | + mkdir -p "${RPM_REPO_DIR}/${FEDORA_VER}/${arch}/repodata" |
| 179 | + aws s3 sync "s3://${AWS_BUCKET}/fedora/${FEDORA_VER}/${arch}/repodata" "${RPM_REPO_DIR}/${FEDORA_VER}/${arch}/repodata" --delete 2>/dev/null || true |
| 180 | + done |
| 181 | + |
| 182 | + # Run repogen for RPM packages with explicit version |
| 183 | + # repogen will create $version/$arch/Packages/ and $version/$arch/repodata/ inside output-dir |
| 184 | + repogen generate \ |
| 185 | + --input-dir "$PACKAGES_RPM_DIR" \ |
| 186 | + --output-dir "$RPM_REPO_DIR" \ |
| 187 | + --incremental \ |
| 188 | + --arch amd64,arm64 \ |
| 189 | + --origin "Upsun" \ |
| 190 | + --label "Upsun CLI" \ |
| 191 | + --version "$FEDORA_VER" \ |
| 192 | + --gpg-key "$GPG_KEY_FILE" |
| 193 | + |
| 194 | + # Sync this Fedora version back to S3 (without --delete to preserve existing packages) |
| 195 | + aws s3 sync "${RPM_REPO_DIR}/${FEDORA_VER}" "s3://${AWS_BUCKET}/fedora/${FEDORA_VER}" |
| 196 | + done |
| 197 | + |
| 198 | + echo "=== Done processing RPM packages ===" |
| 199 | +fi |
| 200 | + |
| 201 | +# --- Alpine Repository --- |
| 202 | +if [[ "$PACKAGE_MANAGER" == "all" || "$PACKAGE_MANAGER" == "alpine" ]]; then |
| 203 | + echo "=== Processing Alpine packages ===" |
| 204 | + APK_REPO_DIR="${REPO_DIR}/alpine" |
| 205 | + mkdir -p "$APK_REPO_DIR" |
| 206 | + |
| 207 | + # Sync Alpine metadata from S3 (if exists) |
| 208 | + for arch in x86_64 aarch64; do |
| 209 | + mkdir -p "${APK_REPO_DIR}/${arch}" |
| 210 | + aws s3 cp "s3://${AWS_BUCKET}/alpine/${arch}/APKINDEX.tar.gz" "${APK_REPO_DIR}/${arch}/APKINDEX.tar.gz" 2>/dev/null || true |
| 211 | + done |
| 212 | + |
| 213 | + # Run repogen for Alpine packages with RSA signing |
| 214 | + repogen generate \ |
| 215 | + --input-dir "$PACKAGES_APK_DIR" \ |
| 216 | + --output-dir "$APK_REPO_DIR" \ |
| 217 | + --incremental \ |
| 218 | + --arch amd64,arm64 \ |
| 219 | + --rsa-key "$RSA_KEY_FILE" \ |
| 220 | + --key-name "repositories-upsun-com" |
| 221 | + |
| 222 | + # Copy RSA public key for users to download |
| 223 | + cp "$RSA_PUB_KEY_FILE" "${APK_REPO_DIR}/" |
| 224 | + |
| 225 | + # Sync Alpine back to S3 |
| 226 | + aws s3 sync "${APK_REPO_DIR}" "s3://${AWS_BUCKET}/alpine" |
| 227 | + echo "=== Done processing Alpine packages ===" |
| 228 | +fi |
| 229 | + |
| 230 | +echo "All packages uploaded successfully!" |
0 commit comments