Uh oh!
There was an error while loading. Please reload this page.
Make the test runners cheaper to run repeatedly and quieter to read back - #356
Make the test runners cheaper to run repeatedly and quieter to read back#356swissspidy wants to merge 5 commits into
Conversation
Adds two opt-in environment variables to the runner scripts, both unset by default so existing output is unchanged: * NO_COLOR (https://no-color.org/) stops the runners from forcing ANSI color codes on. parallel-lint and PHPUnit forced them unconditionally, which meant escape sequences in every captured log. * WP_CLI_TEST_QUIET switches the reporters to their most compact form: PHP_CodeSniffer to one line per violation with no progress ticker, PHPStan to one line per error with no progress bar and no result table, and Behat to omitting step definition snippets. Also documents narrowing a Behat run to a single scenario, --stop-on-failure and composer behat-rerun. Refs wp-cli/wp-cli#6161 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VcGmbu6CYzGGhP3jXuWDkJ
Every `composer behat` invocation resolved WP_VERSION over the network: one request to api.wordpress.org for `latest`, and a second one to the wp-versions artifact when the version has no patch number. That cost applies equally to a full suite run and to re-running one scenario for the fifth time while iterating on a fix. The answers now go into a cache in the system temp directory with a configurable lifetime, defaulting to a day. Two side effects worth noting: * A run without connectivity falls back to the last known answer rather than continuing with an empty WP_VERSION, which silently disabled the filtering of version-specific tags. * When there is nothing to fall back to, that case is now reported instead of being silent. Refs wp-cli/wp-cli#6161 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VcGmbu6CYzGGhP3jXuWDkJ
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
The feature files are linted on every pull request, but the check lives entirely in the reusable CI workflow and its ruleset lives in wp-cli/.github, so contributors cannot run it locally at all. A green `composer test` is therefore not a green build, and the way to find out is to push. Moves the check to where the other suites are: `.gherkin-lintrc` ships with this package as the shared default, a project can override it by committing its own, and `composer lint-gherkin` runs it. CI can then call the same script rather than reimplementing the invocation. Uses gherkin-lint-plus, pinned, and overridable through WP_CLI_TEST_GHERKIN_LINT_VERSION. Being a Node package, it is invoked through npx and skips with a message where npx is absent, rather than failing a suite that is otherwise entirely PHP. The linter colors its report unconditionally and offers no plain output format, so NO_COLOR strips the escape sequences from its output. Refs wp-cli/wp-cli#6161 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VcGmbu6CYzGGhP3jXuWDkJ
Drops the WP_CLI_TEST_GHERKIN_LINT_VERSION override, which was configuration nobody asked for, and puts the pinned version somewhere a dependency bot can see it. A version string inside a shell script is invisible to Dependabot; a devDependency in package.json is not. The package.json exists only to hold that pin: it is private, has no scripts, and nothing runs `npm install` against it. The runner reads the version out of it and fails loudly if it is missing, rather than quietly falling through to whatever the latest release happens to be. Note that picking these updates up needs an npm entry in the dependabot.yml that wp-cli/.github syncs out. Refs wp-cli/wp-cli#6161 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VcGmbu6CYzGGhP3jXuWDkJ
Two points from review: * The wp-versions artifact already marks the current release with a "latest" status, so the separate request to api.wordpress.org was redundant. Both the "latest" and the X.Y resolution now come out of that one file, which means one cached artifact and at most one network request per run instead of two. * Behat's step definition snippets are not only printed when writing new step definitions; they are also how a typo in an existing step surfaces. That makes them a diagnostic rather than noise, and they only appear when something is already wrong, so suppressing them under WP_CLI_TEST_QUIET saved nothing in the passing case and cost information in the failing one. Dropped, which leaves WP_CLI_TEST_QUIET with no effect on Behat. Also adds lint-gherkin to the setup instructions, which listed the scripts a consuming package should wire up but not the new one. Refs wp-cli/wp-cli#6161 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VcGmbu6CYzGGhP3jXuWDkJ
Three independent changes coming out of the discussion in wp-cli/wp-cli#6161 about what it costs an AI agent — or anyone iterating in a terminal — to work in a WP-CLI repository. Happy to split them into separate pull requests if that reads better.
Pairs with wp-cli/.github#285, which rewrites the
composer testguidance inAGENTS.mdand points the CI Gherkin job atcomposer lint-gherkin.1. Quieter output, opt-in
Two environment variables, both unset by default, so nothing changes for existing users or for CI:
NO_COLOR(no-color.org) stops the runners from forcing ANSI color on.run-linter-testspassed--colorsandrun-php-unit-testspassed--color=alwaysunconditionally, so every captured log carried escape sequences whether or not anything was going to render them. Where a project's own config can turn color back on —phpunit.xmlwithcolors="true"— the flag is set to an explicitneverrather than omitted.WP_CLI_TEST_QUIETswitches the reporters to their most compact form:-q --report=emacs, onefile:line:colline per violation, no progress ticker--no-progress --error-format=raw, onefile:line:messageline per error, no redrawing progress bar and no box-drawing result tableBehat is deliberately untouched: its
progressoutput is already minimal, and its step definition snippets are how a typo in an existing step surfaces, so they are a diagnostic rather than noise.Also documents, in the README, things the runners already supported but nobody had written down: narrowing a Behat run to a single scenario with
features/x.feature:12,--tags=,--stop-on-failure, andcomposer behat-rerun.2. Cache the WP_VERSION lookup
run-behat-testsresolvedWP_VERSIONover the network on every single invocation, whether you were running the full suite or re-running one scenario for the fifth time while iterating on a fix.It also made two separate requests for what is one question. The
wp-versionsartifact already carries a status per release with the current one markedlatest, so the extra call toapi.wordpress.orgwas redundant. Both thelatestresolution and theX.Y→ latest-patch resolution now come out of that single file.It is cached under the system temp directory, following the
wp-cli-test-*naming theFeatureContextcore download cache already uses. Lifetime defaults to a day and is configurable throughWP_CLI_TEST_WP_VERSION_CACHE_TTL, where0fetches every run. Net effect: at most one request per run, and none at all on a warm cache.Two behavior changes fall out of it, both of which look like improvements but are worth calling out explicitly:
WP_VERSION, which silently disabled filtering of the@require-wp-*tags.WP_VERSION=X.Y.0still normalizes toX.Yand stops there, rather than resolving on to the newest patch — that spelling asks for the initial release specifically.3. Bring the Gherkin linting into the test suite
The feature files are linted on every pull request, but the check exists only inside the reusable CI workflow and its ruleset lives in
wp-cli/.github. Contributors cannot run it locally at all — not "it is inconvenient", but there is no config file in the repository to run it against. Socomposer testpassing does not mean the build passes, and the way to find out is to push.This moves it next to the other suites:
.gherkin-lintrcships with this package as the shared default ruleset, carried over unchanged fromwp-cli/.github. A project that needs different rules overrides it by committing its own.composer lint-gherkinruns it, and it joinscomposer testand the setup instructions.Uses gherkin-lint-plus. It is a Node package, so it runs through
npxand needs Node.js 20 or later; wherenpxis absent it reports that it is skipping rather than failing a suite that is otherwise entirely PHP. That is a deliberate trade — a hard failure would breakcomposer testfor every PHP-only contributor across ~40 repositories — and CI, where Node is always present, still enforces it.The version is pinned in a
package.jsonthat exists for no other purpose: it is private, has no scripts, and nothing runsnpm installagainst it. The pin lives there rather than in the shell script because a version string in a shell script is invisible to Dependabot. Picking the updates up needs the npm entry added in wp-cli/.github#285.One wrinkle worth recording: the linter writes its report to STDERR and colors it unconditionally, honoring neither
NO_COLORnor the absence of a terminal, andstylishis its only output format. So the runner strips the escape sequences from that stream itself whenNO_COLORis set, preserving STDOUT and the exit code.Testing
The Gherkin linting is verified end to end, since Node was available where I was working:
wp-cli/wp-cli's thirty-five pass cleanly under the ported ruleset, so adopting this does not start with a wall of pre-existing violations.file-name,no-unnamed-scenarios,indentationanduse-andare all caught, exit code 1, whileno-trailing-spacescorrectly stays quiet because the shared config disables it. The fork reads the existing ruleset the same waygherkin-lintdid,indentationoption keys included.NO_COLOR=1output is stripped of escape sequences with the exit code preserved; the default run keeps its colors; a clean tree prints nothing and exits 0; an explicit path argument overrides thefeaturesdefault; a package with nofeaturesdirectory skips and exits 0; apackage.jsonwith the pin removed fails with a message rather than silently installing the latest release.The version resolution was exercised against a stubbed
curland the real artifact: cold cache, warm cache withcurlremoved fromPATHentirely (zero requests), stale entry with the network down, a malformed response,latest→7.0.4,6.8→6.8.8,6.9.0→6.9,7.0.0→7.0, andtrunkand exact versions passing through untouched. All the shell is syntax-checked andcomposer validatepasses.What I could not do is run the PHP suites.
composer installdoes not complete in the environment I am working in —phpstan/phpstanis dist-only and its dist URL is onapi.github.com, which is blocked here. So the flags in the first commit (--report=emacs,--error-format=raw,--color=never) are unverified by execution and rest on the documented CLI surface of each tool. That is the part of this pull request that most needs CI, or a second pair of eyes.Refs wp-cli/wp-cli#6161