ci(windows): mirror gettext-win over HTTP instead of cloning it - #66
Conversation
Every php-sdk Windows build has died at the same line since ~2026-08-05:
[22/30] Downloading artifact gettext-win source from git ...
##[error]The action 'Download PHP sources' has timed out after 15 minutes.
spc's gettext-win artifact is an unshallowed 57 MB clone of
winlibs/gettext @ 0.18 (5x its libiconv-win sibling). The clone stalls
mid-packfile, and spc's git invocation carries -c http.lowSpeedLimit=1
-c http.lowSpeedTime=3600, so a 1-byte/sec trickle is tolerated for a
full hour rather than failing. The step budget always fires first.
Not a block and not bandwidth. Measured on the fleet node that runs
these jobs, 2026-09-18:
git ref advertisement (info/refs) HTTP 200 in 0.31s
winlibs/gettext tarball (29 MB) 4.2s @ 6.9 MB/s
libiconv-win tarball (5 MB) 1.2s @ 4.3 MB/s
The identical content comes over HTTP in four seconds while the clone
hangs past four minutes, so fetch the tarball and hand it to spc.
This is sound for a `type: git` artifact: --custom-url replaces the
artifact's source callback outright with a plain Url download
(ArtifactDownloader::applyCustomDownloads), so spc never needs a .git
tree. The codeload tarball has a single top-level gettext-0.18/ dir,
which spc's extractor strips, landing the layout the clone produced --
verified to contain the declared libintl_a.lib under
MSVC11/libintl_static/x64/Release/.
Downloaded to a file rather than passing the codeload URL directly
because spc names the archive basename($url) and the codeload path ends
in "/0.18" -- extensionless, which breaks archive detection.
Soft-fails: if the mirror download fails we warn and let spc attempt the
clone, which is no worse than today's unconditional behaviour.
libiconv-win is the same shape and the same latent risk, but it is
downloading fine today and is deliberately left alone.
Verified before push: PowerShell AST parse of the step is clean; the
block run verbatim from the file emits
--custom-url=gettext-win:file:///C:/.../gettext-win.tar.gz; curl reads
that URL back at the full 29,157,062 bytes; and spc's explode(':',v,2)
splits it to (gettext-win, file:///C:/...) with the drive colon intact.
|
ePHPm Preview — removed Preview deployment has been torn down. |
|
Validation build 35422511159 (
The run as a whole did not produce an artifact, but for an unrelated reason that this PR does not touch and was previously masked by the gettext hang: the build then stalled in OpenSSL. The node was healthy throughout (135 GB disk free, 22 GB RAM free, no ephemerd error; ephemerd only tore the runner down after GitHub timed the job out). That stall is a separate bug and gets its own investigation. Merging this on its own merits: it fixes the download step it targets, it is proven on hardware, and it soft-fails to the old behaviour if the mirror download ever fails. |
Every php-sdk Windows build has failed at the same line since roughly 2026-08-05 (the last shipped Windows asset):
Root cause
spc's
gettext-winartifact (config/pkg/lib/gettext-win.ymlin the fork, rc19):That is an unshallowed 57 MB clone — 5x its
libiconv-winsibling. It stalls mid-packfile, and spc's git invocation carries-c http.lowSpeedLimit=1 -c http.lowSpeedTime=3600, so a 1 byte/sec trickle is tolerated for a full hour instead of failing. The 15-minute step budget always fires first.It is not a block and not a bandwidth problem. Measured on the fleet node that actually runs these jobs (2026-09-18):
info/refs)winlibs/gettexttarball (29 MB)libiconv-wintarball (5 MB, control)The identical content arrives over HTTP in four seconds while the clone hangs past four minutes.
Note PR #64 did not cause this — it converted a silent 2-hour burn into a fast, visible failure, which is what made it diagnosable.
The fix
Fetch the tarball and hand it to spc via
--custom-url.This is sound for a
type: gitartifact:--custom-urlreplaces the artifact's source callback outright with a plainUrldownload (ArtifactDownloader::applyCustomDownloads), so spc never needs a.gittree. The codeload tarball carries a single top-levelgettext-0.18/dir which spc's extractor strips ("Unzip file with stripping top-level directory",ArtifactExtractor), landing the same layout the clone produced.Downloaded to a file rather than passing the codeload URL directly, because spc names the archive
basename($url)and the codeload path ends in/0.18— extensionless, which breaks archive detection.Soft-fails: if the mirror download fails, we warn and let spc attempt the clone. No worse than today.
Verification done before pushing
--custom-url=gettext-win:file:///C:/.../gettext-win.tar.gzcurlreads thatfile://URL back at the full 29,157,062 bytesexplode(':', $v, 2)splits it to(gettext-win, file:///C:/...)— the drive-letter colon surviveslibintl_a.libatMSVC11/libintl_static/x64/Release/Not yet verified by a real Windows build — that happens when this runs in CI.
Scope
libiconv-winis the sametype: gitshape and the same latent risk, but it downloads fine today, so it is deliberately left alone rather than churning a working path.