diff --git a/.github/workflows/cicd.yaml b/.github/workflows/cicd.yaml new file mode 100644 index 0000000..f06b5ab --- /dev/null +++ b/.github/workflows/cicd.yaml @@ -0,0 +1,274 @@ +name: Backend Services CI/CD + +on: + push: + #branches: [ cicd ] + paths: + - 'member/**' + - 'mysub/**' + - 'recommend/**' + - 'common/**' + - 'deployment/**' + - '.github/workflows/**' + +jobs: + build: + name: Build and Test + runs-on: ubuntu-latest + outputs: + image_tag: ${{ steps.set_outputs.outputs.image_tag }} + + 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: Load environment variables + id: env_vars + run: | + # Read environment variables from file + 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-) + + # Set GitHub environment variables + echo "$key=$value" >> $GITHUB_ENV + done < deployment/deploy_env_vars + + - name: Grant execute permission for gradlew + run: chmod +x gradlew + + - name: Build with Gradle + run: | + ./gradlew :member:build :mysub-infra:build :recommend:build -x test + + - name: Test with Gradle + run: | + ./gradlew :member:test :member:jacocoTestReport + ./gradlew :mysub-infra:test :mysub-infra:jacocoTestReport + ./gradlew :recommend:test :recommend:jacocoTestReport + + - name: SonarQube Analysis + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }} + run: | + ./gradlew :member:sonar \ + -Dsonar.projectKey=lifesub-member \ + -Dsonar.projectName=lifesub-member \ + -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 + + ./gradlew :mysub-infra:sonar \ + -Dsonar.projectKey=lifesub-mysub \ + -Dsonar.projectName=lifesub-mysub \ + -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 + + ./gradlew :recommend:sonar \ + -Dsonar.projectKey=lifesub-recommend \ + -Dsonar.projectName=lifesub-recommend \ + -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 + + - name: Upload build artifacts + uses: actions/upload-artifact@v4 + with: + name: app-builds + path: | + member/build/libs/*.jar + mysub-infra/build/libs/*.jar + recommend/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 + + 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: Load environment variables + run: | + # Read environment variables from file + 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-) + + # Set GitHub environment variables + echo "$key=$value" >> $GITHUB_ENV + done < deployment/deploy_env_vars + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - 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 Member service image + uses: docker/build-push-action@v5 + with: + context: . + file: deployment/Dockerfile + push: true + tags: ${{ env.registry }}/${{ env.image_org }}/member:${{ needs.build.outputs.image_tag }} + build-args: | + BUILD_LIB_DIR=member/build/libs + ARTIFACTORY_FILE=member.jar + + - name: Build and push MySub service image + uses: docker/build-push-action@v5 + with: + context: . + file: deployment/Dockerfile + push: true + tags: ${{ env.registry }}/${{ env.image_org }}/mysub:${{ needs.build.outputs.image_tag }} + build-args: | + BUILD_LIB_DIR=mysub-infra/build/libs + ARTIFACTORY_FILE=mysub.jar + + - name: Build and push Recommend service image + uses: docker/build-push-action@v5 + with: + context: . + file: deployment/Dockerfile + push: true + tags: ${{ env.registry }}/${{ env.image_org }}/recommend:${{ needs.build.outputs.image_tag }} + build-args: | + BUILD_LIB_DIR=recommend/build/libs + ARTIFACTORY_FILE=recommend.jar + + deploy: + name: Deploy to Kubernetes + needs: [build, release] + runs-on: ubuntu-latest + + steps: + - name: Check out code + uses: actions/checkout@v4 + + - name: Load environment variables + run: | + # Read environment variables from file + 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-) + + # Set GitHub environment variables + echo "$key=$value" >> $GITHUB_ENV + done < deployment/deploy_env_vars + + - name: Set image tag environment variable + run: | + echo "IMAGE_TAG=${{ needs.build.outputs.image_tag }}" >> $GITHUB_ENV + + # Azure CLI 설치 단계 수정 + - name: Install Azure CLI + run: | + curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash + + - name: Azure Login + uses: azure/login@v1 + with: + creds: ${{ secrets.AZURE_CREDENTIALS }} + + - name: Setup kubectl + uses: azure/setup-kubectl@v3 + + - name: Get AKS Credentials + run: | + az aks get-credentials --resource-group ictcoe-edu --name ${{ env.teamid }}-aks --overwrite-existing + + - name: Create namespace + run: | + kubectl create namespace ${{ env.namespace }} --dry-run=client -o yaml | kubectl apply -f - + + - name: Install envsubst + run: | + sudo apt-get update + sudo apt-get install -y gettext-base + + - name: Generate Kubernetes manifest + run: | + # Set environment variables for the deployment template + export namespace=${{ env.namespace }} + export allowed_origins=${{ env.allowed_origins }} + export jwt_secret_key=${{ env.jwt_secret_key }} + export postgres_user=${{ env.postgres_user }} + export postgres_password=${{ env.postgres_password }} + export replicas=${{ env.replicas }} + export resources_requests_cpu=${{ env.resources_requests_cpu }} + export resources_requests_memory=${{ env.resources_requests_memory }} + export resources_limits_cpu=${{ env.resources_limits_cpu }} + export resources_limits_memory=${{ env.resources_limits_memory }} + + # Set image paths with the dynamic tag + export member_image_path=${{ env.registry }}/${{ env.image_org }}/member:${{ env.IMAGE_TAG }} + export mysub_image_path=${{ env.registry }}/${{ env.image_org }}/mysub:${{ env.IMAGE_TAG }} + export recommend_image_path=${{ env.registry }}/${{ env.image_org }}/recommend:${{ env.IMAGE_TAG }} + + # Generate the manifest file using envsubst + envsubst < deployment/deploy.yaml.template > deployment/deploy.yaml + + # Print manifest for debugging + echo "Generated Kubernetes manifest:" + cat deployment/deploy.yaml + + - name: Apply Kubernetes manifest + run: | + kubectl apply -f deployment/deploy.yaml + + - name: Wait for deployments to be ready + run: | + kubectl -n ${{ env.namespace }} wait --for=condition=available deployment/member --timeout=300s + kubectl -n ${{ env.namespace }} wait --for=condition=available deployment/mysub --timeout=300s + kubectl -n ${{ env.namespace }} wait --for=condition=available deployment/recommend --timeout=300s + + - name: Get service information + run: | + echo "Ingress IP: $(kubectl -n ${{ env.namespace }} get ingress lifesub -o jsonpath='{.status.loadBalancer.ingress[0].ip}')" diff --git a/.gradle/8.10/checksums/checksums.lock b/.gradle/8.10/checksums/checksums.lock new file mode 100644 index 0000000..54b9316 Binary files /dev/null and b/.gradle/8.10/checksums/checksums.lock differ diff --git a/.gradle/8.10/checksums/md5-checksums.bin b/.gradle/8.10/checksums/md5-checksums.bin new file mode 100644 index 0000000..1c2a3d0 Binary files /dev/null and b/.gradle/8.10/checksums/md5-checksums.bin differ diff --git a/.gradle/8.10/checksums/sha1-checksums.bin b/.gradle/8.10/checksums/sha1-checksums.bin new file mode 100644 index 0000000..7ee5530 Binary files /dev/null and b/.gradle/8.10/checksums/sha1-checksums.bin differ diff --git a/.gradle/8.4/dependencies-accessors/gc.properties b/.gradle/8.10/dependencies-accessors/gc.properties similarity index 100% rename from .gradle/8.4/dependencies-accessors/gc.properties rename to .gradle/8.10/dependencies-accessors/gc.properties diff --git a/.gradle/8.10/executionHistory/executionHistory.bin b/.gradle/8.10/executionHistory/executionHistory.bin new file mode 100644 index 0000000..cbc0467 Binary files /dev/null and b/.gradle/8.10/executionHistory/executionHistory.bin differ diff --git a/.gradle/8.10/executionHistory/executionHistory.lock b/.gradle/8.10/executionHistory/executionHistory.lock new file mode 100644 index 0000000..1831748 Binary files /dev/null and b/.gradle/8.10/executionHistory/executionHistory.lock differ diff --git a/.gradle/8.4/fileChanges/last-build.bin b/.gradle/8.10/fileChanges/last-build.bin similarity index 100% rename from .gradle/8.4/fileChanges/last-build.bin rename to .gradle/8.10/fileChanges/last-build.bin diff --git a/.gradle/8.10/fileHashes/fileHashes.bin b/.gradle/8.10/fileHashes/fileHashes.bin new file mode 100644 index 0000000..c63e7cb Binary files /dev/null and b/.gradle/8.10/fileHashes/fileHashes.bin differ diff --git a/.gradle/8.10/fileHashes/fileHashes.lock b/.gradle/8.10/fileHashes/fileHashes.lock new file mode 100644 index 0000000..7efd6e1 Binary files /dev/null and b/.gradle/8.10/fileHashes/fileHashes.lock differ diff --git a/.gradle/8.4/checksums/md5-checksums.bin b/.gradle/8.10/fileHashes/resourceHashesCache.bin similarity index 67% rename from .gradle/8.4/checksums/md5-checksums.bin rename to .gradle/8.10/fileHashes/resourceHashesCache.bin index c4cd60f..b0d9532 100644 Binary files a/.gradle/8.4/checksums/md5-checksums.bin and b/.gradle/8.10/fileHashes/resourceHashesCache.bin differ diff --git a/.gradle/8.4/gc.properties b/.gradle/8.10/gc.properties similarity index 100% rename from .gradle/8.4/gc.properties rename to .gradle/8.10/gc.properties diff --git a/.gradle/8.4/checksums/checksums.lock b/.gradle/8.4/checksums/checksums.lock deleted file mode 100644 index a40b6ec..0000000 Binary files a/.gradle/8.4/checksums/checksums.lock and /dev/null differ diff --git a/.gradle/8.4/checksums/sha1-checksums.bin b/.gradle/8.4/checksums/sha1-checksums.bin deleted file mode 100644 index d218812..0000000 Binary files a/.gradle/8.4/checksums/sha1-checksums.bin and /dev/null differ diff --git a/.gradle/8.4/dependencies-accessors/dependencies-accessors.lock b/.gradle/8.4/dependencies-accessors/dependencies-accessors.lock deleted file mode 100644 index d286ed7..0000000 Binary files a/.gradle/8.4/dependencies-accessors/dependencies-accessors.lock and /dev/null differ diff --git a/.gradle/8.4/executionHistory/executionHistory.bin b/.gradle/8.4/executionHistory/executionHistory.bin deleted file mode 100644 index 13b10dd..0000000 Binary files a/.gradle/8.4/executionHistory/executionHistory.bin and /dev/null differ diff --git a/.gradle/8.4/executionHistory/executionHistory.lock b/.gradle/8.4/executionHistory/executionHistory.lock deleted file mode 100644 index 2373254..0000000 Binary files a/.gradle/8.4/executionHistory/executionHistory.lock and /dev/null differ diff --git a/.gradle/8.4/fileHashes/fileHashes.bin b/.gradle/8.4/fileHashes/fileHashes.bin deleted file mode 100644 index 0528af3..0000000 Binary files a/.gradle/8.4/fileHashes/fileHashes.bin and /dev/null differ diff --git a/.gradle/8.4/fileHashes/fileHashes.lock b/.gradle/8.4/fileHashes/fileHashes.lock deleted file mode 100644 index 0ec05f6..0000000 Binary files a/.gradle/8.4/fileHashes/fileHashes.lock and /dev/null differ diff --git a/.gradle/8.4/fileHashes/resourceHashesCache.bin b/.gradle/8.4/fileHashes/resourceHashesCache.bin deleted file mode 100644 index e55db9c..0000000 Binary files a/.gradle/8.4/fileHashes/resourceHashesCache.bin and /dev/null differ diff --git a/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/.gradle/buildOutputCleanup/buildOutputCleanup.lock index 701d69c..8910022 100644 Binary files a/.gradle/buildOutputCleanup/buildOutputCleanup.lock and b/.gradle/buildOutputCleanup/buildOutputCleanup.lock differ diff --git a/.gradle/buildOutputCleanup/cache.properties b/.gradle/buildOutputCleanup/cache.properties index 99fad32..8f2bf5d 100644 --- a/.gradle/buildOutputCleanup/cache.properties +++ b/.gradle/buildOutputCleanup/cache.properties @@ -1,2 +1,2 @@ -#Wed Feb 12 15:21:47 KST 2025 -gradle.version=8.4 +#Sat Feb 15 20:31:45 KST 2025 +gradle.version=8.10 diff --git a/.gradle/buildOutputCleanup/outputFiles.bin b/.gradle/buildOutputCleanup/outputFiles.bin index 06e466b..b09a2bf 100644 Binary files a/.gradle/buildOutputCleanup/outputFiles.bin and b/.gradle/buildOutputCleanup/outputFiles.bin differ diff --git a/.gradle/file-system.probe b/.gradle/file-system.probe index 88c418f..c3d150e 100644 Binary files a/.gradle/file-system.probe and b/.gradle/file-system.probe differ diff --git a/.idea/compiler.xml b/.idea/compiler.xml index a49a46e..e4d4aff 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -8,13 +8,18 @@ + + + + + - + - + \ No newline at end of file diff --git a/.idea/dictionaries/hiond.xml b/.idea/dictionaries/hiond.xml new file mode 100644 index 0000000..9c8e361 --- /dev/null +++ b/.idea/dictionaries/hiond.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml index 97657e0..e62aa53 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -1,5 +1,6 @@ +