Disabling Composer timeout with nested scripts

Useful for long-running CI pipelines

Joel Clermont
Joel Clermont
2024-05-21

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.

Toss a coin in the jar if you found this helpful.
Want a tip like this in your inbox every weekday? Sign up below 👇🏼

Level up your Laravel skills!

Each 2-minute email has real-world advice you can use.