WooCommerce Dual API

Building and staleness checks

The GraphQL layer is generated from the code API by a build script and committed to source control. This document covers the commands and the check that keeps the committed output in sync with its source.

Regenerating

From your plugin’s root, run your build script (see Creating a dual API in a plugin for what it contains):

# Regenerate the GraphQL layer from src/Api/
php bin/build-api.php

# Same, when the WooCommerce Dual API plugin isn't a sibling directory
WC_DUAL_API_PATH=/path/to/woocommerce-dual-api php bin/build-api.php

The script wipes and regenerates the output directory, formats the result with phpcbf, refreshes your Composer autoloader (composer dump-autoload in your plugin root), and writes the staleness-tracking files. WC_DUAL_API_PATH may point at the installed plugin or at a clone of its repository with composer install run in it.

After regenerating, commit the src/Api/ change and the regenerated src/Internal/Api/Autogenerated/ tree together.

Formatting

The build formats the generated files with phpcbf (WordPress-Core standard). It looks for the binary among the dual API plugin’s development dependencies, so it is only found when you build against a clone with composer install run in it; when it is missing the build prints a warning and leaves the files unformatted. Formatting only affects whitespace: the code is functionally identical with or without it.

For fast local iteration, pass --no-linter: the phpcbf pass is the slowest step in the build. Run a full build before committing so the formatted output is what lands in source control. ApiBuilder::run_for_plugin() honours --no-linter from argv, so php bin/build-api.php --no-linter works.

The low-level entry point

run_for_plugin() derives every path from the conventional layout. For a non-conventional layout, call the dual API plugin’s bin/api-builder/build-api.php directly with all of these flags:

Flag Meaning
--api-dir=PATH Directory of code-API source classes to scan.
--autogen-dir=PATH Output directory (wiped each run).
--api-namespace=NS PSR-4 namespace mapping to --api-dir.
--autogen-namespace=NS PSR-4 namespace mapping to --autogen-dir.
--text-domain=DOMAIN Text domain the generated code translates its descriptions with.
--composer-working-dir=DIR Where to run composer dump-autoload; omitted = the autoloader isn’t regenerated.
--phpcbf-path=PATH Path to the phpcbf binary used for formatting.
--no-linter Skip the phpcbf formatting pass.

The staleness check

The dual API plugin’s bin/api-builder/check-api-staleness.php fails when a committed generated tree doesn’t match the current source:

php /path/to/woocommerce-dual-api/bin/api-builder/check-api-staleness.php --api-dir=src/Api --autogen-dir=src/Internal/Api/Autogenerated

The check is content-based, not timestamp-based: the build writes a SHA-256 hash of every .php file under the source dir (each file hashed as relative_path \0 contents \0, files sorted by path) into api_source_hash.txt in the output directory. StalenessChecker::is_stale() recomputes that hash and compares. Because it ignores mtimes and filesystem iteration order, it behaves identically on fresh clones, in CI, and during active development. (api_generation_date.txt is also written, for human reference only.)

CI enforcement

Add the staleness check to your plugin’s CI so that a pull request that changes src/Api/ without regenerating fails with Generated GraphQL API code is out of date. The job needs a copy of the WooCommerce Dual API plugin, for example a checkout of its repository with composer install --no-dev run in it. Regenerate, commit, and push to clear the failure.