diff --git a/src/commands/init.ts b/src/commands/init.ts index 9dd377c4..52a06557 100644 --- a/src/commands/init.ts +++ b/src/commands/init.ts @@ -338,6 +338,9 @@ export default createCommand(config, async ({ values }) => { console.info("Run `prismic pull` to pull models from Prismic."); } + // Progress reporting must not turn a successful project setup into a failure. + await completeOnboardingSteps(["connectPrismic"], { repo, token, host }).catch(sentryCaptureError); + // Printed last so it is the step the reader is left with. const setupInstructions = await adapter.getSetupInstructions(); if (setupInstructions) console.info(`\n${setupInstructions}`); diff --git a/src/lib/prismic/clients/repository.ts b/src/lib/prismic/clients/repository.ts index 302b2165..dbdab45b 100644 --- a/src/lib/prismic/clients/repository.ts +++ b/src/lib/prismic/clients/repository.ts @@ -67,6 +67,20 @@ export async function toggleOnboardingStep( }); } +export async function completeOnboardingStep( + stepId: string, + config: RepositoryConfig, +): Promise { + const url = new URL( + `onboarding/${encodeURIComponent(stepId)}/complete`, + getRepositoryServiceUrl(config.host), + ); + return onboardingServiceRequest(url, config, { + method: "PATCH", + schema: OnboardingStateSchema, + }); +} + function repositoryServiceRequest( url: URL, config: RepositoryConfig, diff --git a/src/lib/prismic/onboarding.ts b/src/lib/prismic/onboarding.ts index 4abb7850..e1b155ce 100644 --- a/src/lib/prismic/onboarding.ts +++ b/src/lib/prismic/onboarding.ts @@ -1,4 +1,4 @@ -import { getOnboardingState, toggleOnboardingStep } from "./clients/repository"; +import { completeOnboardingStep } from "./clients/repository"; type OnboardingConfig = { repo: string; @@ -17,12 +17,7 @@ export async function completeOnboardingSteps( stepIds: OnboardingStep[], config: OnboardingConfig, ): Promise { - const { repo, token, host } = config; - const { completedSteps } = await getOnboardingState({ repo, token, host }); - const missing = stepIds.filter((id) => !completedSteps.includes(id)); - - // API does not accept multiple steps; toggle each missing step sequentially. - for (const stepId of missing) { - await toggleOnboardingStep(stepId, { repo, token, host }); + for (const stepId of new Set(stepIds)) { + await completeOnboardingStep(stepId, config); } } diff --git a/test/init.test.ts b/test/init.test.ts index b9e1de7c..b2cec4ff 100644 --- a/test/init.test.ts +++ b/test/init.test.ts @@ -34,6 +34,15 @@ it("supports --help", async ({ expect, prismic }) => { expect(stdout).toContain("prismic docs view cli#set-up-a-type-builder-project"); }); +it("completes app connection after repeated successful init", async ({ expect, prismic, repo, token, host }) => { + for (let attempt = 0; attempt < 2; attempt++) { + const { exitCode, stderr } = await prismic("init", ["--repo", repo, "--no-setup"]); + expect(exitCode, stderr).toBe(0); + } + const completedSteps = await getOnboardingCompletedSteps({ repo, token, host }); + expect(completedSteps.filter((step) => step === "connectPrismic")).toHaveLength(1); +}); + it("fails if prismic.config.json already exists without --repo", async ({ expect, prismic, @@ -439,6 +448,7 @@ it("completes the handoff for a starter project", async ({ const completedSteps = await getOnboardingCompletedSteps({ repo, token, host }); expect(completedSteps).toContain("instantStart_continueBuildingLocally"); + expect(completedSteps).toContain("connectPrismic"); } finally { await deleteRepository(repo, { token, password, host }); }