diff --git a/.env.example b/.env.example index 8064091ff..73fe20a64 100644 --- a/.env.example +++ b/.env.example @@ -10,3 +10,6 @@ POSTHOG_PERSONAL_API_KEY=phx_... # POSTHOG_REGION is optional, defaults to 'us'. Can also be passed via --region flag or workflow input. # POSTHOG_REGION=us POSTHOG_WIZARD_PROJECT_ID=123 + +# used by snapshots to upload source maps to PostHog +SOURCE_MAPS_CLI_KEY=phx... \ No newline at end of file diff --git a/.github/workflows/wizard-ci.yml b/.github/workflows/wizard-ci.yml index eaec0b665..c6e45c7e5 100644 --- a/.github/workflows/wizard-ci.yml +++ b/.github/workflows/wizard-ci.yml @@ -664,6 +664,10 @@ jobs: POSTHOG_REGION: ${{ needs.discover.outputs.input_posthog_region }} POSTHOG_PERSONAL_API_KEY: ${{ secrets.GH_APP_POSTHOG_WIZARD_CI_BOT_POSTHOG_PERSONAL_KEY }} POSTHOG_WIZARD_PROJECT_ID: ${{ secrets.GH_APP_POSTHOG_WIZARD_CI_BOT_TARGET_PROJECT_ID }} + # Upload key for the source-maps e2e: a personal API key with the + # "Source map upload" preset. The host answers the agent's "api-key" + # wizard_ask with it (vaulted; the agent only sees a secretRef). + SOURCE_MAPS_CLI_KEY: ${{ secrets.GH_APP_POSTHOG_WIZARD_CI_BOT_SOURCE_MAPS_CLI_KEY }} WIZARD_PATH: ${{ env.WIZARD_PATH }} CONTEXT_MILL_PATH: ${{ env.CONTEXT_MILL_PATH }} MCP_PATH: ${{ env.MCP_PATH }} diff --git a/apps/manifest.json b/apps/manifest.json index 0dea4dd15..a2779f437 100644 --- a/apps/manifest.json +++ b/apps/manifest.json @@ -55,7 +55,7 @@ "dir": "error-tracking-upload-source-maps", "label": "Upload Source Maps", "description": "Wire up PostHog Error Tracking source-map upload", - "ciCapable": false + "ciCapable": true } ] } diff --git a/services/wizard-ci/e2e.ts b/services/wizard-ci/e2e.ts index fe06efbf8..3f1354458 100644 --- a/services/wizard-ci/e2e.ts +++ b/services/wizard-ci/e2e.ts @@ -117,6 +117,18 @@ export function runE2e(opts: E2eOptions): number { console.error("✖ project id required: --project-id or POSTHOG_WIZARD_PROJECT_ID."); return 2; } + // The source-maps run answers the agent's "api-key" ask with this key (a + // personal API key with the "Source map upload" preset). Without it the host + // would fall back to the generic sentinel answer and write a junk key to the + // fixture's .env — fail fast instead. Forwarded via childEnv's process.env + // spread below. + if (opts.program === "error-tracking-upload-source-maps" && !process.env.SOURCE_MAPS_CLI_KEY) { + console.error( + "✖ SOURCE_MAPS_CLI_KEY is required for the upload-source-maps e2e " + + "(a personal API key created with the 'Source map upload' preset).", + ); + return 2; + } const appSrc = join(APPS_DIR, app); if (!existsSync(appSrc)) { @@ -176,10 +188,14 @@ export function runE2e(opts: E2eOptions): number { /* harness crashed before writing */ } - // The integration flow ends at keep-skills/skillsComplete; other programs - // (e.g. self-driving) end at their own outro, so assert against that instead. - const isIntegration = !opts.program || opts.program === "posthog-integration"; - const programChecks: Array<[string, boolean]> = isIntegration + // Programs that end at keep-skills (integration, source-maps) assert + // skillsComplete; programs whose outro is terminal (self-driving) assert the + // outro was reached instead. + const endsAtKeepSkills = + !opts.program || + opts.program === "posthog-integration" || + opts.program === "error-tracking-upload-source-maps"; + const programChecks: Array<[string, boolean]> = endsAtKeepSkills ? [ ["full interactive flow reached keep-skills", !!result?.screenPath?.includes("keep-skills")], ["skillsComplete", result?.skillsComplete === true],