We use the scripts
section of composer.json
to define a bunch of common tasks like checking coding standards, running tests, and so on.
We then use these scripts inside our CI pipeline, which is really nice for being able to run the same checks both locally and up in CI.
On a recent project, I was asked to enable code coverage reports for our test script, and it made the overall runtime a bit slower. In fact, it was just slow enough in the CI runner, that it now ran longer than Composer's default 300-second process timeout. So the job failed.
No big deal! Inside my script definition, I can insert one line at the beginning: Composer\\Config::disableProcessTimeout
.
I've done this many times before, and it does exactly what you'd expect. But this time, it didn't work. I still hit the timeout.
The reason was that my Composer ci
script was calling another Composer script, and that nested script was timing out.
It's probably easier if I show you a sanitized chunk of my composer.json
:
{
"scripts": {
"ci": [
"Composer\\Config::disableProcessTimeout",
"@composer check",
"@composer test"
],
"check": [
"phpcs",
"phpstan"
],
"test": [
"phpunit --coverage-text"
]
}
}
When you call a script in a nested fashion like this, you need to disable the timeout in both the parent script and the nested script as well.
So in my case, I added Composer\\Config::disableProcessTimeout
as the first line of my test
script, and the problem was solved.
Composer does give you away to just globally disable timeouts for all scripts, but that feels too heavy-handed for me.
CI pipeline minutes cost money, and I want to be very selective when I want a job to run longer than expected.
Here to help,
Joel
P.S. Wish your CI was faster? We have a ton of experience with this. Let's talk.