name: Backend Services CI/CD on: push: branches: [ main, develop ] paths: - 'user/**' - 'meeting/**' - 'stt/**' - 'ai/**' - 'notification/**' - 'common/**' - '.github/**' pull_request: branches: [ main ] workflow_dispatch: inputs: ENVIRONMENT: description: 'Target environment' required: true default: 'dev' type: choice options: - dev - staging - prod SKIP_SONARQUBE: description: 'Skip SonarQube Analysis' required: false default: 'true' type: choice options: - 'true' - 'false' env: REGISTRY: acrdigitalgarage02.azurecr.io IMAGE_ORG: hgzero RESOURCE_GROUP: rg-digitalgarage-02 AKS_CLUSTER: aks-digitalgarage-02 NAMESPACE: hgzero jobs: build: name: Build and Test runs-on: ubuntu-latest outputs: image_tag: ${{ steps.set_outputs.outputs.image_tag }} environment: ${{ steps.set_outputs.outputs.environment }} steps: - name: Check out code uses: actions/checkout@v4 - name: Set up JDK 21 uses: actions/setup-java@v3 with: java-version: '21' distribution: 'temurin' cache: 'gradle' - name: Determine environment id: determine_env run: | # Use input parameter or default to 'dev' ENVIRONMENT="${{ github.event.inputs.ENVIRONMENT || 'dev' }}" echo "environment=$ENVIRONMENT" >> $GITHUB_OUTPUT - name: Load environment variables id: env_vars run: | ENV=${{ steps.determine_env.outputs.environment }} # Initialize variables with defaults REGISTRY="acrdigitalgarage02.azurecr.io" IMAGE_ORG="hgzero" RESOURCE_GROUP="rg-digitalgarage-02" AKS_CLUSTER="aks-digitalgarage-02" NAMESPACE="hgzero" # Read environment variables from .github/config file if [[ -f ".github/config/deploy_env_vars_${ENV}" ]]; then while IFS= read -r line || [[ -n "$line" ]]; do # Skip comments and empty lines [[ "$line" =~ ^#.*$ ]] && continue [[ -z "$line" ]] && continue # Extract key-value pairs key=$(echo "$line" | cut -d '=' -f1) value=$(echo "$line" | cut -d '=' -f2-) # Override defaults if found in config case "$key" in "resource_group") RESOURCE_GROUP="$value" ;; "cluster_name") AKS_CLUSTER="$value" ;; esac done < ".github/config/deploy_env_vars_${ENV}" fi # Export for other jobs echo "REGISTRY=$REGISTRY" >> $GITHUB_ENV echo "IMAGE_ORG=$IMAGE_ORG" >> $GITHUB_ENV echo "RESOURCE_GROUP=$RESOURCE_GROUP" >> $GITHUB_ENV echo "AKS_CLUSTER=$AKS_CLUSTER" >> $GITHUB_ENV - name: Grant execute permission for gradlew run: chmod +x gradlew - name: Build with Gradle run: | ./gradlew build -x test - name: SonarQube Analysis & Quality Gate env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }} run: | # Check if SonarQube should be skipped SKIP_SONARQUBE="${{ github.event.inputs.SKIP_SONARQUBE || 'true' }}" if [[ "$SKIP_SONARQUBE" == "true" ]]; then echo "⏭️ Skipping SonarQube Analysis (SKIP_SONARQUBE=$SKIP_SONARQUBE)" exit 0 fi # Define services array services=(user meeting stt ai notification) # Run tests, coverage reports, and SonarQube analysis for each service for service in "${services[@]}"; do ./gradlew :$service:test :$service:jacocoTestReport :$service:sonar \ -Dsonar.projectKey=hgzero-$service-${{ steps.determine_env.outputs.environment }} \ -Dsonar.projectName=hgzero-$service-${{ steps.determine_env.outputs.environment }} \ -Dsonar.host.url=$SONAR_HOST_URL \ -Dsonar.token=$SONAR_TOKEN \ -Dsonar.java.binaries=build/classes/java/main \ -Dsonar.coverage.jacoco.xmlReportPaths=build/reports/jacoco/test/jacocoTestReport.xml \ -Dsonar.exclusions=**/config/**,**/entity/**,**/dto/**,**/*Application.class,**/exception/** done - name: Upload build artifacts uses: actions/upload-artifact@v4 with: name: app-builds retention-days: 1 path: | user/build/libs/*.jar meeting/build/libs/*.jar stt/build/libs/*.jar ai/build/libs/*.jar notification/build/libs/*.jar - name: Set outputs id: set_outputs run: | # Generate timestamp for image tag IMAGE_TAG=$(date +%Y%m%d%H%M%S) echo "image_tag=$IMAGE_TAG" >> $GITHUB_OUTPUT echo "environment=${{ steps.determine_env.outputs.environment }}" >> $GITHUB_OUTPUT release: name: Build and Push Docker Images needs: build runs-on: ubuntu-latest steps: - name: Check out code uses: actions/checkout@v4 - name: Download build artifacts uses: actions/download-artifact@v4 with: name: app-builds - name: Set environment variables from build job run: | echo "REGISTRY=${{ env.REGISTRY }}" >> $GITHUB_ENV echo "IMAGE_ORG=${{ env.IMAGE_ORG }}" >> $GITHUB_ENV echo "ENVIRONMENT=${{ needs.build.outputs.environment }}" >> $GITHUB_ENV echo "IMAGE_TAG=${{ needs.build.outputs.image_tag }}" >> $GITHUB_ENV - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Login to Docker Hub (prevent rate limit) uses: docker/login-action@v3 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_PASSWORD }} - name: Login to Azure Container Registry uses: docker/login-action@v3 with: registry: ${{ env.REGISTRY }} username: ${{ secrets.ACR_USERNAME }} password: ${{ secrets.ACR_PASSWORD }} - name: Build and push Docker images for all services run: | # Define services array services=(user meeting stt ai notification) # Build and push each service image for service in "${services[@]}"; do echo "Building and pushing $service..." docker build \ --build-arg BUILD_LIB_DIR="$service/build/libs" \ --build-arg ARTIFACTORY_FILE="$service.jar" \ -f deployment/container/Dockerfile-backend \ -t ${{ env.REGISTRY }}/${{ env.IMAGE_ORG }}/$service:${{ needs.build.outputs.environment }}-${{ needs.build.outputs.image_tag }} . docker push ${{ env.REGISTRY }}/${{ env.IMAGE_ORG }}/$service:${{ needs.build.outputs.environment }}-${{ needs.build.outputs.image_tag }} done update-manifest: name: Update Manifest Repository needs: [build, release] runs-on: ubuntu-latest steps: - name: Set image tag environment variable run: | echo "IMAGE_TAG=${{ needs.build.outputs.image_tag }}" >> $GITHUB_ENV echo "ENVIRONMENT=${{ needs.build.outputs.environment }}" >> $GITHUB_ENV - name: Update Manifest Repository run: | # 매니페스트 레포지토리 클론 REPO_URL=$(echo "https://github.com/hjmoons/hgzero-manifest.git" | sed 's|https://||') git clone https://${{ secrets.GIT_USERNAME }}:${{ secrets.GIT_PASSWORD }}@${REPO_URL} manifest-repo cd manifest-repo # Kustomize 설치 curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash sudo mv kustomize /usr/local/bin/ # 매니페스트 업데이트 cd hgzero-back/kustomize/overlays/${{ env.ENVIRONMENT }} # 각 서비스별 이미지 태그 업데이트 services="user meeting stt ai notification" for service in $services; do kustomize edit set image acrdigitalgarage02.azurecr.io/hgzero/$service:${{ env.ENVIRONMENT }}-${{ env.IMAGE_TAG }} done # Git 설정 및 푸시 cd ../../../.. git config user.name "GitHub Actions" git config user.email "actions@github.com" git add . git commit -m "🚀 Update hgzero ${{ env.ENVIRONMENT }} images to ${{ env.ENVIRONMENT }}-${{ env.IMAGE_TAG }}" git push origin main echo "✅ 매니페스트 업데이트 완료. ArgoCD가 자동으로 배포합니다."