Skip to content

CLI-1793: Consume Cloud API v3 OpenAPI spec in ACLI - #2018

Open
deepakmishra2 wants to merge 19 commits into
mainfrom
feature/meo-v3-gateway
Open

CLI-1793: Consume Cloud API v3 OpenAPI spec in ACLI#2018
deepakmishra2 wants to merge 19 commits into
mainfrom
feature/meo-v3-gateway

Conversation

@deepakmishra2

@deepakmishra2 deepakmishra2 commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

This pull request introduces support for Acquia Cloud API v3 (MEO) commands, enabling the CLI to dynamically generate commands from the v3 OpenAPI spec and handle v3-specific conventions. The changes include a new workflow for automated v3 spec updates, new service definitions and classes for v3 command generation, and enhancements to the command helper logic to support v3's OpenAPI conventions and stability indicators. Additionally, the CLI now correctly filters and displays v3 commands and handles edge cases in argument parsing.

Key changes:

Acquia Cloud API v3 Support

  • Added new classes ApiV3CommandFactory and ApiV3CommandHelper to generate CLI commands from v3 OpenAPI specs, using v3-specific extension fields and filtering logic. (src/Command/Api/ApiV3CommandFactory.php, src/Command/Api/ApiV3CommandHelper.php) [1] [2]
  • Introduced V3ClientService to resolve the v3 API base URI and share credentials with v2, with service registration in the DI container. (src/CloudApi/V3ClientService.php, config/prod/services.yml, src/CloudApi/CloudCredentials.php) [1] [2] [3]

Automated v3 Spec Updates

  • Added a GitHub Actions workflow to download, dereference, and commit updates to the Acquia v3 OpenAPI spec on a schedule or manual trigger. (.github/workflows/update-v3-spec.yml, assets/acquia-v3-spec.version) [1] [2]

Command Generation and Filtering Improvements

  • Enhanced ApiCommandHelper to support extension-point overrides for v3, including command name extraction, stability detection, and audience/channel-based filtering. (src/Command/Api/ApiCommandHelper.php, src/Command/Api/ApiV3CommandHelper.php) [1] [2] [3] [4] [5]
  • Updated command description and execution logic to display stability warnings for pre-release or non-production commands. (src/Command/Api/ApiBaseCommand.php) [1] [2]

CLI List and Namespace Handling

  • Improved namespace handling for list commands, including support for api:v3 and correct filtering of subcommands by namespace depth. (src/Command/Api/ApiListCommandBase.php, src/Command/Api/ApiCommandHelper.php, src/Command/Self/ListCommand.php) [1] [2] [3] [4]

Testing and Miscellaneous

  • Added unit tests for V3ClientService construction and authentication logic. (tests/phpunit/src/CloudApi/ClientServiceTest.php) [1] [2]
  • Improved handling of array arguments in generated commands and fixed minor logic bugs. (src/Command/Api/ApiCommandHelper.php, src/Command/Ide/IdeCreateCommand.php) [1] [2]

* Bump the dependencies group with 2 updates (#2010)

Bumps the dependencies group with 2 updates: [guzzlehttp/guzzle](https://github.com/guzzle/guzzle) and [ramsey/uuid](https://github.com/ramsey/uuid).

Updates `guzzlehttp/guzzle` from 7.11.1 to 7.12.1
- [Release notes](https://github.com/guzzle/guzzle/releases)
- [Changelog](https://github.com/guzzle/guzzle/blob/7.12/CHANGELOG.md)
- [Commits](guzzle/guzzle@7.11.1...7.12.1)

Updates `ramsey/uuid` from 4.9.2 to 4.9.3
- [Release notes](https://github.com/ramsey/uuid/releases)
- [Changelog](https://github.com/ramsey/uuid/blob/4.x/CHANGELOG.md)
- [Commits](ramsey/uuid@4.9.2...4.9.3)

---
updated-dependencies:
- dependency-name: guzzlehttp/guzzle
  dependency-version: 7.12.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: dependencies
- dependency-name: ramsey/uuid
  dependency-version: 4.9.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* CLI-1793: Spike — POC to consume Cloud API v3 OpenAPI spec in ACLI

Adds a parallel command-generation path for v3 specs sourced from
`acquia/api-specs`, without touching the existing v2 or ACSF pipelines.

- composer.json: new `update-acquia-v3-spec` script that bundles
  site-service-php + environment-service-php via redocly, then
  translates legacy `x-cli-name` to ARB-550's
  `x-acquia-exposure.channels.cli.command` at the consumption boundary.
- src/Command/Api/ApiCommandHelper.php: extracted `getCliCommandName()`
  and `normalizePath()` as protected template methods. v2 behavior
  unchanged (defaults return legacy key / input path).
- src/Command/Api/ApiV3CommandHelper.php: subclass with strict ARB-550
  key lookup (no legacy fallback) and `/v3/` path prefixing for
  env-service endpoints (site-service endpoints are not prefixed on
  the live gateway and are left untouched).
- bin/acli: register `api:v3:*` commands under a `file_exists` guard,
  reusing the existing `ApiCommandFactory`.
- assets/acquia-v3-spec.json: first v3 bundle (20 operations across
  site-service-php + environment-service-php).
- docs/poc/acquia-v3-spec-ingestion.md: findings doc with go/no-go
  recommendation, upstream dependency tracking (API-1678 KaaS server,
  API-1674 CLI directive, acquia/api-specs PR #46 bundling fixes),
  and a cleanup plan for each jq transform once upstream catches up.

Tests: 32 pass / 159 assertions. 4 ARB-550 key cases, 4 path
normalization cases, 6 spec-file sanity checks, 5 real-bundle E2E
tests, plus v2 regression coverage via ApiCommandHelperTest and
ApiListCommandTest.

Live-verified end-to-end:
- `api:v3:environments:find <uuid>` returns 200 OK with real MEO env
  data from the production Cloud Platform gateway.
- `api:v3:sites:duplicate` accepted (202) and created a real
  duplicated site.
- No regressions on `api:*` (378 v2 commands) or `acsf:*` (128 commands).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix mutation testing.

* fix test and v3 changes.

* fix site instance issue.

* Fix gateway url and logic update.

* mutation test added

* fix cves.

* fix test.

* fix test

* feedback changes.

* update spec.

* add more test.

* add stability flag

* mutation testing fix.

* mutation test fix.

* logic for audience added.

* mutation fix again

* update make redocly call

* CLI-1796: Productionize the v3 commands for CLI. (#2013)

* CLI-1796: Productionize the v3 commands for CLI.

* fix CI.

* remove CI logic.

* ran composer command to update spec.

* update git ssh url.

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@deepakmishra2
deepakmishra2 force-pushed the feature/meo-v3-gateway branch from 33243c5 to c2df57a Compare July 10, 2026 10:21
@deepakmishra2 deepakmishra2 self-assigned this Jul 10, 2026
@deepakmishra2 deepakmishra2 added the breaking change Requires change record label Jul 10, 2026
@codecov

codecov Bot commented Jul 10, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 98.78049% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 92.54%. Comparing base (9afe4e7) to head (d4539a0).

Files with missing lines Patch % Lines
src/Command/Ide/IdeCreateCommand.php 66.66% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##               main    #2018      +/-   ##
============================================
+ Coverage     92.49%   92.54%   +0.04%     
- Complexity     1995     2022      +27     
============================================
  Files           123      126       +3     
  Lines          7238     7307      +69     
============================================
+ Hits           6695     6762      +67     
- Misses          543      545       +2     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@github-actions

Copy link
Copy Markdown

Try the dev build for this PR: https://acquia-cli.s3.amazonaws.com/build/pr/2018/acli.phar

curl -OL https://acquia-cli.s3.amazonaws.com/build/pr/2018/acli.phar
chmod +x acli.phar

deepakmishra2 and others added 6 commits July 15, 2026 11:44
Adds a GitHub Actions workflow (.github/workflows/update-v3-spec.yml)
that runs daily at 03:00 UTC (and supports workflow_dispatch). It fetches
the latest v3 OpenAPI spec from the gateway URL, converts YAML to JSON,
and auto-creates + auto-merges a PR when the spec changes.

Removes the old update-acquia-v3-spec composer script (npm/git-clone
approach) since the workflow replaces it.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
GITHUB_TOKEN cannot trigger CI on automated PRs; a PAT stored as
GH_TOKEN is required for workflow runs to start on the created PR.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@deepakmishra2

Copy link
Copy Markdown
Contributor Author

@copilot can you resolve the conflict?

Copilot AI added 2 commits July 24, 2026 12:00
Resolve conflicts:
- ApiBaseCommand.php: take CLI-1779 fix (POST-only empty-body guard)
- ApiCommandTest.php: keep both testPostWithBodyDoesNotSendEmptyFallback and testBodylessPutDoesNotSendEmptyJsonBody

Copilot AI commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

@copilot can you resolve the conflict?

Resolved. The two conflicts were:

  1. src/Command/Api/ApiBaseCommand.php — took the CLI-1779 fix from main: the empty-body JSON fallback is now restricted to POST only (not PUT/PATCH), since Guzzle creates a non-seekable stream for an empty stdClass on PUT/PATCH requests.

  2. tests/phpunit/src/Commands/Api/ApiCommandTest.php — kept both test methods: testPostWithBodyDoesNotSendEmptyFallback (from the feature branch) and testBodylessPutDoesNotSendEmptyJsonBody (from main), as they test complementary scenarios.

deepakmishra2 and others added 5 commits July 28, 2026 08:53
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Update update-v3-spec.yml to pull from https://staging.api.acquia.com/v3/openapi.yaml
  (replaces internal mesh endpoint which is being decommissioned)
- Refresh assets/acquia-v3-spec.json from staging: "Acquia Cloud Platform API"
  v3.0.0 with 84 paths (was "Failover Service API" v1.0.0 with 75 paths)
- Update CloudCredentials::getV3BaseUri() comment with confirmed QA and Stage URLs

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@deepakmishra2
deepakmishra2 force-pushed the feature/meo-v3-gateway branch from c37a130 to deb1468 Compare July 30, 2026 14:14
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Comment on lines +27 to +28
redocly bundle --dereferenced /tmp/acquia-v3-raw.yaml -o /tmp/acquia-v3-deref.json
jq 'del(.paths["/openapi.yaml"])' /tmp/acquia-v3-deref.json > assets/acquia-v3-spec.json

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we had to do this because Spec is not dereferenced and the YAML served has internal $ref entries (e.g. $ref: '#/components/parameters/Failover_Service_API_Offset').

@deepakmishra2
deepakmishra2 requested a review from shriacquia July 30, 2026 18:23
@deepakmishra2 deepakmishra2 changed the title [Do not Merge] CLI-1793: Consume Cloud API v3 OpenAPI spec in ACLI (#2011) [Do not Merge] CLI-1793: Consume Cloud API v3 OpenAPI spec in ACLI Jul 30, 2026
Comment thread src/CloudApi/CloudCredentials.php Outdated
deepakmishra2 and others added 3 commits August 4, 2026 15:59
- Default getV3BaseUri() to https://api.acquia.com/v3 (prod confirmed)
- Override via ACLI_CLOUD_API_V3_BASE_URI for dev/stage environments
- Update spec download workflow to pull from prod instead of staging
- Update test to assert prod default when env var is unset

Co-Authored-By: Deepak Kumar Mishra <deepak.mishra@acquia.com>
@deepakmishra2
deepakmishra2 marked this pull request as ready for review August 13, 2026 10:31
Copilot AI lite review requested due to automatic review settings August 13, 2026 10:31
@deepakmishra2 deepakmishra2 changed the title [Do not Merge] CLI-1793: Consume Cloud API v3 OpenAPI spec in ACLI CLI-1793: Consume Cloud API v3 OpenAPI spec in ACLI Aug 13, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds first-class support for Acquia Cloud API v3 (MEO) by loading a bundled v3 OpenAPI spec and dynamically generating api:v3:* CLI commands, including v3-specific extension handling (command naming, stability, and audience/channel filtering). This extends the existing spec-driven v2 command generation pipeline without duplicating the bulk of the generator logic.

Changes:

  • Introduces v3-specific command helper/factory and DI wiring to generate api:v3:* commands from the v3 OpenAPI bundle.
  • Enhances the shared API command generator to support overridable extension lookups (CLI name, stability, skip rules) and fixes list-namespace generation for multi-segment prefixes like api:v3.
  • Adds a scheduled GitHub Actions workflow to fetch/dereference the v3 spec, plus PHPUnit coverage for v3 spec sanity, filtering, stability tagging/warnings, and array-argument edge cases.

Reviewed changes

Copilot reviewed 19 out of 21 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
tests/phpunit/src/Misc/ApiV3SpecTest.php Sanity checks for the committed v3 spec bundle (structure, refs, placeholders, exposure keys).
tests/phpunit/src/Commands/Api/ApiV3CommandHelperTest.php Unit + bundle-driven tests covering v3 extension conventions, filtering, stability tagging, and list-prefix behavior.
tests/phpunit/src/Commands/Api/ApiListCommandTest.php Adds coverage for namespace filtering and list-command hiding edge cases.
tests/phpunit/src/Commands/Api/ApiCommandTest.php Adds tests for stability runtime warnings and POST-body handling correctness.
tests/phpunit/src/Commands/Api/ApiCommandHelperTest.php Adds tests for multi-segment prefixes and required array-body argument behavior.
tests/phpunit/src/CloudApi/EnvVarAuthenticationTest.php Adds env-var coverage for v3 base URI resolution.
tests/phpunit/src/CloudApi/ClientServiceTest.php Adds a basic construction/auth test for the new V3ClientService.
src/Command/Self/ListCommand.php Extends hiding logic to handle api:v3 namespaces and sub-namespaces.
src/Command/Ide/IdeCreateCommand.php Adjusts IDE DNS wait flow to only print links when ready and returns failure on non-ready termination.
src/Command/Api/ApiV3CommandHelper.php Implements v3-specific command-name lookup, stability extraction, and audience/channel filtering.
src/Command/Api/ApiV3CommandFactory.php Adds a v3 command factory variant injecting the v3 client service.
src/Command/Api/ApiListCommandBase.php Fixes list wrapper commands to pass through the correct namespace.
src/Command/Api/ApiCommandHelper.php Adds overridable extension hooks (CLI name, stability, skip rules), stability tagging in descriptions, and fixes list generation for api:v3.
src/Command/Api/ApiBaseCommand.php Adds stability state + runtime warning for non-production commands.
src/CloudApi/V3ClientService.php Introduces a v3 client service class for DI separation while reusing ClientService behavior.
src/CloudApi/CloudCredentials.php Adds getV3BaseUri() with env-var override for v3 gateway routing.
config/prod/services.yml Registers v3 connector factory + V3ClientService in the Symfony container.
bin/acli Loads v3 spec-derived command factories into the lazy command loader.
assets/acquia-v3-spec.version Adds a pinned identifier for the bundled v3 spec version.
.github/workflows/update-v3-spec.yml Adds scheduled/manual workflow to download, dereference, and PR/auto-merge v3 spec updates.
Suppressed comments (1)

src/Command/Api/ApiCommandHelper.php:444

  • Same issue as above: protectedprivate is not a false positive for Infection here. Making this method private would prevent ApiV3CommandHelper’s override from being used, breaking v3 audience/channel filtering.
     * @infection-ignore-all — protected→private is a false positive: PHP still dispatches
     *   to the child's protected override via $this, so behaviour is identical.
     */

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +426 to +432
/**
* Extracts the stability level from an operation schema, or null if not declared.
* Override in subclasses that use a different spec convention (e.g. v3).
*
* @infection-ignore-all — protected→private is a false positive: PHP still dispatches
* to the child's protected override via $this, so behaviour is identical.
*/
Comment on lines +355 to +357
/**
* @return ApiBaseCommand[]
*/
Comment on lines +484 to +488
$this->assertStringNotContainsString(
'[',
$desc,
"Command '{$command->getName()}' (production) must not have a stability tag."
);
Comment on lines +37 to +44
public function testV3BaseUriFromEnvVar(): void
{
$v3Uri = 'https://gateway.dev.api.acquia.io/v3';
putenv('ACLI_CLOUD_API_V3_BASE_URI=' . $v3Uri);
self::assertEquals($v3Uri, $this->cloudCredentials->getV3BaseUri());
putenv('ACLI_CLOUD_API_V3_BASE_URI');
self::assertEquals('https://api.acquia.com/v3', $this->cloudCredentials->getV3BaseUri());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking change Requires change record

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants