name: CD - Build & Deploy on: push: branches: [ main ] tags: - 'v*' env: REGISTRY: ghcr.io IMAGE_NAME: ${{ github.repository }} jobs: build-and-push: runs-on: ubuntu-latest permissions: contents: read packages: write outputs: image-tag: ${{ steps.meta.outputs.tags }} image-version: ${{ steps.meta.outputs.version }} steps: - name: Checkout code uses: actions/checkout@v3 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2 - name: Log in to Container Registry uses: docker/login-action@v2 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Extract metadata id: meta uses: docker/metadata-action@v4 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} tags: | type=ref,event=branch type=semver,pattern={{version}} type=semver,pattern={{major}}.{{minor}} type=sha,prefix={{branch}}- type=raw,value=latest,enable={{is_default_branch}} - name: Build and push Docker image uses: docker/build-push-action@v4 with: context: . push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} cache-from: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache cache-to: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache,mode=max platforms: linux/amd64 - name: Image digest run: echo "Image pushed with digest ${{ steps.build.outputs.digest }}" package-helm: runs-on: ubuntu-latest needs: build-and-push steps: - name: Checkout code uses: actions/checkout@v3 - name: Install Helm uses: azure/setup-helm@v3 with: version: 'latest' - name: Package Helm chart run: | helm package helm/peikarband --destination . helm repo index . --url https://github.com/${{ github.repository }}/releases/download/${{ github.ref_name }} - name: Upload Helm chart artifact uses: actions/upload-artifact@v3 with: name: helm-chart path: | *.tgz index.yaml deploy-staging: runs-on: ubuntu-latest needs: [build-and-push, package-helm] if: github.ref == 'refs/heads/main' environment: name: staging url: https://staging.peikarband.ir steps: - name: Checkout code uses: actions/checkout@v3 - name: Install kubectl uses: azure/setup-kubectl@v3 - name: Install Helm uses: azure/setup-helm@v3 - name: Configure kubectl run: | echo "${{ secrets.KUBECONFIG_STAGING }}" | base64 -d > kubeconfig export KUBECONFIG=kubeconfig - name: Deploy to Staging run: | export KUBECONFIG=kubeconfig helm upgrade --install peikarband-staging ./helm/peikarband \ --namespace staging \ --create-namespace \ --set image.tag=${{ needs.build-and-push.outputs.image-version }} \ --set image.repository=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} \ --set ingress.hosts[0].host=staging.peikarband.ir \ --wait \ --timeout 5m deploy-production: runs-on: ubuntu-latest needs: [build-and-push, package-helm] if: startsWith(github.ref, 'refs/tags/v') environment: name: production url: https://peikarband.ir steps: - name: Checkout code uses: actions/checkout@v3 - name: Install kubectl uses: azure/setup-kubectl@v3 - name: Install Helm uses: azure/setup-helm@v3 - name: Configure kubectl run: | echo "${{ secrets.KUBECONFIG_PRODUCTION }}" | base64 -d > kubeconfig export KUBECONFIG=kubeconfig - name: Deploy to Production run: | export KUBECONFIG=kubeconfig helm upgrade --install peikarband-prod ./helm/peikarband \ --namespace production \ --create-namespace \ --set image.tag=${{ needs.build-and-push.outputs.image-version }} \ --set image.repository=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} \ --set replicaCount=3 \ --set autoscaling.enabled=true \ --values helm/peikarband/values-production.yaml \ --wait \ --timeout 10m - name: Verify deployment run: | export KUBECONFIG=kubeconfig kubectl rollout status deployment/peikarband-prod -n production kubectl get pods -n production release: runs-on: ubuntu-latest needs: [build-and-push, package-helm, deploy-production] if: startsWith(github.ref, 'refs/tags/v') permissions: contents: write steps: - name: Checkout code uses: actions/checkout@v3 - name: Download Helm chart uses: actions/download-artifact@v3 with: name: helm-chart - name: Create Release uses: softprops/action-gh-release@v1 with: files: | *.tgz index.yaml generate_release_notes: true draft: false prerelease: false