Skip to content

Stripe Database Monitor #217

Stripe Database Monitor

Stripe Database Monitor #217

Workflow file for this run

name: Stripe Database Monitor
on:
push:
branches: [fix-e2e, webhook-e2e]
schedule:
- cron: '0 * * * *' # Every hour
workflow_dispatch:
permissions:
contents: read
# Each matrix leg gets its own concurrency slot so runs don't cancel each other.
concurrency:
group: e2e-monitor-${{ github.ref }}-${{ github.event_name }}
cancel-in-progress: false
jobs:
monitor:
name: E2E — ${{ matrix.env }}
runs-on: ubuntu-24.04-arm
timeout-minutes: 75
strategy:
fail-fast: false
matrix:
include:
- env: prod
api_key: STRIPE_SK_GOLDILOCKS_PROD
api_base: https://api.stripe.com
- env: qa
api_key: STRIPE_SK_GOLDILOCKS_QA
api_base: https://qa-api.stripe.com
env:
STRIPE_API_KEY: ${{ secrets[matrix.api_key] }}
steps:
- name: Checkout repository
uses: actions/checkout@v5
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: '24'
- name: Setup Bun
uses: oven-sh/setup-bun@v2
- name: Install Stripe CLI
run: |
curl -s https://packages.stripe.dev/api/security/keypair/stripe-cli-gpg/public | gpg --dearmor -o /usr/share/keyrings/stripe.gpg
echo "deb [signed-by=/usr/share/keyrings/stripe.gpg] https://packages.stripe.dev/stripe-cli-debian-local stable main" \
| sudo tee /etc/apt/sources.list.d/stripe.list
sudo apt-get update -qq && sudo apt-get install -y -qq stripe
- name: Validate API key
run: |
if [ -z "$STRIPE_API_KEY" ]; then
echo "::error::STRIPE_API_KEY is empty — check that the ${{ matrix.api_key }} secret is set"
exit 1
fi
if ! stripe customers list --limit 1 --api-base ${{ matrix.api_base }} >/dev/null 2>&1; then
echo "::error::STRIPE_API_KEY (${{ matrix.api_key }}) is invalid or expired — rotate it in the Stripe Dashboard and update the GitHub secret"
exit 1
fi
- name: Create Stripe database
id: create-db
run: |
echo "Creating Stripe database..."
RESULT=$(stripe databases create --live --api-base ${{ matrix.api_base }})
DB_ID=$(echo "$RESULT" | grep -oE 'db_[A-Za-z0-9]+' | head -1)
DB_STRING=$(echo "$RESULT" | grep -oE 'postgresql://[^[:space:]]+')
if [ -z "$DB_ID" ]; then
echo "::error::Could not extract database ID from output (connection string redacted)"
exit 1
fi
if [ -z "$DB_STRING" ]; then
echo "::error::Could not extract connection string from output"
exit 1
fi
# Mask the full connection string and its password component before any further output.
echo "::add-mask::$DB_STRING"
DB_PASSWORD=$(printf '%s' "$DB_STRING" | sed -nE 's#^postgresql://[^:]+:([^@]+)@.*$#\1#p')
if [ -n "$DB_PASSWORD" ]; then
echo "::add-mask::$DB_PASSWORD"
fi
echo "db_id=$DB_ID" >> "$GITHUB_OUTPUT"
echo "db_string=$DB_STRING" >> "$GITHUB_OUTPUT"
echo "Database $DB_ID created successfully"
- name: Install psql
run: sudo apt-get install -y -qq postgresql-client
- name: Verify backfill
if: always() && steps.create-db.outputs.db_id != ''
env:
DB_STRING: ${{ steps.create-db.outputs.db_string }}
DB_ID: ${{ steps.create-db.outputs.db_id }}
STRIPE_API_BASE: ${{ matrix.api_base }}
run: bash scripts/verify-backfill.sh
- name: Verify live sync
if: always() && steps.create-db.outputs.db_id != ''
env:
DB_STRING: ${{ steps.create-db.outputs.db_string }}
DB_ID: ${{ steps.create-db.outputs.db_id }}
STRIPE_API_BASE: ${{ matrix.api_base }}
run: bash scripts/verify-live-sync.sh
# TODO: Make Sigma validation a hard failure once selective sync is available
# and the DB consistently reaches ready state.
- name: Sigma validation
env:
DATABASE_URL: ${{ steps.create-db.outputs.db_string }}
run: |
set +e
bun scripts/reconcile-sigma-vs-postgres.ts
STATUS=$?
if [ "$STATUS" -ne 0 ]; then
echo "::warning title=Sigma reconciliation::Postgres is missing rows that exist in Sigma. See the job log for the per-table diff and the list of missing IDs with their created timestamps."
fi
- name: Delete Stripe database
if: always() && steps.create-db.outputs.db_id
run: |
echo "Deleting database ${{ steps.create-db.outputs.db_id }}..."
stripe databases delete ${{ steps.create-db.outputs.db_id }} --yes --api-base ${{ matrix.api_base }}