| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258 |
- #!/bin/bash
- #
- # Smartbotic Production Build Script
- #
- # This script handles the Docker build workflow:
- # 1. Checks if the pre-built base image exists
- # 2. Creates it if needed
- # 3. Builds production packages using the base image
- #
- # Usage:
- # ./packaging/build.sh # Build with auto-detected version
- # ./packaging/build.sh 0.1.0 # Build with specific version
- # ./packaging/build.sh --rebuild-base # Force rebuild the base image
- #
- set -e
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
- PROJECT_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
- cd "$PROJECT_DIR"
- # Configuration
- BASE_IMAGE_NAME="smartbotic-build-base:debian13"
- OUTPUT_DIR="${PROJECT_DIR}/dist"
- BUILD_JOBS="${BUILD_JOBS:-16}"
- # Colors for output
- RED='\033[0;31m'
- GREEN='\033[0;32m'
- YELLOW='\033[1;33m'
- BLUE='\033[0;34m'
- NC='\033[0m' # No Color
- log_info() {
- echo -e "${BLUE}[INFO]${NC} $1"
- }
- log_success() {
- echo -e "${GREEN}[OK]${NC} $1"
- }
- log_warn() {
- echo -e "${YELLOW}[WARN]${NC} $1"
- }
- log_error() {
- echo -e "${RED}[ERROR]${NC} $1"
- }
- # Parse arguments
- REBUILD_BASE=false
- CLEAR_CACHE=false
- NO_CACHE=false
- VERSION=""
- while [[ $# -gt 0 ]]; do
- case $1 in
- --rebuild-base)
- REBUILD_BASE=true
- shift
- ;;
- --clear-cache)
- CLEAR_CACHE=true
- shift
- ;;
- --no-cache)
- NO_CACHE=true
- shift
- ;;
- --help|-h)
- echo "Smartbotic Production Build Script"
- echo ""
- echo "Usage: $0 [OPTIONS] [VERSION]"
- echo ""
- echo "Options:"
- echo " --rebuild-base Force rebuild the base image"
- echo " --clear-cache Clear BuildKit build caches (ccache, npm)"
- echo " --no-cache Build without using caches"
- echo " --help, -h Show this help message"
- echo ""
- echo "Arguments:"
- echo " VERSION Version string (default: auto-detect from CMakeLists.txt)"
- echo ""
- echo "Environment variables:"
- echo " BUILD_JOBS Number of parallel build jobs (default: 16)"
- echo ""
- echo "Examples:"
- echo " $0 # Build with auto-detected version"
- echo " $0 0.1.0 # Build version 0.1.0"
- echo " $0 --rebuild-base # Rebuild base image and build packages"
- echo " $0 --clear-cache # Clear caches and build fresh"
- exit 0
- ;;
- *)
- VERSION="$1"
- shift
- ;;
- esac
- done
- # Auto-detect version if not specified
- if [ -z "$VERSION" ]; then
- VERSION=$(grep -oP 'project\(smartbotic-microbit VERSION \K[0-9.]+' CMakeLists.txt)
- if [ -z "$VERSION" ]; then
- log_error "Could not detect version from CMakeLists.txt"
- exit 1
- fi
- fi
- log_info "Smartbotic Build Script"
- log_info "Version: $VERSION"
- log_info "Output directory: $OUTPUT_DIR"
- echo ""
- # Check if Docker is available
- if ! command -v docker &> /dev/null; then
- log_error "Docker is not installed or not in PATH"
- exit 1
- fi
- # Check if base image exists
- base_image_exists() {
- docker image inspect "$BASE_IMAGE_NAME" &> /dev/null
- }
- # Build base image
- build_base_image() {
- log_info "Building base image: $BASE_IMAGE_NAME"
- log_info "This may take several minutes on first run..."
- echo ""
- docker buildx build \
- -f packaging/Dockerfile.base \
- -t "$BASE_IMAGE_NAME" \
- .
- log_success "Base image built successfully"
- echo ""
- }
- # Build production packages
- build_packages() {
- log_info "Building production packages..."
- log_info "Using base image: $BASE_IMAGE_NAME"
- log_info "Build jobs: $BUILD_JOBS"
- if [ "$NO_CACHE" = true ]; then
- log_warn "Building without caches (--no-cache)"
- else
- log_info "Using ccache and npm cache for faster builds"
- fi
- echo ""
- # Get git info
- GIT_COMMIT=$(git rev-parse HEAD 2>/dev/null || echo "unknown")
- GIT_BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown")
- log_info "Git commit: $GIT_COMMIT"
- log_info "Git branch: $GIT_BRANCH"
- echo ""
- # Clean output directory
- rm -rf "$OUTPUT_DIR"
- mkdir -p "$OUTPUT_DIR"
- # Build arguments
- BUILD_ARGS=(
- -f packaging/Dockerfile.build
- --build-arg BASE_IMAGE="$BASE_IMAGE_NAME"
- --build-arg BUILD_VERSION="$VERSION"
- --build-arg BUILD_GIT_COMMIT="$GIT_COMMIT"
- --build-arg BUILD_GIT_BRANCH="$GIT_BRANCH"
- --build-arg BUILD_JOBS="$BUILD_JOBS"
- --target packages
- --output "type=local,dest=$OUTPUT_DIR"
- )
- # Add --no-cache if requested
- if [ "$NO_CACHE" = true ]; then
- BUILD_ARGS+=(--no-cache)
- fi
- # Build packages
- docker buildx build "${BUILD_ARGS[@]}" .
- log_success "Packages built successfully"
- echo ""
- }
- # Clear build caches
- clear_build_cache() {
- log_info "Clearing BuildKit build caches..."
- docker builder prune --filter type=exec.cachemount -f
- log_success "Build caches cleared"
- echo ""
- }
- # Main flow
- echo "=================================================="
- echo " Smartbotic Production Build"
- echo " Version: $VERSION"
- echo "=================================================="
- echo ""
- # Clear cache if requested
- if [ "$CLEAR_CACHE" = true ]; then
- clear_build_cache
- fi
- # Check/build base image
- if [ "$REBUILD_BASE" = true ]; then
- log_warn "Force rebuilding base image..."
- build_base_image
- elif base_image_exists; then
- log_success "Base image found: $BASE_IMAGE_NAME"
- else
- log_warn "Base image not found, building..."
- build_base_image
- fi
- # Build packages
- build_packages
- # List created packages
- echo "=================================================="
- echo " Build Complete"
- echo "=================================================="
- echo ""
- log_info "Created packages in $OUTPUT_DIR:"
- echo ""
- ls -lh "$OUTPUT_DIR"/*.tar.gz 2>/dev/null | while read line; do
- echo " $line"
- done
- echo ""
- # Calculate total size
- TOTAL_SIZE=$(du -sh "$OUTPUT_DIR" | cut -f1)
- log_info "Total size: $TOTAL_SIZE"
- echo ""
- # Show cache info
- echo "=================================================="
- echo " Build Cache Info"
- echo "=================================================="
- echo ""
- log_info "BuildKit caches (ccache, npm) are stored persistently."
- log_info "Subsequent builds will be faster due to compilation caching."
- echo ""
- log_info "Cache management commands:"
- echo " $0 --clear-cache # Clear all build caches"
- echo " $0 --no-cache # Build without using caches"
- echo ""
- log_success "Build completed successfully!"
- echo ""
- echo "To deploy to production:"
- echo " scp dist/*.tar.gz root@<server>:/tmp/smartbotic-update/"
- echo " ssh root@<server> '/opt/smartbotic/bin/smartbotic-update --rolling --backup /tmp/smartbotic-update/'"
- echo ""
|