name: Deploy Preview (PR) on: pull_request: types: [opened, reopened, synchronize, closed] permissions: contents: read pull-requests: write jobs: deploy: if: github.event.action != 'closed' name: Helm upgrade/install (PR preview) runs-on: ubuntu-latest concurrency: group: pr-${{ github.event.pull_request.number }} cancel-in-progress: false steps: - name: Checkout uses: actions/checkout@v4 - name: Setup Helm uses: azure/setup-helm@v4 - name: Setup kubectl uses: azure/setup-kubectl@v4 - name: Configure kubeconfig env: KUBE_CONFIG: ${{ secrets.KUBE_CONFIG }} run: | mkdir -p ~/.kube if [ -z "$KUBE_CONFIG" ]; then echo "Secret KUBE_CONFIG is required (kubeconfig content)"; exit 1; fi echo "$KUBE_CONFIG" > ~/.kube/config chmod 600 ~/.kube/config - name: Set up QEMU uses: docker/setup-qemu-action@v3 - name: Set up Docker Buildx id: buildx uses: docker/setup-buildx-action@v3 - name: Log in to Docker Hub uses: docker/login-action@v3 with: username: ${{ secrets.DOCKER_USER }} password: ${{ secrets.DOCKER_PASSWORD }} - name: Compute image repo and tags (PR) run: | IMAGE_REPO="${IMAGE_REPO:-lukastrkan/cc-app-demo}" echo "IMAGE_REPO=$IMAGE_REPO" >> $GITHUB_ENV PR=${{ github.event.pull_request.number }} SHA_SHORT="${GITHUB_SHA::12}" echo "TAG1=pr-$PR" >> $GITHUB_ENV echo "TAG2=pr-$PR-$SHA_SHORT" >> $GITHUB_ENV - name: Build and push image id: build uses: docker/build-push-action@v5 with: context: 7project/backend push: true tags: | ${{ env.IMAGE_REPO }}:${{ env.TAG1 }} ${{ env.IMAGE_REPO }}:${{ env.TAG2 }} platforms: linux/amd64 - name: Helm upgrade/install PR preview env: DEV_BASE_DOMAIN: ${{ secrets.BASE_DOMAIN }} RABBITMQ_PASSWORD: ${{ secrets.RABBITMQ_PASSWORD }} DB_PASSWORD: ${{ secrets.DB_PASSWORD }} IMAGE_REPO: ${{ env.IMAGE_REPO }} run: | PR=${{ github.event.pull_request.number }} if [ -z "$PR" ]; then echo "PR number missing"; exit 1; fi if [ -z "$DEV_BASE_DOMAIN" ]; then echo "Secret DEV_BASE_DOMAIN is required (e.g., dev.example.com)"; exit 1; fi if [ -z "$RABBITMQ_PASSWORD" ]; then echo "Secret DEV_RABBITMQ_PASSWORD is required"; exit 1; fi if [ -z "$DB_PASSWORD" ]; then echo "Secret DEV_DB_PASSWORD is required"; exit 1; fi RELEASE=myapp-pr-$PR NAMESPACE=pr-$PR DOMAIN=pr-$PR.$DEV_BASE_DOMAIN DIGEST='${{ steps.build.outputs.digest }}' if [ -z "$IMAGE_REPO" ]; then IMAGE_REPO="lukastrkan/cc-app-demo"; fi helm upgrade --install "$RELEASE" ./7project/charts/myapp-chart \ -n "$NAMESPACE" --create-namespace \ -f 7project/charts/myapp-chart/values-dev.yaml \ --set prNumber="$PR" \ --set domain="$DOMAIN" \ --set image.repository="$IMAGE_REPO" \ --set image.digest="$DIGEST" \ --set-string rabbitmq.password="$RABBITMQ_PASSWORD" \ --set-string database.password="$DB_PASSWORD" - name: Post preview URL as PR comment uses: actions/github-script@v7 env: DEV_BASE_DOMAIN: ${{ secrets.BASE_DOMAIN }} with: script: | const pr = context.payload.pull_request; if (!pr) { core.setFailed('No pull_request context'); return; } const prNumber = pr.number; const domainBase = process.env.DEV_BASE_DOMAIN; if (!domainBase) { core.setFailed('DEV_BASE_DOMAIN is required'); return; } const domain = `pr-${prNumber}.${domainBase}`; const url = `https://${domain}`; const marker = ''; const body = `${marker}\nPreview environment is running: ${url}\n`; const { owner, repo } = context.repo; const { data: comments } = await github.rest.issues.listComments({ owner, repo, issue_number: prNumber, per_page: 100 }); const existing = comments.find(c => c.body && c.body.includes(marker)); if (existing) { await github.rest.issues.updateComment({ owner, repo, comment_id: existing.id, body }); } else { await github.rest.issues.createComment({ owner, repo, issue_number: prNumber, body }); } uninstall: if: github.event.action == 'closed' name: Helm uninstall (PR preview) runs-on: ubuntu-latest steps: - name: Setup Helm uses: azure/setup-helm@v4 - name: Setup kubectl uses: azure/setup-kubectl@v4 - name: Configure kubeconfig env: KUBE_CONFIG: ${{ secrets.KUBE_CONFIG }} run: | mkdir -p ~/.kube if [ -z "$KUBE_CONFIG" ]; then echo "Secret KUBE_CONFIG is required (kubeconfig content)"; exit 1; fi echo "$KUBE_CONFIG" > ~/.kube/config chmod 600 ~/.kube/config - name: Helm uninstall release and cleanup namespace run: | PR=${{ github.event.pull_request.number }} RELEASE=myapp-pr-$PR NAMESPACE=pr-$PR helm uninstall "$RELEASE" -n "$NAMESPACE" || true # Optionally delete the namespace if empty kubectl delete namespace "$NAMESPACE" --ignore-not-found=true || true