Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -666,12 +666,12 @@ jobs:
- name: posthog:sync --plan
if: steps.affected.outputs.is_affected == 'yes'
env:
POSTHOG_PERSONAL_API_KEY: ${{ secrets.POSTHOG_PERSONAL_API_KEY }}
POSTHOG_PERSONAL_API_KEY: ${{ secrets.POSTHOG_PERSONAL_API_KEY_READONLY }}
POSTHOG_HOST: https://us.i.posthog.com
POSTHOG_PROJECT_ID: ${{ secrets.POSTHOG_PROJECT_ID }}
run: |
if [ -z "$POSTHOG_PERSONAL_API_KEY" ]; then
echo "::notice::POSTHOG_PERSONAL_API_KEY not set — soft skip for contributor PRs."
echo "::notice::POSTHOG_PERSONAL_API_KEY_READONLY not set — soft skip for contributor PRs."
exit 0
fi
npx nx run posthog-tools:sync:plan
4 changes: 2 additions & 2 deletions .github/workflows/posthog-quality.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,15 @@ jobs:
- run: npm ci
- name: Run live telemetry quality check
env:
POSTHOG_PERSONAL_API_KEY: ${{ secrets.POSTHOG_PERSONAL_API_KEY }}
POSTHOG_PERSONAL_API_KEY: ${{ secrets.POSTHOG_PERSONAL_API_KEY_READONLY }}
POSTHOG_HOST: https://us.i.posthog.com
POSTHOG_PROJECT_ID: ${{ secrets.POSTHOG_PROJECT_ID }}
QUALITY_DAYS: ${{ github.event.inputs.days || '7' }}
QUALITY_LIMIT_PER_EVENT: ${{ github.event.inputs.limit_per_event || '100' }}
run: |
set -euo pipefail
if [ -z "${POSTHOG_PERSONAL_API_KEY:-}" ] || [ -z "${POSTHOG_PROJECT_ID:-}" ]; then
echo "::error::POSTHOG_PERSONAL_API_KEY and POSTHOG_PROJECT_ID Actions secrets are required."
echo "::error::POSTHOG_PERSONAL_API_KEY_READONLY and POSTHOG_PROJECT_ID Actions secrets are required."
exit 1
fi
npx nx run posthog-tools:quality:live -- --days "$QUALITY_DAYS" --limit-per-event "$QUALITY_LIMIT_PER_EVENT" --require-critical-coverage
30 changes: 29 additions & 1 deletion scripts/ci-workflow.spec.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,15 @@ describe('CI workflow', () => {
);
}

async function readPostHogSyncPlanJob() {
const workflow = await readWorkflow();
return workflow.slice(workflow.indexOf(' posthog-sync-plan:'));
}

async function readPostHogQualityWorkflow() {
return readFile('.github/workflows/posthog-quality.yml', 'utf8');
}

it('treats nested library files as deploy-relevant changes', async () => {
const deployJob = await readDeployJob();

Expand Down Expand Up @@ -58,8 +67,27 @@ describe('CI workflow', () => {

assert.ok(
productionSmokeJob.indexOf('Verify shared LangGraph backend') <
productionSmokeJob.indexOf('npx playwright install --with-deps chromium')
productionSmokeJob.indexOf(
'npx playwright install --with-deps chromium'
)
);
});

it('uses the read-only PostHog key for CI drift checks', async () => {
const postHogSyncPlanJob = await readPostHogSyncPlanJob();

assert.match(
postHogSyncPlanJob,
/POSTHOG_PERSONAL_API_KEY:\s*\$\{\{\s*secrets\.POSTHOG_PERSONAL_API_KEY_READONLY\s*\}\}/
);
});

it('uses the read-only PostHog key for scheduled live quality checks', async () => {
const postHogQualityWorkflow = await readPostHogQualityWorkflow();

assert.match(
postHogQualityWorkflow,
/POSTHOG_PERSONAL_API_KEY:\s*\$\{\{\s*secrets\.POSTHOG_PERSONAL_API_KEY_READONLY\s*\}\}/
);
});
});
15 changes: 8 additions & 7 deletions tools/posthog/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,14 @@ Requires a **Personal API Key** with `dashboard:write`, `insight:write`, `cohort

Env vars (see `.env.example` at repo root):

| Variable | Purpose |
| -------------------------- | --------------------------------------------------- |
| `POSTHOG_PERSONAL_API_KEY` | Personal API Key (Bearer) |
| `POSTHOG_HOST` | `https://us.i.posthog.com` (default) or your region |
| `POSTHOG_PROJECT_ID` | Numeric project id (visible in PostHog URL) |

**CI** uses the same key (write-scoped) for `--plan` only. **Production hardening TODO:** create a read-only Personal API Key for CI and add it as `POSTHOG_PERSONAL_API_KEY_READONLY` in GitHub Actions secrets. Local development continues using the write-scoped key for `--apply` and `--report`.
| Variable | Purpose |
| ----------------------------------- | ------------------------------------------------------------------ |
| `POSTHOG_PERSONAL_API_KEY` | Write-scoped Personal API Key for local `--apply` and `--report` |
| `POSTHOG_PERSONAL_API_KEY_READONLY` | Read-only Personal API Key for CI `--plan` and live quality checks |
| `POSTHOG_HOST` | `https://us.i.posthog.com` (default) or your region |
| `POSTHOG_PROJECT_ID` | Numeric project id (visible in PostHog URL) |

**CI** maps `POSTHOG_PERSONAL_API_KEY_READONLY` into the tool's `POSTHOG_PERSONAL_API_KEY` environment variable for read-only `--plan` and live quality checks. Local development continues using the write-scoped `POSTHOG_PERSONAL_API_KEY` for `--apply` and `--report`.

## JSON contract

Expand Down
Loading