From 762a97108105745d5f1c68a6af26a56743452711 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 27 Mar 2026 14:23:09 +0000 Subject: [PATCH 1/2] Initial plan From 67f5f0b18eebdfa26ed77f25c6b16cc871b63d5b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 27 Mar 2026 14:27:06 +0000 Subject: [PATCH 2/2] Fix Update Preprod K8s Manifest CI failure by validating PAT repo access - Enhance pat-check step to verify PAT has read access to k8s-cluster-state via GitHub API probe before attempting checkout - Use --oauth2-bearer to avoid PAT appearing in process listings - Extract k8s repo path to workflow-level K8S_STATE_REPO env var Agent-Logs-Url: https://github.com/christianlouis/InboxConverge/sessions/e5e9c2ee-5f82-4cf5-84a3-b968518699c8 Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com> --- .github/workflows/ci.yml | 15 ++++++++++++--- CHANGELOG.md | 1 + 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1f6a413..fb4eb1e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,6 +14,7 @@ on: env: GHCR_REGISTRY: ghcr.io PRIVATE_REGISTRY: registry.cklnet.com + K8S_STATE_REPO: christianlouis/k8s-cluster-state jobs: # ── Phase 1: Lint ────────────────────────────────────────────────────── @@ -243,7 +244,7 @@ jobs: echo "frontend_image=ghcr.io/${{ github.repository_owner }}/inboxconverge/frontend:sha-${SHORT_SHA}" >> "$GITHUB_OUTPUT" echo "short_sha=${SHORT_SHA}" >> "$GITHUB_OUTPUT" - - name: Check if GH_PAT is configured + - name: Check if GH_PAT is configured and has repo access id: pat-check env: GH_PAT: ${{ secrets.GH_PAT }} @@ -252,14 +253,22 @@ jobs: echo "::warning::GH_PAT secret is not configured. Skipping k8s manifest update." echo "available=false" >> "$GITHUB_OUTPUT" else - echo "available=true" >> "$GITHUB_OUTPUT" + HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" \ + --oauth2-bearer "$GH_PAT" \ + "https://api.github.com/repos/${{ env.K8S_STATE_REPO }}") + if [ "$HTTP_CODE" = "200" ]; then + echo "available=true" >> "$GITHUB_OUTPUT" + else + echo "::warning::GH_PAT does not have access to ${{ env.K8S_STATE_REPO }} (HTTP $HTTP_CODE). Skipping k8s manifest update." + echo "available=false" >> "$GITHUB_OUTPUT" + fi fi - name: Checkout k8s-cluster-state if: steps.pat-check.outputs.available == 'true' uses: actions/checkout@v4 with: - repository: christianlouis/k8s-cluster-state + repository: ${{ env.K8S_STATE_REPO }} token: ${{ secrets.GH_PAT }} path: k8s-cluster-state ref: main diff --git a/CHANGELOG.md b/CHANGELOG.md index 016905c..20e7dd5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Fixed +- **CI `update-k8s-manifest` job**: Enhanced the PAT validation step to verify the token actually has read access to the `k8s-cluster-state` repository (via a GitHub API probe) before attempting checkout, preventing a 403 "Write access to repository not granted" failure when the PAT exists but lacks the necessary repository access. - **CI `update-k8s-manifest` job**: Added a `Check if GH_PAT is configured` step that emits a warning and skips the GitOps steps when the `GH_PAT` secret is absent or empty, preventing a 403 "Write access to repository not granted" failure that blocked the pipeline when the secret was not set. - **CI `update-k8s-manifest` job**: Fixed checkout of `k8s-cluster-state` repo by adding `ref: main` to the `actions/checkout` step, preventing a "Not Found" 404 error caused by the action's API call to determine the default branch. Also corrected the image tag format from `main-` to `sha-` to match the tags actually generated by `docker/metadata-action@v5` with `type=sha`. - **`ProgrammingError` on `notification_configs`**: Added Alembic migration `0001` that runs `ALTER TABLE notification_configs ADD COLUMN IF NOT EXISTS` for the `name` and `apprise_url` columns introduced by the Apprise PR. SQLAlchemy's `create_all` does not ALTER existing tables, so existing deployments were missing these columns and crashing at runtime. The migration is idempotent (`IF NOT EXISTS`) so it is safe for fresh installs too. `app/main.py` lifespan now runs `alembic upgrade head` after `create_all`.