diff --git a/.github/cicd.yaml b/.github/cicd.yaml new file mode 100644 index 0000000..f55dd0c --- /dev/null +++ b/.github/cicd.yaml @@ -0,0 +1,171 @@ +name: Backend CI/CD Pipeline + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +env: + # Team Settings + TEAMID: dg0200 + ROOT_PROJECT: lifesub + + # Container Registry Settings + REGISTRY: dg0200cr.azurecr.io + IMAGE_ORG: lifesub + + # Application Settings + REPLICAS: 2 + ALLOWED_ORIGINS: http://20.249.193.161 + + # Security Settings + JWT_SECRET_KEY: 8O2HQ13etL2BWZvYOiWsJ5uWFoLi6NBUG8divYVoCgtHVvlk3dqRksMl16toztDUeBTSIuOOPvHIrYq11G2BwQ + POSTGRES_USER: admin + POSTGRES_PASSWORD: Passw0rd + + # Resource Settings + RESOURCES_REQUESTS_CPU: 256m + RESOURCES_REQUESTS_MEMORY: 256Mi + RESOURCES_LIMITS_CPU: 1024m + RESOURCES_LIMITS_MEMORY: 1024Mi + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Set up JDK 21 + uses: actions/setup-java@v3 + with: + java-version: '21' + distribution: 'temurin' + cache: gradle + + - name: Setup Gradle + uses: gradle/gradle-build-action@v2 + + - name: Build with Gradle + run: | + chmod +x gradlew + ./gradlew clean :member:build :mysub-infra:build :recommend:build + + - name: Upload build artifacts + uses: actions/upload-artifact@v3 + with: + name: build-artifacts + path: | + member/build/libs + mysub-infra/build/libs + recommend/build/libs + + release: + needs: build + runs-on: ubuntu-latest + outputs: + image_tag: ${{ steps.set-image-tag.outputs.image_tag }} + steps: + - uses: actions/checkout@v3 + + - name: Download build artifacts + uses: actions/download-artifact@v3 + with: + name: build-artifacts + + - name: Set image tag + id: set-image-tag + run: | + echo "image_tag=$(date +'%Y%m%d%H%M%S')" >> $GITHUB_OUTPUT + + - name: Login to Azure Container Registry + uses: azure/docker-login@v1 + with: + login-server: ${{ env.REGISTRY }} + username: ${{ secrets.ACR_USERNAME }} + password: ${{ secrets.ACR_PASSWORD }} + + - name: Build and push images + run: | + IMAGE_TAG=${{ steps.set-image-tag.outputs.image_tag }} + + # Build and push member service + docker build \ + --build-arg BUILD_LIB_DIR="member/build/libs" \ + --build-arg ARTIFACTORY_FILE="member.jar" \ + -f deployment/Dockerfile \ + -t ${{ env.REGISTRY }}/${{ env.IMAGE_ORG }}/member:${IMAGE_TAG} . + docker push ${{ env.REGISTRY }}/${{ env.IMAGE_ORG }}/member:${IMAGE_TAG} + + # Build and push mysub service + docker build \ + --build-arg BUILD_LIB_DIR="mysub-infra/build/libs" \ + --build-arg ARTIFACTORY_FILE="mysub.jar" \ + -f deployment/Dockerfile \ + -t ${{ env.REGISTRY }}/${{ env.IMAGE_ORG }}/mysub:${IMAGE_TAG} . + docker push ${{ env.REGISTRY }}/${{ env.IMAGE_ORG }}/mysub:${IMAGE_TAG} + + # Build and push recommend service + docker build \ + --build-arg BUILD_LIB_DIR="recommend/build/libs" \ + --build-arg ARTIFACTORY_FILE="recommend.jar" \ + -f deployment/Dockerfile \ + -t ${{ env.REGISTRY }}/${{ env.IMAGE_ORG }}/recommend:${IMAGE_TAG} . + docker push ${{ env.REGISTRY }}/${{ env.IMAGE_ORG }}/recommend:${IMAGE_TAG} + + deploy: + needs: release + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Azure Login + uses: azure/login@v1 + with: + creds: ${{ secrets.AZURE_CREDENTIALS }} + + - name: Set AKS Context + uses: azure/aks-set-context@v3 + with: + resource-group: ictcoe-edu + cluster-name: ${{ env.TEAMID }}-aks + + - name: Generate manifest + env: + IMAGE_TAG: ${{ needs.release.outputs.image_tag }} + NAMESPACE: ${{ env.TEAMID }}-${{ env.ROOT_PROJECT }}-ns + run: | + # Create namespace if not exists + kubectl create namespace ${NAMESPACE} --dry-run=client -o yaml | kubectl apply -f - + + # Set environment variables for envsubst + export namespace=${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 + export member_image_path=${{ env.REGISTRY }}/${{ env.IMAGE_ORG }}/member:${IMAGE_TAG} + export mysub_image_path=${{ env.REGISTRY }}/${{ env.IMAGE_ORG }}/mysub:${IMAGE_TAG} + export recommend_image_path=${{ env.REGISTRY }}/${{ env.IMAGE_ORG }}/recommend:${IMAGE_TAG} + + # Generate manifest + envsubst < deployment/deploy.yaml.template > deployment/deploy.yaml + + # Debug: Print generated manifest + cat deployment/deploy.yaml + + - name: Deploy to AKS + run: | + kubectl apply -f deployment/deploy.yaml + + echo "Waiting for deployments to be ready..." + kubectl -n ${{ env.TEAMID }}-${{ env.ROOT_PROJECT }}-ns wait --for=condition=available deployment/member --timeout=300s + kubectl -n ${{ env.TEAMID }}-${{ env.ROOT_PROJECT }}-ns wait --for=condition=available deployment/mysub --timeout=300s + kubectl -n ${{ env.TEAMID }}-${{ env.ROOT_PROJECT }}-ns wait --for=condition=available deployment/recommend --timeout=300s \ No newline at end of file diff --git a/.github/workflows b/.github/workflows new file mode 100644 index 0000000..e69de29