Skip to content

CI-local Postgres smoke for PR preview burn-in#481

Merged
isuttell merged 2 commits into
mainfrom
codex/ap-303-ci-local-postgres-smoke
Jun 11, 2026
Merged

CI-local Postgres smoke for PR preview burn-in#481
isuttell merged 2 commits into
mainfrom
codex/ap-303-ci-local-postgres-smoke

Conversation

@isuttell

@isuttell isuttell commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Summary

Add a CI-local Postgres/RLS smoke path so default PR CI can exercise the database-backed local harness without provisioning Neon branches, Hyperdrive configs, or deployed PR-preview Workers.

Changes

  • Add pnpm smoke:ci:postgres, which runs migrations against a Postgres owner URL and drives smoke-local-mvp.mjs through app_role.
  • Teach the local MVP harness and jobs bridge to run against either in-memory services or a Postgres binding.
  • Add a separate non-required Postgres smoke CI job using a job-local postgres:16-alpine service.
  • Make hosted PR preview opt-in via the full-pr-preview label.
  • Update local-dev, hosted-ops, workflow config, and script docs to describe the burn-in status and default no-hosted-preview path.

Risk: HIGH

  • Areas touched: CI, PR preview workflow, local MVP harness, jobs bridge, Postgres/RLS smoke path, ops docs.
  • Security: no production secrets or production resources touched; CI runtime role password is job-local and exercises app_role/RLS.
  • Performance: adds a non-required CI job with build + smoke runtime; intended to reduce default PR pressure on Neon/Hyperdrive.
  • Breaking: hosted PR preview no longer runs automatically for every same-repo PR; add full-pr-preview when deployed Worker evidence is needed.

Test plan

  • pnpm verify
  • pnpm test:coverage
  • DATABASE_URL=postgres://agent_paste:agent_paste@127.0.0.1:55432/agent_paste DATABASE_RUNTIME_ROLE_PASSWORD=agent-paste-ci-app-role pnpm smoke:ci:postgres against disposable postgres:16-alpine
  • Pre-commit hooks: gitleaks, biome, prettier-docs, typecheck
  • Pre-push hooks: test-coverage, verify

Review: local ziw-code-review clean after docs correction; CodeRabbit auto-review enabled, no manual trigger.

Issue: AP-303

Summary by CodeRabbit

  • New Features

    • CI now runs a job-local Postgres smoke test and adds a convenience script to execute it.
    • PR preview deployments are opt-in via the full-pr-preview label; previews and cleanup respond to label add/remove events.
  • Documentation

    • Updated developer and ops guides to document the Postgres smoke workflow, local Postgres/dev setup, and preview labeling/teardown semantics.

@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

CI now includes a Postgres smoke job that provisions a local PostgreSQL service, runs migrations as the database owner, and executes local smoke tests via the app_role with RLS. The local MVP server supports backend selection between memory and Postgres modes. PR preview deployments require the full-pr-preview label.

Changes

Postgres Smoke Testing with Label-Gated Preview Deployments

Layer / File(s) Summary
PR Preview Deployment Label Gating
.github/workflows/pr-preview.yml, .github/workflows/pr-preview-cleanup.yml
Workflow triggers now include labeled/unlabeled; deploy/cleanup jobs require presence/removal of the full-pr-preview label plus same-repo checks.
CI Postgres Smoke Job
.github/workflows/ci.yml, package.json
Adds postgres-smoke job that starts postgres:16-alpine service, sets DATABASE_URL/runtime password, and runs pnpm smoke:ci:postgres. Adds smoke:ci:postgres script.
CI smoke script and runner
scripts/smoke-ci-postgres.mjs, scripts/README.md
New CI script validates/derives migration and runtime URLs, runs @agent-paste/db migrations, then invokes the local MVP smoke harness against Postgres; README documents the flow and env vars.
Local MVP backend selection
scripts/local-mvp-server.mjs
Supports AGENT_PASTE_LOCAL_DATABASE_BACKEND (memory or postgres), derives postgres binding from env, conditionally initializes createPostgresServices or createLocalServices, adjusts envs (API/upload/jobs), and skips proof-artifact seeding in Postgres mode.
Service configuration contract flexibility
scripts/local-jobs-bridge.mjs, scripts/README.md
createJobsEnv now requires exactly one of repo or db, conditionally sets LOCAL_MVP_REPOSITORY, and allows injected DB executors for job environments.
Docs and runbooks
docs/agents/workflow/config.md, docs/development.md, docs/specs/local-dev.md, docs/ops/*
Documentation updated to enumerate smoke commands (pnpm smoke:ci:postgres), describe local docker-compose Postgres setup and owner/app_role patterns, and clarify that hosted preview deploys are opt-in via full-pr-preview and cleaned up on label removal.

Sequence Diagram(s)

sequenceDiagram
  participant CI as GitHub Actions (postgres-smoke job)
  participant Script as smoke-ci-postgres.mjs
  participant Migrate as pnpm --filter `@agent-paste/db` migrate
  participant Smoke as smoke-local-mvp.mjs (local harness)
  participant DB as PostgreSQL service container

  CI->>DB: start postgres:16-alpine (healthchecks)
  CI->>Script: run pnpm smoke:ci:postgres with DATABASE_URL & runtime password
  Script->>Migrate: run migrations (owner DATABASE_URL)
  Migrate->>DB: apply committed migrations
  Script->>Smoke: invoke local smoke with runtime app_role URL
  Smoke->>DB: connect as app_role (RLS)
  DB-->>Smoke: smoke results
  Smoke-->>Script: exit status
  Script-->>CI: pass/fail
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • zaks-io/agent-paste#2: Related PR-preview lifecycle changes affecting preview gating and cleanup logic.
  • zaks-io/agent-paste#146: Related changes to PR-preview cleanup and reconciliation steps interacting with label-based cleanup.
  • zaks-io/agent-paste#62: Overlapping updates to pr-preview.yml that affect preview deploy gating and per-PR resource flows.

Poem

A rabbit hops where migrations run,
In CI fields beneath the sun.
Labels open previews wide,
Postgres roles keep smoke supplied.
Hooray — the tests all pass, my bun! 🐇✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and specifically describes the main change: adding a CI-local Postgres smoke test path for PR preview burn-in, which is the primary objective of the changeset.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/ap-303-ci-local-postgres-smoke

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
docs/agents/workflow/config.md (1)

3-3: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Update the "Last updated" date.

The date is stale (2026-06-09), but this PR was created on 2026-06-11 and includes substantive changes to this file.

📅 Proposed fix
-Last updated: 2026-06-09
+Last updated: 2026-06-11
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/agents/workflow/config.md` at line 3, Update the "Last updated" metadata
string by replacing the stale date after the literal "Last updated:" with the PR
creation date 2026-06-11 so the top-of-file header reflects the current change;
edit the line that reads "Last updated: 2026-06-09" to "Last updated:
2026-06-11".
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/ci.yml:
- Line 240: Replace the floating Postgres tag with a pinned digest: locate the
service declaration that uses "image: postgres:16-alpine" (the Postgres smoke
job/service) and change it to the corresponding image@sha256:<digest> for
postgres:16-alpine so the workflow uses a specific immutable image; obtain the
correct sha256 from Docker Hub or your trusted registry and update the image
string accordingly.
- Around line 257-260: The Checkout step using
actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 (labelled "Checkout")
currently leaves the workflow token persisted; update that checkout step to
explicitly set persist-credentials: false so the workflow token is not available
to subsequent git operations.

In @.github/workflows/pr-preview.yml:
- Line 37: Add an unlabeled teardown path so removing the "full-pr-preview"
label immediately destroys resources: update the PR preview workflow condition
(the if using contains(..., 'full-pr-preview')) to not gate teardown-only jobs,
or add a new job triggered on pull_request: types: [unlabeled] that invokes the
existing cleanup logic; ensure this job calls the same cleanup entrypoint used
by .github/workflows/pr-preview-cleanup.yml (cleanup-stale-pr-previews.mjs) and
that the script is updated to treat PRs missing the 'full-pr-preview' label as
stale when invoked for an unlabeled event.

In `@docs/agents/workflow/config.md`:
- Line 151: The phrase "needs deployed" is nonstandard; search for the exact
string "needs deployed" (e.g., the snippet "preview smoke when a PR is labeled
`full-pr-preview` or needs deployed Worker") and replace it across the three
occurrences in the docs with a formal alternative such as "needs to be deployed"
or "requires deployment" so the sentence reads clearly (e.g., "preview smoke
when a PR is labeled `full-pr-preview` or needs to be deployed Worker" → rewrite
to "preview smoke when a PR is labeled `full-pr-preview` or requires a deployed
Worker" or "…or needs to be deployed"). Ensure the replacement preserves
surrounding punctuation and markdown formatting.

In `@scripts/local-jobs-bridge.mjs`:
- Around line 87-111: The createJobsEnv function currently allows both repo and
db to be provided which leads to ambiguous behavior (jobs prefer
LOCAL_MVP_REPOSITORY over DB); modify createJobsEnv to explicitly reject
simultaneous inputs by adding a validation at the start that throws an Error
when both repo and db are present, ensuring callers must pass only one of
LOCAL_MVP_REPOSITORY (repo) or DB; update any tests or callers if needed and
reference createJobsEnv, LOCAL_MVP_REPOSITORY, DB, and createLocalMvpSqlExecutor
to locate the change.

---

Outside diff comments:
In `@docs/agents/workflow/config.md`:
- Line 3: Update the "Last updated" metadata string by replacing the stale date
after the literal "Last updated:" with the PR creation date 2026-06-11 so the
top-of-file header reflects the current change; edit the line that reads "Last
updated: 2026-06-09" to "Last updated: 2026-06-11".
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: ae6db5a7-9ef5-46fe-94d7-d1600dede033

📥 Commits

Reviewing files that changed from the base of the PR and between bdea25d and 359e293.

📒 Files selected for processing (12)
  • .github/workflows/ci.yml
  • .github/workflows/pr-preview.yml
  • docs/agents/workflow/config.md
  • docs/development.md
  • docs/ops/first-deploy.md
  • docs/ops/status/hosted-ops.md
  • docs/specs/local-dev.md
  • package.json
  • scripts/README.md
  • scripts/local-jobs-bridge.mjs
  • scripts/local-mvp-server.mjs
  • scripts/smoke-ci-postgres.mjs

Comment thread .github/workflows/ci.yml Outdated
Comment thread .github/workflows/ci.yml
Comment thread .github/workflows/pr-preview.yml
Comment thread docs/agents/workflow/config.md Outdated
Comment thread scripts/local-jobs-bridge.mjs

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.github/workflows/pr-preview-cleanup.yml (1)

24-26: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Grant issues: write or drop the PR comments.

github.rest.issues.createComment() uses the Issues API, and GitHub documents issues: write as the permission for adding issue comments. With only contents: read and pull-requests: write, the cleanup status/failure comment steps can fail and turn a successful cleanup job red. (docs.github.com)

Fix
 permissions:
   contents: read
+  issues: write
   pull-requests: write

Also applies to: 111-125

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/pr-preview-cleanup.yml around lines 24 - 26, The
workflow's permissions block currently only grants contents: read and
pull-requests: write but the job uses github.rest.issues.createComment(), which
requires issues: write; update the permissions section to add issues: write
(i.e., add "issues: write" alongside the existing keys) so the cleanup
status/failure comment steps that call github.rest.issues.createComment() can
succeed, or alternatively remove/replace those steps so they don't call the
Issues API.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In @.github/workflows/pr-preview-cleanup.yml:
- Around line 24-26: The workflow's permissions block currently only grants
contents: read and pull-requests: write but the job uses
github.rest.issues.createComment(), which requires issues: write; update the
permissions section to add issues: write (i.e., add "issues: write" alongside
the existing keys) so the cleanup status/failure comment steps that call
github.rest.issues.createComment() can succeed, or alternatively remove/replace
those steps so they don't call the Issues API.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 5fc8410b-7865-45db-8097-dcaf2756b4cf

📥 Commits

Reviewing files that changed from the base of the PR and between 359e293 and 4121716.

📒 Files selected for processing (7)
  • .github/workflows/ci.yml
  • .github/workflows/pr-preview-cleanup.yml
  • docs/agents/workflow/config.md
  • docs/ops/first-deploy.md
  • docs/ops/status/hosted-ops.md
  • scripts/README.md
  • scripts/local-jobs-bridge.mjs

@isuttell isuttell merged commit e3be243 into main Jun 11, 2026
10 checks passed
@isuttell isuttell deleted the codex/ap-303-ci-local-postgres-smoke branch June 11, 2026 18:59
@github-actions

Copy link
Copy Markdown

agent-paste PR preview resources were cleaned up. The shared Preview GitHub Environment is retained for future preview deploys.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant