Make WordPress Core

Opened 6 weeks ago

Closed 10 days ago

Last modified 10 days ago

#65745 closed defect (bug) (fixed)

"Start Docker environment" is not retried, and start.js discards the failure

Reported by: adrianmoldovanwp Owned by: lancewillett
Priority: normal Milestone: 7.2
Component: Build/Test Tools Version: trunk
Severity: normal Keywords: has-patch
Cc: Focuses:

Description

Start Docker environment failed in 85 runs across 69 branches in 30 days. Of 92 sampled failures: 63 Docker Hub, 20 Packagist, 9 undetermined.

start.js never checks the exit status of docker compose up, so a failed pull does not fail the step:

LOCAL_PHP=this-tag-does-not-exist npm run env:start; echo $?   # 0

docker.js has the same defect: process.exit( returns.status ) exits 0 when Docker cannot be spawned, because status is then null.

Commit d0a30472b0 added an env:pull retry, but only to reusable-phpunit-tests-v3.yml, and it covers image pulls only. env:start also runs composer update -W,

which reaches repo.packagist.org. Example: run 30353258811, where the pull step passed and Start Docker environment then failed with curl error 7 while downloading https://repo.packagist.org/packages.json.

Possible fix:


The retry has to stay in the workflow YAML. 30 branches (4.1-7.0) call these reusable workflows @trunk but check out their own tools/local-env/ and package.json, so a retry in trunk's scripts would only protect trunk.

6.9 and 7.0 ship an identical start.js and need the same backport.

Change History (33)

This ticket was mentioned in PR #12735 on WordPress/wordpress-develop by @adrianmoldovanwp.


6 weeks ago
#1

  • Keywords has-patch added

tools/local-env/scripts/start.js runs docker compose up through spawnSync and never inspects the result. A failed pull therefore does not fail the script. Execution continues into composer update -W with containers that may not exist, and the error surfaces later and in the wrong step.

tools/local-env/scripts/docker.js has the same class of defect. It calls process.exit( returns.status ), and status is null when Docker cannot be spawned. process.exit( null ) exits 0, so npm run env:pull reports success when the Docker CLI is missing.

This PR checks and propagates the status in both files. It is deliberately kept to that one change so that it can be backported.

## Backport

start.js and docker.js on the 6.8, 6.9 and 7.0 branches carry the same defect. Branches 6.7 and earlier run these commands through execSync, which throws on a non-zero exit, so they are not affected.

Branch start.js docker.js
4.1 - 6.7 not affected (execSync) not affected (execSync)
6.8 affected affected
6.9 affected affected
7.0 affected affected

## Testing instructions

Reproduce the discarded status. Before this change the pull fails and the exit code is 0. After it, the exit code is 1.

LOCAL_PHP=this-tag-does-not-exist npm run env:start; echo $?

Reproduce the docker.js defect. Before this change the exit code is 0. After it, the exit code is 1.

env PATH=/var/empty $(which node) ./tools/local-env/scripts/docker.js pull; echo $?

Confirm a normal start still works.

npm run env:stop && docker compose down -v
npm run env:start && npm run env:install

Ctrl+C during npm run env:logs still exits without an npm error block.

## Use of AI Tools

AI assistance: Yes
Tool(s): Claude Code
Model(s): Claude Opus 5
Used for: Investigating the CI failures, writing the patch, and iterative code review. The behaviour described above was reproduced and verified locally before and after the change.

This ticket was mentioned in PR #12736 on WordPress/wordpress-develop by @adrianmoldovanwp.


6 weeks ago
#2

Start Docker environment failed in 85 runs across 69 branches over 30 days. That spread rules out contributor code. Of 92 sampled failures, 63 were Docker Hub and 20 were repo.packagist.org.

env:pull was already retried in reusable-phpunit-tests-v3.yml. This PR extends that to the five remaining workflows, and also retries npm run env:start, which runs composer update -W in addition to starting the containers. Retrying only the pull leaves the Packagist failures uncovered.

## Why the retry stays in the workflows

30 released branches (4.1 through 7.0) call these reusable workflows as WordPress/wordpress-develop/.github/workflows/reusable-*.yml@trunk, and each job checks out its own branch. The workflow body comes from trunk. tools/local-env/ and package.json come from the released branch.

A retry added to trunk's start.js would therefore protect trunk and nothing else. The same constraint rules out a composite action and any new npm script: only env:pull and env:start exist in package.json on all 30 calling branches.

Keeping the retry in CI also keeps it away from contributors. Someone working offline gets an immediate error instead of waiting through the backoff.

The retry is bounded at three attempts with a 10s and 20s backoff, and the underlying error is printed on every attempt, so a bad tag or a malformed Compose file still fails loudly.

## The .env change

ensure_env_file() moves the .env bootstrap into utils.js and calls it from start.js, docker.js and install.js.

The new pull step runs before start.js has created .env, so env:pull resolved image tags from the Compose defaults while docker compose up resolved them from .env. On trunk that means mysql:latest is pulled and then mysql:9.7 is pulled again.

The synchronous copy also removes a race. The previous copyFile call was asynchronous, and dotenv.config() ran on the next line, so on a fresh clone the first run could read a .env that had not been written yet.

## Stacked on

The first commit is #12735, which propagates the exit status of docker compose up. Review that one first. The retry is only fully effective once a failed up actually fails the step.

## Testing instructions

Confirm the retry is bounded and reports the real error. Point the environment at a tag that does not exist and run the loop from the workflow. It should make three attempts, back off for 10 and 20 seconds, print the registry error each time, and exit 1.

LOCAL_PHP=this-tag-does-not-exist npm run env:pull

Confirm a normal cold start still works and is not slower.

npm run env:stop && docker compose down -v
npm run env:pull && npm run env:start && npm run env:install

Confirm env:pull and env:start now resolve the same image tags. Delete .env, run npm run env:pull, and check that .env exists afterwards and that docker compose up does not pull a second database image.

Local Docker Environment, PHPUnit Tests and End-to-end Tests all exercise this step across large matrices.

## Note for reviewers

These six workflows are consumed at @trunk by every released branch, so this change takes effect on all 30 of them as soon as it is committed. There is no staged rollout.

## Use of AI Tools

AI assistance: Yes
Tool(s): Claude Code
Model(s): Claude Opus 5
Used for: Investigating the CI failures, writing the patch, and iterative code review. The cross-branch constraints described above were checked against every calling branch, and the behaviour was verified locally.

@lancewillett commented on PR #12735:


6 weeks ago
#3

This change looks correct, I'd like a 2nd review from a core committer on the backports since that will involve SVN commits to 7.0, 6.9, and 6.8. CC @aaronjorbin @desrosj @johnbillion

@adrianmoldovanwp commented on PR #12736:


4 weeks ago
#4

https://github.com/WordPress/wordpress-develop/pull/12937 partially changed the scope so I decided to fold the changes into https://github.com/WordPress/wordpress-develop/pull/12735 instead for easier landing. Both changes touch only tools/ and share Trac ticket 65745, so they are now on one branch.

Closing this one.

@adrianmoldovanwp commented on PR #12735:


4 weeks ago
#5

Tested with head a88479c

Confirmed failed image pulls and a missing Docker executable exit non-zero. SIGTERM exits non-zero, SIGINT remains clean for interactive commands, and a normal environment start and install > succeeded

The affected code shape was also verified on 6.8, 6.9, and 7.0.

Good to land.

@lancewillett this needs a new round of review, I just folded https://github.com/WordPress/wordpress-develop/pull/12736 into it.

@lancewillett commented on PR #12735:


11 days ago
#6

Re-reviewed and tested head 87734e38efc36e12526bbfed80510fd827497c91 after the Composer option-parsing follow-up and trunk refresh.

Confirmed:

  • Missing Docker exits non-zero without retrying
  • Failed pulls and starts retry three times, then exit non-zero
  • Non-registry Composer commands run once
  • .env is created before Compose runs
  • A cold start and install succeed

No blocking issues. Looks good to land.

#7 @lancewillett
11 days ago

  • Milestone Awaiting Review7.2
  • Owner set to lancewillett
  • Status newaccepted

#8 @lancewillett
11 days ago

In 63416:

Build/Test Tools: Correct local environment failure handling.

start.js and docker.js can report success when Docker Compose fails to start, exits unsuccessfully, or is killed. Propagate failures while preserving SIGINT as cancellation for interactive commands.

Create .env synchronously before each local environment script loads it. This prevents Docker Compose from resolving image tags before the configuration exists.

Developed in: https://github.com/WordPress/wordpress-develop/pull/12735

Props adrianmoldovanwp.
See #65745.

#9 @lancewillett
11 days ago

In 63417:

Build/Test Tools: Retry local environment registry commands.

Docker Hub and Packagist failures can interrupt image pulls, container startup, and Composer dependency operations. Retry those commands up to three times, waiting 10 and 20 seconds between attempts.

Stop immediately when a command is killed by a signal or cannot start. Run Composer commands that do not contact a registry once.

Developed in: https://github.com/WordPress/wordpress-develop/pull/12735

Props adrianmoldovanwp.
See #65745.

@lancewillett commented on PR #12735:


11 days ago
#10

https://core.trac.wordpress.org/changeset/63416 and https://core.trac.wordpress.org/changeset/63417 for trunk

I'll proceed to backport r63416 to older branches once I have a 2nd core committer review.

@lancewillett commented on PR #12735:


11 days ago
#11

Trunk landed in two revisions:

  • r63416 contains the backportable bug fixes.
  • r63417 adds retry behavior and will remain on trunk because it is an enhancement rather than a defect fix.

For the r63416 backports, the planned scope is:

Branch Changes
7.1 Exit-status fix
7.0 Exit-status and .env fixes
6.9 Exit-status fix
6.8 Exit-status and .env fixes
6.7 Optional .env fix only

The adapted backports will record mergeinfo for r63416. I’m keeping Trac #65745 open until the agreed backports land.

@johnbillion commented on PR #12735:


11 days ago
#12

Planned scope back to 6.7 looks good. Let's do this via a PR for each branch though so anything unexpected in CI gets caught.

This ticket was mentioned in PR #13350 on WordPress/wordpress-develop by @adrianmoldovanwp.


10 days ago
#13

Backport of r62871 to the 6.7 branch, from #12697.

This ticket was mentioned in PR #13351 on WordPress/wordpress-develop by @adrianmoldovanwp.


10 days ago
#14

Backport of r63416 to the 6.9 branch, from #12735. Only the exit-status half applies: this branch already copies .env synchronously, from r62871.

This ticket was mentioned in PR #13352 on WordPress/wordpress-develop by @adrianmoldovanwp.


10 days ago
#15

Backport of r63416 and r62871 to the 7.0 branch, from #12735 and #12697.

This ticket was mentioned in PR #13353 on WordPress/wordpress-develop by @adrianmoldovanwp.


10 days ago
#16

Backport of r63416 and r62871 to the 6.8 branch, from #12735 and #12697.

This ticket was mentioned in PR #13354 on WordPress/wordpress-develop by @adrianmoldovanwp.


10 days ago
#17

Backport of r63416 to the 7.1 branch, from #12735. Only the exit-status half applies: this branch already copies .env synchronously, from r62871.

@adrianmoldovanwp commented on PR #12735:


10 days ago
#18

Planned scope back to 6.7 looks good. Let's do this via a PR for each branch though so anything unexpected in CI gets caught.

Opened backport PRs:

PR Base Backports

| --- | --- | --- |
| #13350 | 6.7 | r62871 |
| #13353 | 6.8 | r63416 + r62871 |
| #13351 | 6.9 | r63416 |
| #13352 | 7.0 | r63416 + r62871 |
| #13354 | 7.1 | r63416 |


6.7 has no exit-status defect: docker.js there uses execSync, which throws. 6.9 and 7.1 already carry
r62871, so they take only the exit-status half of r63416.

@lancewillett commented on PR #12735:


10 days ago
#19

@adimoldovan Thanks for the PRs; I'll review, monitor, and land these today

#20 @lancewillett
10 days ago

In 63421:

Build/Test Tools: Correct local environment failure handling.

Merges [63416] to the 7.1 branch.

Developed in: https://github.com/WordPress/wordpress-develop/pull/13354

Reviewed by: johnbillion.
Props adrianmoldovanwp.
See #65745.

@lancewillett commented on PR #13354:


10 days ago
#21

Committed to the 7.1 branch in r63421.

@desrosj commented on PR #12735:


10 days ago
#22

It may be worthwhile to task an LLM with analyzing the older numbered branches to create a list of the build tool-related changes that are missing from each. I believe the last time we backported a number of improvements to the local environment and build tools was ~3 years ago now.

Ideally these branches are all as consistent as possible. It used to take a lot of manual work. But AI can probably handle that pretty easily and doing that now will help us going forward by limiting how much trunk diverges from these old branches.

#23 @lancewillett
10 days ago

In 63422:

Build/Test Tools: Correct local environment failure handling.

Merges [62871] and [63416] to the 7.0 branch.

Developed in: https://github.com/WordPress/wordpress-develop/pull/13352

Reviewed by: johnbillion.
Props jonsurrell, lucasbustamante, mukesh27, adrianmoldovanwp.
See #65745.

@lancewillett commented on PR #13352:


10 days ago
#24

Committed to the 7.0 branch in r63422.

#25 @lancewillett
10 days ago

In 63423:

Build/Test Tools: Correct local environment failure handling.

Merges [63416] to the 6.9 branch.

Developed in: https://github.com/WordPress/wordpress-develop/pull/13351

Reviewed by: johnbillion.
Props adrianmoldovanwp.
See #65745.

@lancewillett commented on PR #13351:


10 days ago
#26

Committed to the 6.9 branch in r63423.

#27 @lancewillett
10 days ago

In 63424:

Build/Test Tools: Correct local environment failure handling.

Merges [62871] and [63416] to the 6.8 branch.

Developed in: https://github.com/WordPress/wordpress-develop/pull/13353

Reviewed by: johnbillion.
Props jonsurrell, lucasbustamante, mukesh27, adrianmoldovanwp.
See #65745.

@lancewillett commented on PR #13353:


10 days ago
#28

Committed to the 6.8 branch in r63424.

#29 @lancewillett
10 days ago

In 63425:

Build/Test Tools: Copy local environment configuration synchronously.

Merges [62871] to the 6.7 branch.

Developed in: https://github.com/WordPress/wordpress-develop/pull/13350

Reviewed by: johnbillion.
Props jonsurrell, lucasbustamante, mukesh27, adrianmoldovanwp.
See #65745.

@lancewillett commented on PR #13350:


10 days ago
#30

Committed to the 6.7 branch in r63425.

@lancewillett commented on PR #12735:


10 days ago
#31

Committed to trunk in r63416 and [r63417](https://core.trac.wordpress.org/
changeset/63417).

Branch commits:

#32 @lancewillett
10 days ago

  • Resolutionfixed
  • Status acceptedclosed
  • Versiontrunk

Committed to trunk in [63416] and [63417].

Merged to the release branches:

All planned branch commits are complete.
Closing as fixed.

Note: See TracTickets for help on using tickets.