Offer the Acquia trial signup when the account has no applications - #1
Open
lauriii wants to merge 3 commits into
Open
Offer the Acquia trial signup when the account has no applications#1lauriii wants to merge 3 commits into
lauriii wants to merge 3 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR enhances acli setup to handle first-time Acquia Cloud users who authenticate successfully but have zero existing applications, by offering a browser hand-off to the Acquia trial signup and then resuming setup once a new application (and a cloneable environment) appears via the Cloud API.
Changes:
- Add a
--newflag and a trial-signup + polling flow to create/await a new application when none exist (or when explicitly requested). - Wait for trial environment provisioning (non-production, non-node, with a git URL) before continuing into the existing setup workflow.
- Expand PHPUnit coverage for the zero-applications path, non-interactive failure modes, and timeout behavior.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| tests/phpunit/src/Commands/App/SetupCommandTest.php | Adds tests for the new trial-signup flow, non-interactive failures, and timeout handling. |
| src/Command/CommandBase.php | Widens environment-chooser helper visibility to support reuse from the new setup path. |
| src/Command/App/SetupCommand.php | Implements trial-signup prompting, polling/backoff logic, and environment provisioning waits; adds --new. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Add `acli trials:create`: creates a free 14-day trial through the trials
service (POST /trials, polled at GET /api/trials/{id} with percent
progress), resumes an in-flight trial, retries a failed one, and reports
an existing one — always safe to re-run. The template catalog is
hard-coded until the service exposes one.
dev:init uses it so a developer with no application never dead-ends: the
zero-application path offers a trial, the application picker gains a
"Create a new application" choice, and --new skips straight to trial
creation. After the trial completes, dev:init waits for the new
application and a cloneable environment, then continues to a local site
with the usual resumability.
Verified live against the production trials service: created a real
trial, watched provisioning, and exercised the retry and timeout paths.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Assert the token grant, Bearer headers on both sides of a 401 refresh, and http_errors in the request matchers; cover all three error-message fallback arms and the HTTP 400 boundary; and assert the dev:start help paragraph's position. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… cast Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Note
Stacked PR: this branch is based on
acli-createand depends on acquia#2033. The diff shows only the trial-provisioning capability.Why
acli dev:init(acquia#2033, formerlyacli setup) dead-ends for a genuine newcomer: it authenticates and then asks the user to pick an existing application, but a brand-new account has nothing to pick. This PR closes that gap so the one-liner is honest for someone starting from zero.How applications get created
The public Cloud Platform API is read-only for applications and subscriptions (
OPTIONS /api/applicationsreturnsallow: GET). Trials are created through the trials service (trials-service-prod.prod.mesh.cicd.acquia.io), which accepts the same OAuthclient_credentialstokens as the Cloud API — verified live. Its path prefixes are inconsistent by design and encoded carefully:POST /trials(create) andPOST /api/trials/{id}(retry) vsGET /api/trials(current trial, 404 = none) andGET /api/trials/{id}(status poll).What this adds
acli trials:create(aliastrial:create) — the small CLI wrapper + polling loop:--site-name,--template(validated against the catalog: archimedes, byte, caresphere, convene, convivial_gov, drupal_cms_starter, haven, healthcare, local, provus_edu, pulse — hard-coded with a@todo, the service has no catalog endpoint yet),--region. All defaulted, so it works non-interactively.percent_complete+ status printed as they change, a note every minute, timeout after 30 minutes (ACLI_TRIAL_TIMEOUToverrides, validated numeric) with exact resume instructions, and the service'sfailure_reasonsurfaced verbatim on failure.acli dev:initintegration — the trial path is reachable three ways, not gated on having existing applications or sites:--new: skips straight to trial creation; works non-interactively.After
trials:createsucceeds, dev:init pollsGET /applicationsuntil the new application appears, waits for a non-production environment with a git URL, and continues the existing flow to a running local site. Re-runningacli dev:initresumes naturally at every stage. Zero-apps non-interactive runs do not create a trial implicitly; they fail fast pointing atacli dev:init --new/acli trials:create.Implementation notes
CommandBase:pollCloud()(shared backoff poll with testable timeout), andpromptChooseEnvironmentConsiderProd()/promptChooseApplication()widenedprivate→protected(one word each) so DevInitCommand reuses the standard choosers; base behavior for other commands is unchanged.client_credentialsgrant the SDK uses, and refreshed once automatically on a 401 mid-poll (provisioning outlives the ~5-minute token lifetime).POST /trials/account, fire-and-forget CRM record) is not called; add later if wanted for parity with the UI.Verification — live, against the real trials service
Run for real with limited agent credentials (
lauri.timmanee+agent@acquia.com):POST /trials→ trial422ba415-dbc8-4830-bd10-1f80a8ce6dfc, then polled its status for the full 15 minutes of server-side provisioning.no subscription unit is available for region "us-east-1"(the prod trial pool was empty at test time) — and the command surfaced that reason verbatim with retry guidance.POST /api/trials/{id}reset it toINITIATED(7% → 14% progress output), and theACLI_TRIAL_TIMEOUToverride + timeout messaging worked.Not verified live: a trial reaching
COMPLETED(blocked by the empty pool, not by the CLI — the full status object shape includingsite_urlcomes from the service's own responses and the Cloud UI fixtures), and therefore the post-trialdev:initcontinuation against a real new application. Those legs are covered by spec-fixture/mocked tests (TrialsCreateCommandTest,DevInitCommandTest) including the zero-applications, picker,--new, decline, failure, retry, 401-refresh, and timeout paths. A human can finish verification by re-runningacli trials:createonce the trial pool has capacity, thenacli dev:init.Leftover state from testing: the failed trial above remains on the agent account (no subscription was created; re-running
trials:createretries it). Theeelaurieskolaapplication was never touched.Repo checks: phplint, phpcs, phpstan, and the full PHPUnit suite (65 serial + 561 parallel) pass locally.
🤖 Generated with Claude Code