Chore: Build pipeline fix and dev env cleanup#2933
Conversation
When downloading too fast translation files from wordpress.org we hit 429 error code. Now download script: - use translation meta endpoint to fetch information about translations - checks if files timestamp match local files and skip download if it does. - has workaround as translation meta doesn't return all locales, so for those files we check if they exist in local env and are valid .mo, .po files; download only if missing or broken - implements delay between downloads to prevent 429 - add 30 sec wait time and retry if we hit 429
|
The build on the local is now getting all translation files and it's fast as it skips most if not all files. But on GH Action we hit the 429 wall still. Assume it's because rate limit is for the the IP and many GH actions across repositories could hit the wordpress.org API causing 429. My idea is to fetch those files locally and add them to project git repo. First download script will read from translation meta API to check translation files timestamps, will compare them with project files and only download/update those that changed. GH Action will use repo files so will only fetch them from API when outdated saving on build time. |
WordPress Translation Files — What to ShipBackgroundResearch into whether plugin authors need to ship Plugin URL: https://pl.wordpress.org/plugins/woocommerce-services/ For Plugins on wordpress.orgYou do NOT need to ship WordPress automatically downloads language packs from translate.wordpress.org once
What you do need to ship:
Requirements for language packs to work:
For WooCommerce.com Paid ExtensionsWooCommerce deprecated their own language pack CDN in WooCommerce 2.4.8 (2015) File Types Reference
Bottom Line for This RepoSince this plugin is on wordpress.org:
References |
The *.js and *.php globs in lint-staged.config.js matched any staged file, including wp-calypso/**. lint-staged appends matched paths to the command, causing ESLint to auto-fix wp-calypso JS files and phpcbf to scan the entire project (wp-calypso included) on every commit. - lint-staged.config.js: convert *.js entry to a function returning a plain string so lint-staged no longer appends staged paths — ESLint runs scoped to tasks/ and client/ only. Convert *.php entry to a function that filters out wp-calypso/ files before forwarding to phpcbf. - composer.json: add wp-calypso to --ignore in all seven phpcs/phpcbf scripts (check-all, check-all:fix, check-php, check-php:fix, check-security, phpcs, phpcbf) as defence-in-depth for standalone runs.
i18n Build Pipeline — Findings & RecommendationsCurrent Build Pipeline (end-to-end)The full translation build runs as the npm run i18n && node tasks/i18n-download && npm run i18njsonStep 1 — String extraction (
|
| File | Change |
|---|---|
tasks/i18n-download.js |
Skip .mo download; remove .po/.mo copy loop |
tasks/i18njson.js |
Read .po from translations/ instead of i18n/languages/ |
i18n/languages/*.po |
Delete from git |
i18n/languages/*.mo |
Delete from git |
strings.php — Build Artifact, Not Needed in Plugin Bundle
What it is
i18n/strings.php is generated by tasks/i18n.js (line 11) during the npm run i18n
build step. It is a PHP array of all translatable strings extracted from the built JS
files, named $i18nStrings, used by Poedit and GlotPress to build the .pot template.
It is not loaded at runtime. The only reference in PHP is a stale @var comment at
woocommerce-services.php:1700 — $i18nStrings is never required or included
anywhere in the plugin. The comment is a leftover from an older approach.
Why it ends up in the plugin zip
tasks/release.js copies the entire i18n/ directory to the release folder (line 16
of dirsToCopy). Since strings.php is regenerated on every build by npm run i18n,
it is present on disk when release.js runs — even though it has been removed from git
tracking. This means it currently ships inside the plugin zip despite serving no
runtime purpose.
Plan: Exclude it from the release
Add a single cleanup line to tasks/release.js after the directory copy (line 48) and
before archive.finalize():
// Remove build artifacts not needed in the release
rm( '-f', targetFolder + '/i18n/strings.php' );This is the minimal, safe change — it does not alter the directory structure in the zip
or affect any other file, and it requires no changes to tasks/i18n.js.
Summary
| File | Status |
|---|---|
i18n/strings.php |
Generated at build time; removed from git; exclude from zip |
tasks/release.js |
Add rm( '-f', targetFolder + '/i18n/strings.php' ) before archiving |
woocommerce-services.php:1700 |
Stale @var comment referencing $i18nStrings — can be removed |
Replace the directory-scoped `eslint --fix tasks/ client/` command with a function that passes only the staged file paths directly to eslint, preventing the pre-commit hook from reformatting every JS file in the project on each commit. Also excludes wp-calypso/ files, matching the existing PHP handler.
iyut
left a comment
There was a problem hiding this comment.
This is the obvious that probably need to be changed.
| "qit:woo-api": [ | ||
| "npm run build && composer install && ./vendor/bin/qit run:woo-api woocommerce-services --zip=woocommerce-services.zip" | ||
| ], | ||
| "tests": [ |
There was a problem hiding this comment.
is there any reason we change it to tests? Because it's stated in AGENTS.md as a test under Common Commands. If we want to change it to tests then we will need to update the AGENTS.md as well.
| RUN pecl install xdebug \ | ||
| && echo 'xdebug.mode=debug' >> $PHP_INI_DIR/php.ini \ | ||
| && echo 'xdebug.start_with_request=trigger' >> $PHP_INI_DIR/php.ini \ | ||
| && echo 'xdebug.remote_timeout=3600' >> $PHP_INI_DIR/php.ini \ |
There was a problem hiding this comment.
| && echo 'xdebug.remote_timeout=3600' >> $PHP_INI_DIR/php.ini \ | |
| && echo 'xdebug.connect_timeout_ms=3600' >> $PHP_INI_DIR/php.ini \ |
XDebug 3 rename that settings.
| && echo 'xdebug.var_display_max_data=512' >> $PHP_INI_DIR/php.ini \ | ||
| && echo 'xdebug.var_display_max_children=-1' >> $PHP_INI_DIR/php.ini \ | ||
| && echo 'xdebug.var_display_max_depth=128' >> $PHP_INI_DIR/php.ini \ | ||
| && echo 'xdebug.remote_cookie_expire_time = 3600' >> $PHP_INI_DIR/php.ini \ |
There was a problem hiding this comment.
| && echo 'xdebug.remote_cookie_expire_time = 3600' >> $PHP_INI_DIR/php.ini \ |
This has been removed on the XDebug 3
|
|
||
| == Changelog == | ||
|
|
||
| = 3.5.1 - 2026-02-23 = |
There was a problem hiding this comment.
| = 3.5.1 - 2026-02-23 = | |
| = 3.5.1 - 2026-xx-xx = |
| @@ -1,7 +1,10 @@ | |||
| *** WooCommerce Tax Changelog *** | |||
|
|
|||
| = 3.5.1 - 2026-02-23 = | |||
There was a problem hiding this comment.
| = 3.5.1 - 2026-02-23 = | |
| = 3.5.1 - 2026-xx-xx = |
iyut
left a comment
There was a problem hiding this comment.
Just having conversation with Bart and listen to his explanation about the translations folder and his reasoning. I'll approve this since this is the efficient way to fix the translation issue.

Description
Fixes the build i18n translation that resulted with pushing broken translation files
See https://plugins.trac.wordpress.org/browser/woocommerce-services/#tags/3.5.0/i18n/languages
All .po, .mo files of 162 bytes size contents is
Modernises the local development environment and static-analysis toolchain without touching any plugin functionality. The goal is to bring all dev tooling up to current standards so new contributors can spin up quickly and PHPCS/PHPUnit reflect the actual PHP/WP versions we target.
Also includes several build-pipeline fixes discovered while validating the changes in CI.
How to test:
i18n/languagesfolder contain only .json files.npm run upit should workChanges at a glance:
Dockerfile-php84), update WP-CLI user fromxfs→www-data, add--ssl=0towp db checkcalls to avoid TLS handshake noise.phpcs.xml.dist,.phpcs.security.xml): bump minimum WP version 4.7 → 6.7, PHP compatibility target 5.6– → 7.4–, excludedocker/andwp-calypso/directories, remove stale rule exceptions (DisallowShortArraySyntax/NotHyphenatedLowercaseforclasses/), fixtext_domainproperty syntax, add trailing newline.composer.json,composer.lock): bump all Jetpack and WPCS packages to latest stable versions, add new dev dependencies (phpstan,php-parallel-lint,php-stubs/wordpress-stubs,phpcs-variable-analysis,ergebnis/composer-normalize), normalise JSON indentation (tabs), add missingallow-pluginsentries.composer.json): fixphpcsandphpcbfscript definitions so they execute correctly..gitignore: add.phpunit.result.cache.i18n/: remove stale generated artefacts (woocommerce-services.pot,strings.php).package.json,npm-shrinkwrap.json): addreact-modalto dev dependencies — it was missing, causing webpack to fail in CI.tasks/i18n.js,tasks/i18n-download.js): two fixes found when runningnpm run buildin CI:tasks/i18n.js— createi18n/languages/directory if it doesn't exist. CI starts from a clean checkout so the gitignoredi18n/directory is absent, causing a hard crash before this fix.tasks/i18n-download.js— overhauled to avoid translate.wordpress.org rate limiting (HTTP 429) that was writing HTML error pages into.po/.mofiles:api.wordpress.org/translations/plugins/1.0/in a single call to get last-updated timestamps per locale.Related issue(s)
N/A — this is a standalone dev-environment housekeeping PR.
Steps to reproduce & screenshots/GIFs
composer install— should resolve cleanly with updated lock file.npm run up— container should build usingDockerfile-php84(PHP 8.4).npm run build— should complete without errors, including i18n extraction and translation download.Checklist
changelog.txtentry addedreadme.txtentry added