The scheduled Update Psalm baseline workflow (.github/workflows/update-psalm-baseline.yml) has been failing on every run since around 2026-08-20, and the PRs it opens do not contain baseline changes.
What happens
-
composer run psalm:update-baseline runs psalm --threads=$(nproc) --update-baseline .... With more than one thread, Psalm 6 forks workers with pcntl_fork(), and the PHP shipped on the ubuntu-latest runner lists pcntl_* in disable_functions. Psalm dies:
Uncaught Error: Call to undefined function pcntl_fork() in .../vendor/vimeo/psalm/src/Psalm/Internal/Fork/ForkContext.php:85
Script psalm --threads=$(nproc) --update-baseline --set-baseline=tests/psalm-baseline.xml handling the psalm:update-baseline event returned with error code 1
(On the stable branches it is reported as pcntl_fork() is disabled by php configuration (disable_functions directive).)
-
The step has continue-on-error: true, so the job keeps going as if the baseline had been updated.
-
The previous step, composer require --dev nextcloud/ocp:dev-<branch>, had already rewritten composer.lock. peter-evans/create-pull-request is used without add-paths, so it commits everything that changed and opens a [branch] Update psalm-baseline.xml PR whose only content is the new nextcloud-deps/ocp reference in composer.lock (+4/−4). tests/psalm-baseline.xml is not touched.
-
Finally team-reviewers: server-backend fails with Reviews may only be requested from collaborators, which is what marks the run as failed.
Runs: https://github.com/LibreSign/libresign/actions/runs/33243943681 (2026-08-29), https://github.com/LibreSign/libresign/actions/runs/33178796997 (2026-08-28).
PRs produced this way, all changing only composer.lock: #8052, #8064, #8083, #8084, #8093 (merged) and #8118, #8119 (open).
Fix
The repository already handles the same problem elsewhere: psalm.yml sets ini-values: disable_functions= on setup-php (and so do the phpunit/behat/playwright/infection workflows). The baseline workflow only needs:
ini-values: disable_functions= in its setup-php step, so Psalm can fork;
add-paths: tests/psalm-baseline.xml in create-pull-request, so the composer.lock churn from the nextcloud/ocp install is never committed.
team-reviewers: server-backend is a separate decision (the team is not a collaborator of this repository); the run will stay red until it is removed or points to an existing team.
Verification on a fork
I ran the workflow on my fork with workflow_dispatch, with the fork's main/stable32/stable33/stable34 synced to upstream, once as-is and once with the two changes above (plus a test-only step that prints git status after Psalm, and the PR step disabled because the fork has no COMMAND_BOT_PAT):
- As-is (https://github.com/maia-andre/libresign/actions/runs/33266309373): Psalm crashed with
Call to undefined function pcntl_fork() in all four jobs, exactly as upstream.
- With the fix (https://github.com/maia-andre/libresign/actions/runs/33266307137): Psalm finished in all four jobs (
Baseline saved to tests/psalm-baseline.xml.). What was left modified after Psalm:
main: only composer.lock — the baseline is already current, so with add-paths the action would open no PR at all;
stable32, stable33: only tests/psalm-baseline.xml (the psalm-version header, since the file on those branches was last written by a different Psalm version);
stable34: composer.lock and the same one-line header change in tests/psalm-baseline.xml.
So after the fix the PRs contain only the baseline, and are only opened when it actually changed.
I'll open the PR for this.
The scheduled
Update Psalm baselineworkflow (.github/workflows/update-psalm-baseline.yml) has been failing on every run since around 2026-08-20, and the PRs it opens do not contain baseline changes.What happens
composer run psalm:update-baselinerunspsalm --threads=$(nproc) --update-baseline .... With more than one thread, Psalm 6 forks workers withpcntl_fork(), and the PHP shipped on theubuntu-latestrunner listspcntl_*indisable_functions. Psalm dies:(On the stable branches it is reported as
pcntl_fork() is disabled by php configuration (disable_functions directive).)The step has
continue-on-error: true, so the job keeps going as if the baseline had been updated.The previous step,
composer require --dev nextcloud/ocp:dev-<branch>, had already rewrittencomposer.lock.peter-evans/create-pull-requestis used withoutadd-paths, so it commits everything that changed and opens a[branch] Update psalm-baseline.xmlPR whose only content is the newnextcloud-deps/ocpreference incomposer.lock(+4/−4).tests/psalm-baseline.xmlis not touched.Finally
team-reviewers: server-backendfails withReviews may only be requested from collaborators, which is what marks the run as failed.Runs: https://github.com/LibreSign/libresign/actions/runs/33243943681 (2026-08-29), https://github.com/LibreSign/libresign/actions/runs/33178796997 (2026-08-28).
PRs produced this way, all changing only
composer.lock: #8052, #8064, #8083, #8084, #8093 (merged) and #8118, #8119 (open).Fix
The repository already handles the same problem elsewhere:
psalm.ymlsetsini-values: disable_functions=onsetup-php(and so do the phpunit/behat/playwright/infection workflows). The baseline workflow only needs:ini-values: disable_functions=in itssetup-phpstep, so Psalm can fork;add-paths: tests/psalm-baseline.xmlincreate-pull-request, so thecomposer.lockchurn from thenextcloud/ocpinstall is never committed.team-reviewers: server-backendis a separate decision (the team is not a collaborator of this repository); the run will stay red until it is removed or points to an existing team.Verification on a fork
I ran the workflow on my fork with
workflow_dispatch, with the fork'smain/stable32/stable33/stable34synced to upstream, once as-is and once with the two changes above (plus a test-only step that printsgit statusafter Psalm, and the PR step disabled because the fork has noCOMMAND_BOT_PAT):Call to undefined function pcntl_fork()in all four jobs, exactly as upstream.Baseline saved to tests/psalm-baseline.xml.). What was left modified after Psalm:main: onlycomposer.lock— the baseline is already current, so withadd-pathsthe action would open no PR at all;stable32,stable33: onlytests/psalm-baseline.xml(thepsalm-versionheader, since the file on those branches was last written by a different Psalm version);stable34:composer.lockand the same one-line header change intests/psalm-baseline.xml.So after the fix the PRs contain only the baseline, and are only opened when it actually changed.
I'll open the PR for this.