From 20796ae5240cf176a1cbccf1ea16ca73c3e19622 Mon Sep 17 00:00:00 2001 From: "Vincent (Wen Yu) Ge" Date: Thu, 27 Aug 2026 11:05:31 -0400 Subject: [PATCH 1/3] feat(wizard-ci): enable upload-source-maps e2e snapshots Flips ciCapable on upload-sourcemaps, threads SOURCE_MAPS_CLI_KEY through the CI workflow (fail fast when missing), and asserts source-maps runs end at keep-skills like integration. Fresh port of #2379 onto current main. Generated-By: PostHog Desktop Task-Id: 7e06dd69-14e8-4105-b15e-655c10cc47d5 --- .env.example | 3 +++ .github/workflows/wizard-ci.yml | 4 ++++ apps/manifest.json | 2 +- services/wizard-ci/e2e.ts | 24 ++++++++++++++++++++---- 4 files changed, 28 insertions(+), 5 deletions(-) diff --git a/.env.example b/.env.example index 8064091ff..addde76f8 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... diff --git a/.github/workflows/wizard-ci.yml b/.github/workflows/wizard-ci.yml index 8d515df74..b88267e08 100644 --- a/.github/workflows/wizard-ci.yml +++ b/.github/workflows/wizard-ci.yml @@ -665,6 +665,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 }} WIZARD_REF: ${{ needs.discover.outputs.input_wizard_ref }} diff --git a/apps/manifest.json b/apps/manifest.json index 33e8a77a5..0aaa1f733 100644 --- a/apps/manifest.json +++ b/apps/manifest.json @@ -69,7 +69,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], From b0e382805a77ba3211527b5d9b25d768fda8be2f Mon Sep 17 00:00:00 2001 From: "Vincent (Wen Yu) Ge" Date: Thu, 27 Aug 2026 11:36:17 -0400 Subject: [PATCH 2/3] docs(wizard-ci): tighten source-maps e2e comments Generated-By: PostHog Desktop Task-Id: 7e06dd69-14e8-4105-b15e-655c10cc47d5 --- .github/workflows/wizard-ci.yml | 4 +--- services/wizard-ci/e2e.ts | 10 ++-------- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/.github/workflows/wizard-ci.yml b/.github/workflows/wizard-ci.yml index b88267e08..b8d5838b9 100644 --- a/.github/workflows/wizard-ci.yml +++ b/.github/workflows/wizard-ci.yml @@ -665,9 +665,7 @@ 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). + # Upload key for the source-maps e2e ("Source map upload" preset; vaulted to a secretRef for the agent). 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 }} diff --git a/services/wizard-ci/e2e.ts b/services/wizard-ci/e2e.ts index 3f1354458..9f4b70488 100644 --- a/services/wizard-ci/e2e.ts +++ b/services/wizard-ci/e2e.ts @@ -117,11 +117,7 @@ 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. + // The source-maps upload key; without it the host would write a junk sentinel key — fail fast instead. 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 " + @@ -188,9 +184,7 @@ export function runE2e(opts: E2eOptions): number { /* harness crashed before writing */ } - // Programs that end at keep-skills (integration, source-maps) assert - // skillsComplete; programs whose outro is terminal (self-driving) assert the - // outro was reached instead. + // Integration and source-maps end at keep-skills; terminal-outro programs (self-driving) assert the outro. const endsAtKeepSkills = !opts.program || opts.program === "posthog-integration" || From a76949c322655b849599da1e3d3b9ad9fba9ccfc Mon Sep 17 00:00:00 2001 From: "Vincent (Wen Yu) Ge" Date: Thu, 27 Aug 2026 12:40:59 -0400 Subject: [PATCH 3/3] refactor(wizard-ci): reuse the CI key for source-maps upload Defaults SOURCE_MAPS_CLI_KEY to POSTHOG_PERSONAL_API_KEY (scoped with error_tracking:write) instead of requiring a separate secret. Generated-By: PostHog Desktop Task-Id: 7e06dd69-14e8-4105-b15e-655c10cc47d5 --- .env.example | 4 ++-- .github/workflows/wizard-ci.yml | 4 ++-- services/wizard-ci/e2e.ts | 10 ++-------- 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/.env.example b/.env.example index addde76f8..b64fabba7 100644 --- a/.env.example +++ b/.env.example @@ -11,5 +11,5 @@ POSTHOG_PERSONAL_API_KEY=phx_... # POSTHOG_REGION=us POSTHOG_WIZARD_PROJECT_ID=123 -# used by snapshots to upload source maps to PostHog -SOURCE_MAPS_CLI_KEY=phx... +# Optional: upload key for the source-maps e2e. Defaults to POSTHOG_PERSONAL_API_KEY (needs error_tracking:write). +# SOURCE_MAPS_CLI_KEY=phx... diff --git a/.github/workflows/wizard-ci.yml b/.github/workflows/wizard-ci.yml index b8d5838b9..404bde455 100644 --- a/.github/workflows/wizard-ci.yml +++ b/.github/workflows/wizard-ci.yml @@ -665,8 +665,8 @@ 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 ("Source map upload" preset; vaulted to a secretRef for the agent). - SOURCE_MAPS_CLI_KEY: ${{ secrets.GH_APP_POSTHOG_WIZARD_CI_BOT_SOURCE_MAPS_CLI_KEY }} + # The existing CI key, now with error_tracking:write, doubles as the source-maps upload key. + SOURCE_MAPS_CLI_KEY: ${{ secrets.GH_APP_POSTHOG_WIZARD_CI_BOT_POSTHOG_PERSONAL_KEY }} WIZARD_PATH: ${{ env.WIZARD_PATH }} CONTEXT_MILL_PATH: ${{ env.CONTEXT_MILL_PATH }} WIZARD_REF: ${{ needs.discover.outputs.input_wizard_ref }} diff --git a/services/wizard-ci/e2e.ts b/services/wizard-ci/e2e.ts index 9f4b70488..17d87f5cb 100644 --- a/services/wizard-ci/e2e.ts +++ b/services/wizard-ci/e2e.ts @@ -117,14 +117,6 @@ export function runE2e(opts: E2eOptions): number { console.error("✖ project id required: --project-id or POSTHOG_WIZARD_PROJECT_ID."); return 2; } - // The source-maps upload key; without it the host would write a junk sentinel key — fail fast instead. - 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)) { @@ -160,6 +152,8 @@ export function runE2e(opts: E2eOptions): number { for (const k of Object.keys(childEnv)) if (STRIP_HOST_AUTH.test(k)) delete childEnv[k]; childEnv.POSTHOG_PERSONAL_API_KEY = apiKey; + // The source-maps upload key defaults to the CI key (which has error_tracking:write); SOURCE_MAPS_CLI_KEY overrides it locally. + childEnv.SOURCE_MAPS_CLI_KEY = process.env.SOURCE_MAPS_CLI_KEY ?? apiKey; childEnv.APP_DIR = appDir; childEnv.PROJECT_ID = projectId; childEnv.POSTHOG_REGION = region;