name: Deploy Preview (PR) on: pull_request: types: [opened, reopened, synchronize, closed] permissions: contents: read pull-requests: write jobs: test: name: Run Python Tests if: github.event.action != 'closed' runs-on: ubuntu-latest steps: - name: Check out repository code uses: actions/checkout@v4 - name: Set up Python 3.11 uses: actions/setup-python@v5 with: python-version: '3.11' - name: Install dependencies run: | python -m pip install --upgrade pip pip install -r requirements.txt - name: Run tests with pytest run: pytest working-directory: ./7project/backend build: if: github.event.action != 'closed' name: Build and push image (reusable) uses: ./.github/workflows/build-image.yaml with: mode: pr image_repo: lukastrkan/cc-app-demo context: 7project/backend pr_number: ${{ github.event.pull_request.number }} secrets: inherit get_urls: if: github.event.action != 'closed' name: Generate Preview URLs uses: ./.github/workflows/url_generator.yml with: runner: vhs mode: pr pr_number: ${{ github.event.pull_request.number }} base_domain: ${{ vars.DEV_BASE_DOMAIN }} secrets: inherit frontend: if: github.event.action != 'closed' name: Frontend - Build and Deploy to Cloudflare Pages (PR) needs: [get_urls] uses: ./.github/workflows/frontend-pages.yml with: mode: pr pr_number: ${{ github.event.pull_request.number }} backend_url_scheme: ${{ needs.get_urls.outputs.backend_url_scheme }} secrets: inherit deploy: if: github.event.action != 'closed' name: Helm upgrade/install (PR preview) runs-on: vhs concurrency: group: pr-${{ github.event.pull_request.number }} cancel-in-progress: false needs: [build, frontend, get_urls] 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: Helm upgrade/install PR preview env: DEV_BASE_DOMAIN: ${{ secrets.BASE_DOMAIN }} RABBITMQ_PASSWORD: ${{ secrets.PROD_RABBITMQ_PASSWORD }} DB_PASSWORD: ${{ secrets.PROD_DB_PASSWORD }} DIGEST: ${{ needs.build.outputs.digest }} DOMAIN: "${{ needs.get_urls.outputs.backend_url }}" DOMAIN_SCHEME: "${{ needs.get_urls.outputs.backend_url_scheme }}" FRONTEND_DOMAIN: "${{ needs.get_urls.outputs.frontend_url }}" FRONTEND_DOMAIN_SCHEME: "${{ needs.get_urls.outputs.frontend_url_scheme }}" run: | PR=${{ github.event.pull_request.number }} RELEASE=myapp-pr-$PR NAMESPACE=pr-$PR helm upgrade --install "$RELEASE" ./7project/charts/myapp-chart \ -n "$NAMESPACE" --create-namespace \ -f 7project/charts/myapp-chart/values-dev.yaml \ --set prNumber="$PR" \ --set deployment="pr-$PR" \ --set domain="$DOMAIN" \ --set domain_scheme="$DOMAIN_SCHEME" \ --set frontend_domain="$FRONTEND_DOMAIN" \ --set frontend_domain_scheme="$FRONTEND_DOMAIN_SCHEME" \ --set image.digest="$DIGEST" \ --set-string rabbitmq.password="$RABBITMQ_PASSWORD" \ --set-string database.password="$DB_PASSWORD" - name: Post preview URLs as PR comment uses: actions/github-script@v7 env: BACKEND_URL: ${{ needs.get_urls.outputs.backend_url_scheme }} FRONTEND_URL: ${{ needs.get_urls.outputs.frontend_url_scheme }} with: script: | const pr = context.payload.pull_request; if (!pr) { core.setFailed('No pull_request context'); return; } const prNumber = pr.number; const backendUrl = process.env.BACKEND_URL || '(not available)'; const frontendUrl = process.env.FRONTEND_URL || '(not available)'; const marker = ''; const body = `${marker}\nPreview environment is running\n- Frontend: ${frontendUrl}\n- Backend: ${backendUrl}\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: vhs 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