diff --git a/.github/workflows/cicd.yaml b/.github/workflows/cicd.yaml index 3fff54f..18f46eb 100644 --- a/.github/workflows/cicd.yaml +++ b/.github/workflows/cicd.yaml @@ -5,136 +5,123 @@ on: branches: [ main ] env: - # Team Settings - TEAMID: dg0200 - ROOT_PROJECT: lifesub-web - - # Container Registry Settings REGISTRY: dg0200cr.azurecr.io IMAGE_ORG: lifesub - - # Application Settings - REPLICAS: 1 - EXPORT_PORT: 18080 - - # Backend Service URLs - REACT_APP_MEMBER_URL: http://20.249.185.127/member - REACT_APP_MYSUB_URL: http://20.249.185.127/mysub - REACT_APP_RECOMMEND_URL: http://20.249.185.127/recommend - - # Resource Settings - RESOURCES_REQUESTS_CPU: 256m - RESOURCES_REQUESTS_MEMORY: 256Mi - RESOURCES_LIMITS_CPU: 1024m - RESOURCES_LIMITS_MEMORY: 1024Mi + APP_NAME: lifesub-web + NAMESPACE: dg0200-lifesub-web-ns jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - + - name: Checkout code + uses: actions/checkout@v4 + - name: Set up Node.js - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version: '20' - + cache: 'npm' + - name: Install dependencies run: npm ci - + - name: Build application run: npm run build - - - name: Upload build artifacts - uses: actions/upload-artifact@v3 + + - name: Upload build artifact + uses: actions/upload-artifact@v4 with: - name: build-artifacts + name: build-files path: build/ release: needs: build runs-on: ubuntu-latest outputs: - image_tag: ${{ steps.create_tag.outputs.tag }} + image_tag: ${{ steps.set_tag.outputs.tag }} steps: - - uses: actions/checkout@v3 - - - name: Create image tag - id: create_tag + - name: Checkout code + uses: actions/checkout@v4 + + - name: Download build artifact + uses: actions/download-artifact@v4 + with: + name: build-files + path: build/ + + - name: Generate image tag + id: set_tag run: | tag=$(date +'%Y%m%d%H%M%S') echo "tag=${tag}" >> $GITHUB_OUTPUT - - - name: Download build artifacts - uses: actions/download-artifact@v3 - with: - name: build-artifacts - path: build/ - - - name: Azure Container Registry login + + - 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 Docker image run: | docker build \ --build-arg PROJECT_FOLDER="." \ - --build-arg REACT_APP_MEMBER_URL="${{ env.REACT_APP_MEMBER_URL }}" \ - --build-arg REACT_APP_MYSUB_URL="${{ env.REACT_APP_MYSUB_URL }}" \ - --build-arg REACT_APP_RECOMMEND_URL="${{ env.REACT_APP_RECOMMEND_URL }}" \ + --build-arg REACT_APP_MEMBER_URL="http://20.249.185.127/member" \ + --build-arg REACT_APP_MYSUB_URL="http://20.249.185.127/mysub" \ + --build-arg REACT_APP_RECOMMEND_URL="http://20.249.185.127/recommend" \ --build-arg BUILD_FOLDER="deployment" \ - --build-arg EXPORT_PORT="${{ env.EXPORT_PORT }}" \ + --build-arg EXPORT_PORT="18080" \ -f deployment/Dockerfile-lifesub-web \ - -t ${{ env.REGISTRY }}/${{ env.IMAGE_ORG }}/lifesub-web:${{ steps.create_tag.outputs.tag }} . - docker push ${{ env.REGISTRY }}/${{ env.IMAGE_ORG }}/lifesub-web:${{ steps.create_tag.outputs.tag }} + -t ${{ env.REGISTRY }}/${{ env.IMAGE_ORG }}/${{ env.APP_NAME }}:${{ steps.set_tag.outputs.tag }} . + docker push ${{ env.REGISTRY }}/${{ env.IMAGE_ORG }}/${{ env.APP_NAME }}:${{ steps.set_tag.outputs.tag }} deploy: needs: release runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - - name: Azure login + - name: Checkout code + uses: actions/checkout@v4 + + - 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: Create namespace + cluster-name: dg0200-aks + + - name: Create namespace if not exists run: | - kubectl create namespace ${{ env.TEAMID }}-${{ env.ROOT_PROJECT }}-ns --dry-run=client -o yaml | kubectl apply -f - - + kubectl create namespace ${{ env.NAMESPACE }} --dry-run=client -o yaml | kubectl apply -f - + - name: Generate deployment manifest run: | - export namespace=${{ env.TEAMID }}-${{ env.ROOT_PROJECT }}-ns - export lifesub_web_image_path=${{ env.REGISTRY }}/${{ env.IMAGE_ORG }}/lifesub-web:${{ needs.release.outputs.image_tag }} - export replicas=${{ env.REPLICAS }} - export export_port=${{ env.EXPORT_PORT }} - 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 }} + export namespace=${{ env.NAMESPACE }} + export lifesub_web_image_path=${{ env.REGISTRY }}/${{ env.IMAGE_ORG }}/${{ env.APP_NAME }}:${{ needs.release.outputs.image_tag }} + export replicas=1 + export export_port=18080 + export resources_requests_cpu=256m + export resources_requests_memory=256Mi + export resources_limits_cpu=1024m + export resources_limits_memory=1024Mi envsubst < deployment/deploy.yaml.template > deployment/deploy.yaml + echo "Generated manifest:" cat deployment/deploy.yaml - + - name: Deploy to AKS run: | kubectl apply -f deployment/deploy.yaml echo "Waiting for deployment to be ready..." - kubectl -n ${{ env.TEAMID }}-${{ env.ROOT_PROJECT }}-ns wait --for=condition=available deployment/lifesub-web --timeout=300s + kubectl -n ${{ env.NAMESPACE }} wait --for=condition=available deployment/lifesub-web --timeout=300s echo "Waiting for service external IP..." - while [[ -z $(kubectl -n ${{ env.TEAMID }}-${{ env.ROOT_PROJECT }}-ns get svc lifesub-web -o jsonpath='{.status.loadBalancer.ingress[0].ip}') ]]; do + while [[ -z $(kubectl -n ${{ env.NAMESPACE }} get svc lifesub-web -o jsonpath='{.status.loadBalancer.ingress[0].ip}') ]]; do sleep 5 done - echo "Service external IP: $(kubectl -n ${{ env.TEAMID }}-${{ env.ROOT_PROJECT }}-ns get svc lifesub-web -o jsonpath='{.status.loadBalancer.ingress[0].ip}')" \ No newline at end of file + echo "Service external IP: $(kubectl -n ${{ env.NAMESPACE }} get svc lifesub-web -o jsonpath='{.status.loadBalancer.ingress[0].ip}')" \ No newline at end of file