#!/usr/bin/env bash # ============================================================================= # 빌드 공통 스크립트 # Jenkins Stage 2: Build에서 호출 # 환경변수: BUILD_TOOL(maven|gradle|npm|custom), APP_VERSION, WORKSPACE # ============================================================================= set -euo pipefail BUILD_TOOL="${BUILD_TOOL:-auto}" APP_VERSION="${APP_VERSION:-dev-0}" WORKSPACE="${WORKSPACE:-.}" LOG_DIR="${WORKSPACE}/build-logs" BUILD_LOG="${LOG_DIR}/build-$(date +%Y%m%d-%H%M%S).log" GREEN='\033[0;32m'; RED='\033[0;31m'; YELLOW='\033[1;33m'; NC='\033[0m' log() { echo -e "${GREEN}[BUILD]${NC} $*" | tee -a "${BUILD_LOG}"; } err() { echo -e "${RED}[ERROR]${NC} $*" | tee -a "${BUILD_LOG}"; } warn() { echo -e "${YELLOW}[WARN]${NC} $*" | tee -a "${BUILD_LOG}"; } mkdir -p "${LOG_DIR}" # ── 빌드 도구 자동 감지 ────────────────────────────────────────────────────── detect_build_tool() { if [[ "${BUILD_TOOL}" != "auto" ]]; then return fi if [[ -f "${WORKSPACE}/pom.xml" ]]; then BUILD_TOOL="maven" elif [[ -f "${WORKSPACE}/build.gradle" ]] || \ [[ -f "${WORKSPACE}/build.gradle.kts" ]]; then BUILD_TOOL="gradle" elif [[ -f "${WORKSPACE}/package.json" ]]; then BUILD_TOOL="npm" elif [[ -f "${WORKSPACE}/Makefile" ]]; then BUILD_TOOL="make" else err "빌드 파일을 찾을 수 없습니다 (pom.xml / build.gradle / package.json / Makefile)" exit 1 fi log "빌드 도구 자동 감지: ${BUILD_TOOL}" } # ── Maven 빌드 ──────────────────────────────────────────────────────────────── build_maven() { log "Maven 빌드 시작..." cd "${WORKSPACE}" MVN_CMD="mvn" [[ -f "./mvnw" ]] && MVN_CMD="./mvnw" ${MVN_CMD} clean package \ -DskipTests=true \ -Dapp.version="${APP_VERSION}" \ --batch-mode \ --no-transfer-progress \ 2>&1 | tee -a "${BUILD_LOG}" local artifact artifact=$(ls target/*.jar target/*.war 2>/dev/null | head -1 || true) if [[ -z "${artifact}" ]]; then err "빌드 산출물을 찾을 수 없습니다 (target/*.jar|*.war)" exit 1 fi log "빌드 완료: ${artifact}" echo "${artifact}" > "${LOG_DIR}/artifact.path" } # ── Gradle 빌드 ──────────────────────────────────────────────────────────────── build_gradle() { log "Gradle 빌드 시작..." cd "${WORKSPACE}" GRADLE_CMD="gradle" [[ -f "./gradlew" ]] && { GRADLE_CMD="./gradlew"; chmod +x ./gradlew; } ${GRADLE_CMD} clean build \ -x test \ -Pversion="${APP_VERSION}" \ --no-daemon \ --parallel \ 2>&1 | tee -a "${BUILD_LOG}" local artifact artifact=$(ls build/libs/*.jar build/libs/*.war 2>/dev/null | grep -v plain | head -1 || true) if [[ -z "${artifact}" ]]; then err "빌드 산출물을 찾을 수 없습니다 (build/libs/*.jar|*.war)" exit 1 fi log "빌드 완료: ${artifact}" echo "${artifact}" > "${LOG_DIR}/artifact.path" } # ── npm 빌드 ────────────────────────────────────────────────────────────────── build_npm() { log "npm 빌드 시작..." cd "${WORKSPACE}" node --version npm --version # 의존성 설치 if [[ -f "package-lock.json" ]]; then npm ci --prefer-offline else npm install fi # 빌드 npm run build # 아티팩트 패키징 local dist_dir="dist" [[ -d "build" ]] && dist_dir="build" local artifact="app-${APP_VERSION}.tar.gz" tar czf "${artifact}" "${dist_dir}/" log "빌드 완료: ${artifact}" echo "${WORKSPACE}/${artifact}" > "${LOG_DIR}/artifact.path" } # ── make 빌드 ──────────────────────────────────────────────────────────────── build_make() { log "Make 빌드 시작..." cd "${WORKSPACE}" make build VERSION="${APP_VERSION}" 2>&1 | tee -a "${BUILD_LOG}" log "Make 빌드 완료" } # ── 빌드 정보 출력 ──────────────────────────────────────────────────────────── print_build_info() { local artifact_path="${LOG_DIR}/artifact.path" echo "" log "────────────────────────────────────────" log " 빌드 정보" log "────────────────────────────────────────" log " 도구: ${BUILD_TOOL}" log " 버전: ${APP_VERSION}" log " 로그: ${BUILD_LOG}" if [[ -f "${artifact_path}" ]]; then local artifact artifact=$(cat "${artifact_path}") local size size=$(du -sh "${artifact}" 2>/dev/null | cut -f1 || echo "N/A") log " 산출물: ${artifact} (${size})" fi log "────────────────────────────────────────" } # ── 메인 ───────────────────────────────────────────────────────────────────── main() { local start_time=$SECONDS log "=== 빌드 시작: $(date) ===" detect_build_tool case "${BUILD_TOOL}" in maven) build_maven ;; gradle) build_gradle ;; npm) build_npm ;; make) build_make ;; custom) log "사용자 정의 빌드: ${CUSTOM_BUILD_CMD}" eval "${CUSTOM_BUILD_CMD}" 2>&1 | tee -a "${BUILD_LOG}" ;; *) err "알 수 없는 빌드 도구: ${BUILD_TOOL}"; exit 1 ;; esac local elapsed=$((SECONDS - start_time)) print_build_info log "=== 빌드 완료: ${elapsed}초 ===" } main "$@"