docker-publish-beta.sh 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. #!/bin/bash
  2. # Build and push multi-architecture Docker image to GHCR (private beta)
  3. #
  4. # Usage:
  5. # ./docker-publish-beta.sh [version] [--parallel]
  6. #
  7. # Examples:
  8. # ./docker-publish-beta.sh 0.2.0b # Sequential build
  9. # ./docker-publish-beta.sh 0.2.0b --parallel # Build both archs simultaneously
  10. #
  11. # All versions are also tagged as 'beta'
  12. #
  13. # Prerequisites:
  14. # 1. Log in to ghcr.io:
  15. # echo $GITHUB_TOKEN | docker login ghcr.io -u YOUR_USERNAME --password-stdin
  16. #
  17. # 2. Create a GitHub Personal Access Token with 'write:packages' scope:
  18. # https://github.com/settings/tokens/new?scopes=write:packages
  19. #
  20. # 3. After first push, set package to Private in GitHub → Packages → Settings
  21. # and add beta testers via Manage Access
  22. #
  23. # Supported architectures:
  24. # - linux/amd64 (x86_64, most servers/desktops)
  25. # - linux/arm64 (Raspberry Pi 4/5, Apple Silicon via emulation)
  26. set -e
  27. # Configuration
  28. GHCR_REGISTRY="ghcr.io"
  29. IMAGE_NAME="maziggy/bambuddy-beta"
  30. GHCR_IMAGE="${GHCR_REGISTRY}/${IMAGE_NAME}"
  31. PLATFORMS="linux/amd64,linux/arm64"
  32. BUILDER_NAME="bambuddy-builder"
  33. # Colors for output
  34. RED='\033[0;31m'
  35. GREEN='\033[0;32m'
  36. YELLOW='\033[1;33m'
  37. BLUE='\033[0;34m'
  38. NC='\033[0m' # No Color
  39. # Parse arguments
  40. VERSION=""
  41. PARALLEL=false
  42. SKIP_SIDECARS=false
  43. for arg in "$@"; do
  44. case $arg in
  45. --parallel)
  46. PARALLEL=true
  47. ;;
  48. --skip-sidecars)
  49. SKIP_SIDECARS=true
  50. ;;
  51. *)
  52. if [ -z "$VERSION" ]; then
  53. VERSION="$arg"
  54. fi
  55. ;;
  56. esac
  57. done
  58. if [ -z "$VERSION" ]; then
  59. echo -e "${YELLOW}Usage: $0 <version> [--parallel]${NC}"
  60. echo "Example: $0 0.2.0b"
  61. echo " $0 0.2.0b --parallel # Build both architectures simultaneously"
  62. exit 1
  63. fi
  64. # Get CPU count
  65. CPU_COUNT=$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 4)
  66. echo -e "${GREEN}================================================${NC}"
  67. echo -e "${GREEN} Building multi-arch BETA image${NC}"
  68. echo -e "${GREEN} Version: ${VERSION}${NC}"
  69. echo -e "${GREEN} Platforms: ${PLATFORMS}${NC}"
  70. echo -e "${GREEN} CPU cores: ${CPU_COUNT}${NC}"
  71. if [ "$PARALLEL" = true ]; then
  72. echo -e "${GREEN} Mode: PARALLEL (both archs simultaneously)${NC}"
  73. else
  74. echo -e "${GREEN} Mode: Sequential (amd64 → arm64)${NC}"
  75. fi
  76. echo -e "${GREEN} Registry: ${GHCR_IMAGE}${NC}"
  77. echo -e "${GREEN}================================================${NC}"
  78. echo ""
  79. # Check registry login
  80. if ! grep -q "ghcr.io" ~/.docker/config.json 2>/dev/null; then
  81. echo -e "${YELLOW}Warning: You may not be logged in to ghcr.io${NC}"
  82. echo "Run: echo \$GITHUB_TOKEN | docker login ghcr.io -u YOUR_USERNAME --password-stdin"
  83. echo ""
  84. fi
  85. # Setup buildx builder if not exists
  86. echo -e "${BLUE}[1/4] Setting up Docker Buildx...${NC}"
  87. if ! docker buildx inspect "$BUILDER_NAME" >/dev/null 2>&1; then
  88. echo "Creating new buildx builder: $BUILDER_NAME (optimized for ${CPU_COUNT} cores)"
  89. docker buildx create \
  90. --name "$BUILDER_NAME" \
  91. --driver docker-container \
  92. --driver-opt network=host \
  93. --driver-opt "env.BUILDKIT_STEP_LOG_MAX_SIZE=10000000" \
  94. --buildkitd-flags "--allow-insecure-entitlement network.host --oci-worker-gc=false" \
  95. --config /dev/stdin <<EOF
  96. [worker.oci]
  97. max-parallelism = ${CPU_COUNT}
  98. EOF
  99. docker buildx inspect --bootstrap "$BUILDER_NAME"
  100. fi
  101. docker buildx use "$BUILDER_NAME"
  102. # Verify builder supports multi-platform
  103. echo -e "${BLUE}[2/4] Verifying multi-platform support...${NC}"
  104. if ! docker buildx inspect --bootstrap | grep -q "linux/arm64"; then
  105. echo -e "${YELLOW}Installing QEMU for cross-platform builds...${NC}"
  106. docker run --privileged --rm tonistiigi/binfmt --install all
  107. fi
  108. # Build tags — version + beta (not latest)
  109. TAGS="-t ${GHCR_IMAGE}:${VERSION} -t ${GHCR_IMAGE}:beta"
  110. echo -e "${BLUE}[3/4] Building and pushing...${NC}"
  111. # Common build args (no cache to ensure clean builds)
  112. BUILD_ARGS="--provenance=false --sbom=false --no-cache --pull"
  113. if [ "$PARALLEL" = true ]; then
  114. # Parallel build: Build each architecture separately then combine manifests
  115. echo -e "${YELLOW}Building amd64 and arm64 in parallel (${CPU_COUNT} cores each, no cache)...${NC}"
  116. # Build amd64 in background
  117. (
  118. echo -e "${BLUE}[amd64] Starting build...${NC}"
  119. docker buildx build \
  120. --platform linux/amd64 \
  121. -t "${GHCR_IMAGE}:${VERSION}-amd64" \
  122. ${BUILD_ARGS} \
  123. --push \
  124. . 2>&1 | sed 's/^/[amd64] /'
  125. echo -e "${GREEN}[amd64] Complete!${NC}"
  126. ) &
  127. PID_AMD64=$!
  128. # Build arm64 in background
  129. (
  130. echo -e "${BLUE}[arm64] Starting build...${NC}"
  131. docker buildx build \
  132. --platform linux/arm64 \
  133. -t "${GHCR_IMAGE}:${VERSION}-arm64" \
  134. ${BUILD_ARGS} \
  135. --push \
  136. . 2>&1 | sed 's/^/[arm64] /'
  137. echo -e "${GREEN}[arm64] Complete!${NC}"
  138. ) &
  139. PID_ARM64=$!
  140. # Wait for both builds
  141. echo "Waiting for parallel builds to complete..."
  142. wait $PID_AMD64
  143. wait $PID_ARM64
  144. # Create multi-arch manifest
  145. echo -e "${BLUE}Creating multi-arch manifest...${NC}"
  146. docker buildx imagetools create \
  147. -t "${GHCR_IMAGE}:${VERSION}" -t "${GHCR_IMAGE}:beta" \
  148. "${GHCR_IMAGE}:${VERSION}-amd64" \
  149. "${GHCR_IMAGE}:${VERSION}-arm64"
  150. else
  151. # Sequential build (default): Build both platforms in one command
  152. echo -e "${YELLOW}Building sequentially with ${CPU_COUNT} cores (no cache)...${NC}"
  153. DOCKER_BUILDKIT=1 docker buildx build \
  154. --platform "$PLATFORMS" \
  155. ${BUILD_ARGS} \
  156. $TAGS \
  157. --push \
  158. .
  159. fi
  160. echo -e "${BLUE}[4/4] Verifying manifest...${NC}"
  161. docker buildx imagetools inspect "${GHCR_IMAGE}:${VERSION}"
  162. echo ""
  163. echo -e "${GREEN}================================================${NC}"
  164. echo -e "${GREEN} Successfully pushed multi-arch BETA image:${NC}"
  165. echo -e "${GREEN}================================================${NC}"
  166. echo " ${GHCR_IMAGE}:${VERSION}"
  167. echo " ${GHCR_IMAGE}:beta"
  168. echo ""
  169. echo -e "${BLUE}Supported platforms:${NC}"
  170. echo " - linux/amd64 (Intel/AMD servers, desktops)"
  171. echo " - linux/arm64 (Raspberry Pi 4/5, Apple Silicon)"
  172. echo ""
  173. echo -e "${GREEN}Beta testers can run:${NC}"
  174. echo " docker pull ${GHCR_IMAGE}:${VERSION}"
  175. echo " docker pull ${GHCR_IMAGE}:beta"
  176. echo ""
  177. echo -e "${YELLOW}Reminder: Set package to Private in GitHub → Packages → Settings${NC}"
  178. # ============================================================
  179. # Sidecar images (orca-slicer-api + bambu-studio-api) — beta channel = GHCR private
  180. # ============================================================
  181. SIDECAR_SCRIPT="/opt/claude/projects/orca-slicer-api/docker-publish-sidecars.sh"
  182. if [ "$SKIP_SIDECARS" = true ]; then
  183. echo ""
  184. echo -e "${YELLOW}Skipping sidecar images (--skip-sidecars).${NC}"
  185. elif [ ! -x "$SIDECAR_SCRIPT" ]; then
  186. echo ""
  187. echo -e "${YELLOW}Sidecar helper not found at ${SIDECAR_SCRIPT} — skipping sidecar build.${NC}"
  188. else
  189. echo ""
  190. echo -e "${GREEN}================================================${NC}"
  191. echo -e "${GREEN} Publishing sidecar images (beta channel)${NC}"
  192. echo -e "${GREEN}================================================${NC}"
  193. SIDECAR_ARGS="--channel beta --version ${VERSION}"
  194. [ "$PARALLEL" = true ] && SIDECAR_ARGS="$SIDECAR_ARGS --parallel"
  195. "$SIDECAR_SCRIPT" $SIDECAR_ARGS
  196. fi