From 3a929dcbef49145810827cc6c2b2d944410028a0 Mon Sep 17 00:00:00 2001 From: sh4mbhavi Date: Tue, 8 Sep 2026 16:06:21 +1000 Subject: [PATCH 1/2] ci: remove the preview-deploy workflows and the credential they carry The deploy job cannot start. `docker-compose.yml:39` requires `POSTGRES_PASSWORD` -- made required upstream in `f7981302` -- and the workflow sets it nowhere in its 430 lines, so `docker compose up -d db redis opa` at line 240 aborts. While it sits there unable to run, lines 273 and 322 carry the published default database password inside a `postgresql+asyncpg://` URL on a `docker run` command line. detect-secrets 1.5.0 reports it as Basic Auth Credentials at line 267 and `.secrets.baseline` allowlists nothing. The build job in front of it still ran, pushing three mutable `pr-` tags to GHCR on every trigger, so the stack burned CI minutes and published images for an environment that could never come up. `pr.preview-teardown.yml` and `pr.preview-instructions.yml` exist only to tear down and to advertise that environment, so all three go together. Three README paragraphs described the machinery being deleted: the project overview called the monorepo an enabler of "rapid automated deployments to the cloud", the Docker Builds section said production images are pushed to Docker Hub and to GCP Artifact Registry, and Contact & Support routed production deployment queries to a DevOps lead managing GCP integration. After this deletion `git grep -rn "ghcr.io\|build-push-action\|docker push" .github/workflows/` is empty, `ci.grype.yml` already records that its image build was replaced by a directory scan because Docker Hub is no longer configured, and the only workflow still referencing GCP, `ops.collector.yml`, is hard-disabled because it used a long-lived service-account key. The credential remains in git history, so it still has to be rotated. Deleting the file removes one place it is stored, not the exposure. --- .github/workflows/pr.preview-deploy.yml | 412 ------------------ .github/workflows/pr.preview-instructions.yml | 32 -- .github/workflows/pr.preview-teardown.yml | 118 ----- README.md | 17 +- 4 files changed, 11 insertions(+), 568 deletions(-) delete mode 100644 .github/workflows/pr.preview-deploy.yml delete mode 100644 .github/workflows/pr.preview-instructions.yml delete mode 100644 .github/workflows/pr.preview-teardown.yml diff --git a/.github/workflows/pr.preview-deploy.yml b/.github/workflows/pr.preview-deploy.yml deleted file mode 100644 index 597f24c8e..000000000 --- a/.github/workflows/pr.preview-deploy.yml +++ /dev/null @@ -1,412 +0,0 @@ -name: Preview Deploy - -on: - pull_request: - types: [labeled] - workflow_dispatch: - inputs: - pr_number: - description: "PR number to simulate (for manual testing)" - required: true - default: "1" - m365: - description: "Include PowerShell service for M365 scans" - required: false - default: "false" - -permissions: - contents: read - pull-requests: write - issues: write - packages: write - -jobs: - # ───────────────────────────────────────────────────────────────────────────── - # Job 0 — Gate: validate trigger, resolve PR number, remove consumed label - # ───────────────────────────────────────────────────────────────────────────── - gate: - runs-on: ubuntu-latest - if: >- - github.event_name == 'workflow_dispatch' || - (github.event_name == 'pull_request' && - (github.event.label.name == 'deploy-preview' || - github.event.label.name == 'deploy-preview-m365')) - outputs: - pr-number: ${{ steps.pr.outputs.number }} - short-sha: ${{ steps.sha.outputs.short }} - m365: ${{ steps.pr.outputs.m365 }} - - steps: - - name: Resolve PR number - id: pr - run: | - if [ "${{ github.event_name }}" = "pull_request" ]; then - echo "number=${{ github.event.number }}" >> "$GITHUB_OUTPUT" - if [ "${{ github.event.label.name }}" = "deploy-preview-m365" ]; then - echo "m365=true" >> "$GITHUB_OUTPUT" - else - echo "m365=false" >> "$GITHUB_OUTPUT" - fi - else - echo "number=${{ inputs.pr_number }}" >> "$GITHUB_OUTPUT" - echo "m365=${{ inputs.m365 }}" >> "$GITHUB_OUTPUT" - fi - - - name: Resolve short SHA - id: sha - run: | - if [ "${{ github.event_name }}" = "pull_request" ]; then - echo "short=$(echo '${{ github.event.pull_request.head.sha }}' | cut -c1-7)" >> "$GITHUB_OUTPUT" - else - echo "short=$(echo '${{ github.sha }}' | cut -c1-7)" >> "$GITHUB_OUTPUT" - fi - - - name: Remove triggering label - if: github.event_name == 'pull_request' - uses: actions/github-script@v7 - with: - script: | - await github.rest.issues.removeLabel({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: context.payload.pull_request.number, - name: context.payload.label.name, - }); - - # ───────────────────────────────────────────────────────────────────────────── - # Job 1 — Build backend and worker images, push to GHCR - # Uses GitHub Actions cache (type=gha) for layer reuse so no Docker Hub token needed - # Only GITHUB_TOKEN is required (packages: write permission above) - # ───────────────────────────────────────────────────────────────────────────── - build-images: - runs-on: ubuntu-latest - needs: gate - - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Log in to GHCR - uses: docker/login-action@v3 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Set lowercase image names - run: | - echo "BACKEND_IMAGE=ghcr.io/${GITHUB_REPOSITORY,,}/backend:pr-${{ needs.gate.outputs.pr-number }}" >> "$GITHUB_ENV" - echo "WORKER_IMAGE=ghcr.io/${GITHUB_REPOSITORY,,}/worker:pr-${{ needs.gate.outputs.pr-number }}" >> "$GITHUB_ENV" - - - name: Build and push backend image - uses: docker/build-push-action@v6 - with: - context: . - file: backend-api/Dockerfile - push: true - tags: ${{ env.BACKEND_IMAGE }} - cache-from: type=gha,scope=backend - cache-to: type=gha,mode=max,scope=backend - - - name: Build and push worker image - uses: docker/build-push-action@v6 - with: - context: ./engine - file: engine/Dockerfile - push: true - tags: ${{ env.WORKER_IMAGE }} - cache-from: type=gha,scope=worker - cache-to: type=gha,mode=max,scope=worker - - - name: Set lowercase PowerShell image name - if: needs.gate.outputs.m365 == 'true' - run: | - echo "POWERSHELL_IMAGE=ghcr.io/${GITHUB_REPOSITORY,,}/powershell:pr-${{ needs.gate.outputs.pr-number }}" >> "$GITHUB_ENV" - - - name: Build and push PowerShell service image - if: needs.gate.outputs.m365 == 'true' - uses: docker/build-push-action@v6 - with: - context: ./engine/powershell - file: engine/powershell/Dockerfile - platforms: linux/amd64 - push: true - tags: ${{ env.POWERSHELL_IMAGE }} - cache-from: type=gha,scope=powershell - cache-to: type=gha,mode=max,scope=powershell - - # ───────────────────────────────────────────────────────────────────────────── - # Job 2 — Run the full stack on the Actions runner and expose via Cloudflare - # Quick Tunnels (trycloudflare.com, no account, no token required). - # - # Architecture: - # 1. Both CF tunnels start immediately (they serve 502 until origin is ready) - # 2. Tunnel URLs are captured so the backend and frontend are configured once - # with the correct public URLs, no container restarts needed - # 3. The job sleeps (keeping everything alive) until cancelled by teardown - # or the 6-hour GitHub Actions job timeout is reached - # ───────────────────────────────────────────────────────────────────────────── - run-preview: - runs-on: ubuntu-latest - needs: [gate, build-images] - timeout-minutes: 360 - - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Log in to GHCR - uses: docker/login-action@v3 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Set lowercase image names - run: | - echo "BACKEND_IMAGE=ghcr.io/${GITHUB_REPOSITORY,,}/backend:pr-${{ needs.gate.outputs.pr-number }}" >> "$GITHUB_ENV" - echo "WORKER_IMAGE=ghcr.io/${GITHUB_REPOSITORY,,}/worker:pr-${{ needs.gate.outputs.pr-number }}" >> "$GITHUB_ENV" - echo "PREVIEW_ENC_KEY=${{ secrets.PREVIEW_ENCRYPTION_KEY }}" >> "$GITHUB_ENV" - echo "PREVIEW_SECRET_KEY=$(openssl rand -hex 32)" >> "$GITHUB_ENV" - - - name: Set lowercase PowerShell image name - if: needs.gate.outputs.m365 == 'true' - run: | - echo "POWERSHELL_IMAGE=ghcr.io/${GITHUB_REPOSITORY,,}/powershell:pr-${{ needs.gate.outputs.pr-number }}" >> "$GITHUB_ENV" - - - name: Pull pre-built images from GHCR - run: | - docker pull "$BACKEND_IMAGE" - docker pull "$WORKER_IMAGE" - if [ "${{ needs.gate.outputs.m365 }}" = "true" ]; then - docker pull "$POWERSHELL_IMAGE" - fi - - - name: Install cloudflared - run: | - curl -fsSL \ - https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb \ - -o /tmp/cloudflared.deb - sudo dpkg -i /tmp/cloudflared.deb - - - name: Start Cloudflare Quick Tunnels and capture URLs - id: tunnels - run: | - # Start both tunnels immediately — CF generates URLs before the origin is up, - # so we can configure the backend and frontend correctly from the first start. - cloudflared tunnel --url http://localhost:8000 \ - --logfile /tmp/cf-backend.log \ - --no-autoupdate 2>/dev/null & - - cloudflared tunnel --url http://localhost:3000 \ - --logfile /tmp/cf-frontend.log \ - --no-autoupdate 2>/dev/null & - - BACKEND_URL="" - FRONTEND_URL="" - for i in $(seq 1 30); do - sleep 2 - if [ -z "$BACKEND_URL" ]; then - BACKEND_URL=$(grep -o 'https://[a-z0-9-]*\.trycloudflare\.com' /tmp/cf-backend.log 2>/dev/null | head -1 || true) - fi - if [ -z "$FRONTEND_URL" ]; then - FRONTEND_URL=$(grep -o 'https://[a-z0-9-]*\.trycloudflare\.com' /tmp/cf-frontend.log 2>/dev/null | head -1 || true) - fi - if [ -n "$BACKEND_URL" ] && [ -n "$FRONTEND_URL" ]; then - break - fi - done - - if [ -z "$BACKEND_URL" ]; then - echo "ERROR: Could not get backend tunnel URL" - cat /tmp/cf-backend.log - exit 1 - fi - if [ -z "$FRONTEND_URL" ]; then - echo "ERROR: Could not get frontend tunnel URL" - cat /tmp/cf-frontend.log - exit 1 - fi - - echo "Backend tunnel: $BACKEND_URL" - echo "Frontend tunnel: $FRONTEND_URL" - echo "backend-url=$BACKEND_URL" >> "$GITHUB_OUTPUT" - echo "frontend-url=$FRONTEND_URL" >> "$GITHUB_OUTPUT" - - - name: Start infrastructure services - run: COMPOSE_PROJECT_NAME=autoaudit docker compose up -d db redis opa - - - name: Wait for infrastructure healthchecks - run: | - echo "Waiting for PostgreSQL..." - timeout 60 bash -c 'until docker exec autoaudit-db pg_isready -U autoaudit; do sleep 2; done' - - echo "Waiting for Redis..." - timeout 30 bash -c 'until docker exec autoaudit-redis redis-cli ping | grep -q PONG; do sleep 2; done' - - echo "Waiting for OPA..." - timeout 30 bash -c 'until curl -sf http://localhost:8181/health > /dev/null; do sleep 2; done' - - - name: Start PowerShell service - if: needs.gate.outputs.m365 == 'true' - run: | - docker run -d \ - --name autoaudit-powershell-service \ - --network autoaudit_default \ - -p 8001:8001 \ - "$POWERSHELL_IMAGE" - - - name: Wait for PowerShell service health - if: needs.gate.outputs.m365 == 'true' - run: timeout 120 bash -c 'until curl -sf http://localhost:8001/health > /dev/null; do sleep 3; done' - - - name: Start backend container - run: | - docker run -d \ - --name autoaudit-backend-api \ - --network autoaudit_default \ - -p 8000:8000 \ - -e APP_ENV=preview \ - -e DATABASE_URL=postgresql+asyncpg://autoaudit:autoaudit_dev_password@db:5432/autoaudit \ - -e SECRET_KEY="$PREVIEW_SECRET_KEY" \ - -e ENCRYPTION_KEY="$PREVIEW_ENC_KEY" \ - -e REDIS_URL=redis://redis:6379 \ - -e OPA_URL=http://opa:8181 \ - -e BACKEND_PUBLIC_URL="${{ steps.tunnels.outputs.backend-url }}" \ - -e FRONTEND_URL="${{ steps.tunnels.outputs.frontend-url }}" \ - -v "${{ github.workspace }}/engine/policies:/app/policies:ro" \ - "$BACKEND_IMAGE" - - - name: Wait for backend health (includes Alembic migrations) - run: | - echo "Waiting for backend API to be ready..." - timeout 120 bash -c ' - until curl -sf http://localhost:8000/health > /dev/null 2>&1 || \ - curl -sf http://localhost:8000/ > /dev/null 2>&1; do - sleep 3 - done - ' - echo "Backend is ready." - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: 20 - cache: npm - cache-dependency-path: frontend/package-lock.json - - - name: Build frontend - working-directory: frontend - run: | - npm ci - VITE_API_URL="${{ steps.tunnels.outputs.backend-url }}" npm run build - - - name: Serve frontend static files - working-directory: frontend - run: | - npx serve -s dist -l 3000 & - sleep 3 - - - name: Start worker container - run: | - PS_URL="" - if [ "${{ needs.gate.outputs.m365 }}" = "true" ]; then - PS_URL="-e POWERSHELL_SERVICE_URL=http://autoaudit-powershell-service:8001" - fi - docker run -d \ - --name autoaudit-worker \ - --network autoaudit_default \ - -e DATABASE_URL=postgresql+asyncpg://autoaudit:autoaudit_dev_password@db:5432/autoaudit \ - -e REDIS_URL=redis://redis:6379 \ - -e OPA_URL=http://opa:8181 \ - -e ENCRYPTION_KEY="$PREVIEW_ENC_KEY" \ - $PS_URL \ - -v "${{ github.workspace }}/engine:/app/engine:ro" \ - -v "${{ github.workspace }}/engine/policies:/app/policies:ro" \ - "$WORKER_IMAGE" - - - name: Build preview comment body - id: build - uses: actions/github-script@v7 - with: - script: | - const prNumber = parseInt('${{ needs.gate.outputs.pr-number }}'); - const backendUrl = '${{ steps.tunnels.outputs.backend-url }}'; - const frontendUrl = '${{ steps.tunnels.outputs.frontend-url }}'; - const runId = '${{ github.run_id }}'; - const sha = '${{ github.sha }}'.slice(0, 7); - - const m365 = '${{ needs.gate.outputs.m365 }}' === 'true'; - const rows = [ - `| Frontend | ${frontendUrl} |`, - `| Backend | ${backendUrl} |`, - ]; - if (m365) rows.push('| PowerShell | running (M365 enabled) |'); - - const body = [ - '', - ``, - '## Preview Environment', - '', - '| | URL |', - '|---|---|', - ...rows, - '', - `> Running on GitHub Actions · expires in up to 6 hours · SHA: ${sha}`, - `> Add \`teardown-preview\` label to stop early · [Workflow run](${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${runId})` - ].join('\n'); - - core.setOutput('body', body); - - - uses: ./.github/actions/pr-status-comment - with: - marker: '' - body: ${{ steps.build.outputs.body }} - issue-number: ${{ needs.gate.outputs.pr-number }} - - - name: Keep-alive (preview stays up until cancelled or 6h timeout) - run: | - echo "Preview is live." - echo " Frontend: ${{ steps.tunnels.outputs.frontend-url }}" - echo " Backend: ${{ steps.tunnels.outputs.backend-url }}" - echo "Sleeping until cancelled by teardown workflow or 6-hour timeout..." - for i in $(seq 1 360); do - sleep 60 - done - echo "6-hour timeout reached. Preview shutting down." - - - name: Mark PR comment as expired - if: always() - uses: actions/github-script@v7 - with: - script: | - const prNumber = parseInt('${{ needs.gate.outputs.pr-number }}'); - const runId = '${{ github.run_id }}'; - const comments = await github.rest.issues.listComments({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: prNumber, - }); - const existing = comments.data.find(c => - c.user.login === 'github-actions[bot]' && - c.body.includes('') - ); - if (!existing) return; - await github.rest.issues.updateComment({ - owner: context.repo.owner, - repo: context.repo.repo, - comment_id: existing.id, - body: [ - '', - ``, - '## Preview Environment', - '', - '> **Preview has expired.** The tunnel URLs above no longer resolve.', - '> Add `deploy-preview` to spin up a fresh environment.', - '', - `> [Workflow run](${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${runId})` - ].join('\n'), - }); diff --git a/.github/workflows/pr.preview-instructions.yml b/.github/workflows/pr.preview-instructions.yml deleted file mode 100644 index 70172862d..000000000 --- a/.github/workflows/pr.preview-instructions.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: Preview Instructions - -on: - pull_request: - types: [opened, reopened] - -permissions: - pull-requests: write - -jobs: - post-instructions: - runs-on: ubuntu-latest - steps: - - name: Post preview environment instructions - uses: peter-evans/create-or-update-comment@v4 - with: - issue-number: ${{ github.event.number }} - body: | - - ## Preview Environment - - A preview environment can be spun up on demand for this PR. - - | Action | Label | Includes | - |---|---|---| - | **Spin up preview** | `deploy-preview` | Frontend, backend, database, Redis, OPA, worker | - | **Spin up preview with M365** | `deploy-preview-m365` | Everything above + PowerShell service for Exchange/Teams scan testing | - | **Tear down preview** | `teardown-preview` | Stops the environment early | - - > The environment will also be torn down automatically when the PR is closed or merged. - > Preview URLs will appear in a follow-up comment once the deploy completes (~5–8 min). - > M365 scans require real tenant credentials added through the frontend UI. diff --git a/.github/workflows/pr.preview-teardown.yml b/.github/workflows/pr.preview-teardown.yml deleted file mode 100644 index 18449a2de..000000000 --- a/.github/workflows/pr.preview-teardown.yml +++ /dev/null @@ -1,118 +0,0 @@ -name: Preview Teardown - -on: - pull_request: - types: [closed, labeled] - workflow_dispatch: - inputs: - pr_number: - description: "PR number to tear down (for manual testing)" - required: true - default: "1" - -permissions: - contents: read - pull-requests: write - issues: write - actions: write - -jobs: - teardown: - runs-on: ubuntu-latest - if: >- - github.event_name == 'workflow_dispatch' || - (github.event_name == 'pull_request' && github.event.action == 'closed') || - (github.event_name == 'pull_request' && github.event.action == 'labeled' && - github.event.label.name == 'teardown-preview') - - steps: - - name: Resolve PR number - id: pr - run: | - if [ "${{ github.event_name }}" = "pull_request" ]; then - echo "number=${{ github.event.number }}" >> "$GITHUB_OUTPUT" - else - echo "number=${{ inputs.pr_number }}" >> "$GITHUB_OUTPUT" - fi - - - name: Remove teardown-preview label - if: github.event_name == 'pull_request' && github.event.action == 'labeled' - uses: actions/github-script@v7 - with: - script: | - await github.rest.issues.removeLabel({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: context.payload.pull_request.number, - name: 'teardown-preview' - }); - - # Known risk: listComments only returns the first page so teardown may miss the preview comment on PRs with >30 comments. - - name: Find preview comment and extract run ID - id: find-run - uses: actions/github-script@v7 - with: - script: | - const prNumber = parseInt('${{ steps.pr.outputs.number }}'); - const comments = await github.rest.issues.listComments({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: prNumber, - }); - - const preview = comments.data.find(c => - c.user.login === 'github-actions[bot]' && - c.body.includes('') - ); - - if (!preview) { - core.setOutput('run-id', ''); - core.setOutput('comment-id', ''); - console.log('No preview comment found for PR #' + prNumber); - return; - } - - const match = preview.body.match(//); - const runId = match ? match[1] : ''; - core.setOutput('run-id', runId); - core.setOutput('comment-id', String(preview.id)); - console.log('Found run ID: ' + runId + ', comment ID: ' + preview.id); - - - name: Cancel preview workflow run - if: steps.find-run.outputs.run-id != '' - run: | - RUN_ID="${{ steps.find-run.outputs.run-id }}" - echo "Cancelling workflow run $RUN_ID..." - HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" \ - -X POST \ - -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ - -H "Accept: application/vnd.github+json" \ - -H "X-GitHub-Api-Version: 2022-11-28" \ - "https://api.github.com/repos/${{ github.repository }}/actions/runs/${RUN_ID}/cancel") - echo "Cancel API response status: $HTTP_STATUS" - # 202 = accepted, 409 = already completed — both are fine - if [ "$HTTP_STATUS" = "202" ] || [ "$HTTP_STATUS" = "409" ]; then - echo "Run cancelled successfully (or was already completed)." - else - echo "WARNING: Unexpected status $HTTP_STATUS — run may not have been cancelled." - fi - - - name: Update PR comment — teardown complete - if: steps.find-run.outputs.comment-id != '' - uses: actions/github-script@v7 - with: - script: | - await github.rest.issues.updateComment({ - owner: context.repo.owner, - repo: context.repo.repo, - comment_id: parseInt('${{ steps.find-run.outputs.comment-id }}'), - body: [ - '', - '', - '## Preview Environment', - '', - 'Preview environment for this PR has been **torn down**.', - '', - `> [Workflow run](${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${{ github.run_id }})` - ].join('\n'), - }); diff --git a/README.md b/README.md index b8332b298..ab4a617de 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # AutoAudit Monorepo - Main/Deployment Branch ## Project Overview -AutoAudit is a M365 compliance automation platform built by several specialist teams. This monorepo centralizes all codebases—including backend services, APIs, compliance scanners, and frontends—enabling unified CI/CD, streamlined development, and rapid automated deployments to the cloud. +AutoAudit is a M365 compliance automation platform built by several specialist teams. This monorepo centralizes all codebases—including backend services, APIs, compliance scanners, and frontends—so one set of CI gates covers the whole system. It does **not** deploy: there is no deployment pipeline, no target environment and no registry push. ## Documentation @@ -35,9 +35,12 @@ Full commit history and traceability from team forks are preserved. once complete, a GCP Cloud Build trigger will automatically build and deploy the `main` branch code and push images into the GCP Artifact Registry. ## Docker Builds -- Production Docker images from the `main` branch are tagged appropriately and pushed to: - - [Docker Hub - AutoAudit Services](https://hub.docker.com/u/autoauditservices) - - GCP Artifact Registry (once integration is complete) +- **Nothing in this repository pushes to a registry.** The three pull-request preview + workflows that pushed mutable `pr-` tags to GHCR have been removed; the deploy + job among them could never finish, because `docker-compose.yml` has required + `POSTGRES_PASSWORD` since `f7981302` and the workflow set it nowhere. The only other + image build, in `ci.grype.yml`, is commented out; that file records it was replaced by a + directory scan because Docker Hub is no longer configured. - Individual service repos like Engine, Backend-API, Frontend, and Security have mirrored deployment artifacts. ## Contribution Guidelines @@ -47,5 +50,7 @@ Full commit history and traceability from team forks are preserved. ## Contact & Support For production deployment queries: -- Contact the DevOps lead managing GCP integration. -- Report critical issues with `main` branch deployments on GitHub with relevant tags. +- Open a GitHub issue. There is no GCP integration to route these to: the only workflow + that still references GCP is `ops.collector.yml`, which is hard-disabled (`if: false`) + because it used a long-lived service-account key. +- Report critical issues with the `main` branch on GitHub with relevant tags. From 97b3f8798e8cb3bc9510141f7778797e67766793 Mon Sep 17 00:00:00 2001 From: sh4mbhavi Date: Sun, 20 Sep 2026 18:44:47 +1000 Subject: [PATCH 2/2] ci: drop stale references to the deleted preview-deploy workflow `.github/actionlint.yaml` carried a per-file ignore block for `pr.preview-deploy.yml`, and `.secrets.baseline` allowlisted the Basic Auth Credentials finding at its line 267. Both were added on `main` after this branch was cut, and both point at a file this branch deletes. The baseline entry in particular allowlists the very credential this change removes, so it must not survive the deletion. `git grep -n "pr\.preview"` is empty again after this. --- .github/actionlint.yaml | 9 --------- .secrets.baseline | 10 ---------- 2 files changed, 19 deletions(-) diff --git a/.github/actionlint.yaml b/.github/actionlint.yaml index deb8b9c4b..fb66ade8f 100644 --- a/.github/actionlint.yaml +++ b/.github/actionlint.yaml @@ -10,12 +10,3 @@ paths: # do not remove this ignore rule to "fix" the lint without also # removing the reasons the guard exists. - 'constant expression "false" in condition. remove the if: section' - .github/workflows/pr.preview-deploy.yml: - ignore: - # Pre-existing shellcheck findings in a file this PR does not touch. - # actionlint scans every workflow file regardless of what changed, so - # these surface here for the first time. Leaving as a follow-up rather - # than fixing unrelated scripts in an unrelated PR. - - 'SC2129:' - - 'SC2034:' - - 'SC2086:' diff --git a/.secrets.baseline b/.secrets.baseline index 2112d8297..3248e5e34 100644 --- a/.secrets.baseline +++ b/.secrets.baseline @@ -137,16 +137,6 @@ } ], "results": { - ".github/workflows/pr.preview-deploy.yml": [ - { - "type": "Basic Auth Credentials", - "filename": ".github/workflows/pr.preview-deploy.yml", - "hashed_secret": "ab85230e9a00f82361b0655ffbbf32946347c212", - "is_verified": false, - "line_number": 267, - "is_secret": false - } - ], "backend-api/app/db/seed_dev.py": [ { "type": "Base64 High Entropy String",