The retry added for the flaky Docker OpenSSH-server tests was a no-op.
automake generates the recheck target only in the directory that defines
TESTS, so libssh2 has it in tests/Makefile but not at the top level. Every
flaky run ended with "No rule to make target 'recheck'" twice and failed
the job on the first transient error. Run recheck in tests/ instead.
Also correct the description of the race. The handshake fails with -43,
which is LIBSSH2_ERROR_SOCKET_RECV rather than a banner timeout:
docker-proxy binds the published port as soon as the container starts, so
connect() succeeds and sshd resets the connection because it is not
listening inside the container yet. That is why the fixture cannot recover
on its own, as its retry loop only covers connect(), which never fails
here.
Cap the test parallelism at the runner's CPU count. "make -j" is
unbounded, and the failing runs started around 20 containers at once on a
four-CPU runner, which is what starves sshd of the time it needs to come
up. Every observed failure was a single random test out of 46 inside that
burst.
A genuine failure is still retried twice and still fails the job.
The libssh2 integration tests start a fresh OpenSSH-server container per
test with "docker run -d -p 22" and then immediately open the SSH
connection. Docker maps the port as soon as the container starts, so the
TCP connect succeeds before sshd inside the container is ready to send its
banner, and the handshake fails with "Failed getting banner" (-43). This
shows up as an intermittent failure of a single test, most often
test_read, on unrelated pull requests.
Fall back to "make recheck" when "make check" fails. The automake parallel
test harness re-runs only the tests that did not pass, so a transient
container-readiness race no longer fails the job while a genuine failure
still does.
GitHub Actions now emits "Node.js 20 actions are deprecated" warnings:
actions are forced to Node.js 24 by default starting 2026-06-16, and
Node.js 20 is removed from the runners on 2026-09-16. Update every
JavaScript action referenced by the workflows and the local composite
actions to the lowest release that runs on Node.js 24:
actions/checkout v4 -> v5
actions/checkout (SHA pin) v4.1.7 -> v5
actions/upload-artifact v4 -> v6 (v5 still Node.js 20)
actions/download-artifact v4 -> v7 (v5/v6 still Node.js 20)
actions/cache[/restore|/save] v4 -> v5
actions/setup-python v5 -> v6
actions/github-script v7 -> v8
docker/setup-buildx-action v3 -> v4
docker/build-push-action v5 -> v7 (v6 still Node.js 20)
docker/login-action v3 -> v4
microsoft/setup-msbuild v2 -> v3
open-watcom/setup-watcom v0 -> v1
Actions already running on Node.js 24 (jwlawson/actions-setup-cmake,
shogo82148/actions-setup-perl, msys2/setup-msys2, dorny/paths-filter)
are left unchanged. These bumps are runtime-only; no workflow uses an
input or output removed by the new majors, and v4-format artifacts
remain compatible across the upload v6 / download v7 backends.
Something broke in the actions/download-artifact action and it is not preserving symbolic links. It didn't get a new release so my guess is that something was updated in the node environment or in npm. This is a future proof solution to preserve the fs structure between upload and download.