CI issues and fixes¶
This report documents the failures observed in GitHub Actions run 35693337542, the follow-up Test run 35705621385, and the fixes applied to this checkout.
Failure summary¶
| Job | Failure | Root cause | Fix |
|---|---|---|---|
| Ubuntu 22/24 build | memset, memcpy, and memcmp were not declared |
src/vendors/xilinx_xcf.cpp and src/vendors/xilinx_xcfp.cpp used C memory functions without including their standard header |
Added #include <cstring> to both translation units |
| Documentation | Cannot find source directory (.../openFPGALoader/doc) |
The documentation source moved to docs/doc, but the workflow still used the old doc path |
Replaced the old Sphinx job with a strict MkDocs build rooted at docs/ |
| Documentation deployment | Potential token permission failure after the build path was corrected | The workflow did not declare write permission for gh-pages and release operations |
Set read-only workflow permissions by default and write permissions only on the documentation and release jobs |
| Linux package test | Extraction target /tmp/pkg/ was not created |
tar -C /tmp/pkg/ was used without creating the directory |
Added mkdir -p /tmp/pkg |
| Windows MSYS2 clang64/ucrt64/mingw64 | CMake searched .../deploy and reported no CMakeLists.txt |
The MSYS2 packaging files moved one directory deeper under deploy/, but the relative paths were unchanged |
Updated the CMake source and license paths in deploy/scripts/msys2/PKGBUILD |
| macOS artifact upload | ArtifactService/CreateArtifact timed out after five retries |
The build and archive creation succeeded; the failure was in GitHub's artifact service | Updated the artifact action major version; remote rerun still requires repository Actions write access |
| Windows Docker cross-build | no matching manifest for windows(10.0.19045)/amd64 while pulling alpine:edge |
Docker Desktop was running the Windows-container engine, but this cross-build is an Alpine Linux image | Declared platform: linux/amd64, added a PowerShell engine preflight, reduced the Docker context with .dockerignore, and documented the WSL2/Linux-container requirement |
Follow-up failures from the latest Actions run¶
The later run exposed two independent regressions that were not covered by the first repair:
| Jobs | Failure | Root cause | Fix |
|---|---|---|---|
| macOS and MSYS2 clang64 | Clang rejected uint8_t buffer[length] = {} |
The SOJ code used variable-length arrays with initialization; this is accepted as a GCC extension but is ill-formed for Clang | Replaced SOJ and related diagnostic VLAs with zero-initialized std::vector<uint8_t> buffers and fixed the size_t diagnostic format string |
| Linux, macOS, and Windows cross-build checkout | Repository not found while fetching externals/libwdi |
.gitmodules contained the misspelled owner xsesion |
Corrected the submodule URL to https://github.com/xsession/libwdi.git |
The documentation job was also migrated from Sphinx to MkDocs. The new workflow
generates compatibility tables from the existing YAML data and runs
mkdocs build --strict, so broken internal documentation links fail CI.
Additional refactor regressions fixed¶
The review also found stale paths introduced by the same directory move:
- Debian packaging now reads
deploy/packaging/linux/debianand stages it asDEBIAN. - Windows installer packaging now mounts
deploy/packaging/windows. - Docker Linux and Windows deployment scripts now read firmware from
deploy/ise_programmer_bins. - Deployment documentation and release notes now use the moved paths.
- MkDocs documentation sources are now rooted at
docs/, with generated compatibility tables kept in sync from the YAML data. - The Intel HEX regression test no longer depends on a hard-coded Windows developer path.
Workflow maintenance¶
The first-party Actions references were updated to the currently available major versions at the time of this repair:
actions/checkout@v7actions/setup-python@v7actions/upload-artifact@v7actions/download-artifact@v8
A dedicated source-test job now runs the Intel HEX regression test and gates releases.
Deployment packaging review¶
The deployment scripts had three packaging gaps beyond the original workflow failures:
build-linux-deb.shwas tied to the Docker staging directory and hard-coded version1.1.2, so the workflow could not produce matrix-safe Debian installers from its native staging tree.build-windows-installer.shexpected an obsolete generated XPCU driver path and invoked Inno Setup without first building thelibwdiandxilinx-usb-driversubmodules.- The binary workflow's Windows cross job used a second, incomplete native MinGW packaging path instead of the tested Linux-container Compose build.
The repaired pipeline now derives package versions from the built executable,
uses Git release tags in CMake when available, creates matrix-unique .deb
names, builds the Windows executable through
docker-compose.cross-windows.yml, builds the external XPCU package through
the submodules' Docker workflow, verifies checksums, and produces a complete
Inno Setup installer. MkDocs deployment is isolated in
.github/workflows/deploy-docs.yml and publishes the generated site/ tree to
gh-pages.
Validation performed¶
The following checks passed in the available runtime:
- Both workflow YAML files parse successfully.
- All deployment shell scripts pass
bash -n. - MkDocs compatibility generation and
mkdocs build --strictpass. - Both formerly failing Xilinx translation units pass GNU C++17
-Wall -Wextra -Wpedantic -fsyntax-only; the source no longer contains the Clang-rejected SOJ VLAs. - Intel HEX regression tests pass.
- Moved-directory path consistency checks pass.
- Workflow packaging definitions include Linux
.deb, Windows portable ZIP, XPCU driver ZIP, and Windows installer artifacts.
A full CMake build could not be executed in this environment because CMake is not installed and the managed runtime blocks package installation. The corrected workflow should therefore be validated by a new push or pull request run.
Remaining external limitation¶
The original macOS artifact failure could not be rerun from this session: GitHub returned HTTP 403 (Resource not accessible by integration) for the rerun request. No remote branch or pull request was created; all fixes are included in this local repository and in the accompanying archive.
SOJ source review¶
The SPI-over-JTAG review and source-level fixes are documented in
docs/SOJ_REVIEW.md The highest-risk defects were an
8-byte SOJ v2 probe written into 7-byte buffers, v2 detection that only worked
with verbose logging, duplicated multi-device JTAG padding, command bytes being
resent during status polling, and USER4 being accepted as an SPI fallback.
2026-09-30 deploy hardening audit¶
- Fixed Linux
.debCI preview failure caused bydpkg-deb --contents | headunderpipefail. - Made the Windows cross container invoke the bind-mounted build script through
bash. - Removed nested output bind mounts from Windows and Linux Compose deployment paths.
- Fixed CMake semantic-tag matching and synchronized the source fallback with v1.1.6.
- Re-enabled the documented
cross-with-driverDocker stage and fixed.dockerignore. - Pinned deployment images and restricted GitHub workflow write permission to release publishing.
- Made missing upload artifacts fatal and made Debian udev maintainer scripts preserve user overrides.
2026-10-01: act cross-build runtime stall after container creation¶
After the Alpine image build completed, docker compose run could appear to hang
immediately after creating the run container on Docker Desktop for Windows. The
write-heavy CMake build and install trees were on the Windows bind mount. They are
now stored in a named /work Docker volume, Compose TTY allocation is disabled in
CI/act, the redundant pull_policy: build was removed, and the wrapper emits
explicit stage checkpoints. Final packages still land in
dist/docker-windows on the host.
Windows checkout CRLF broke Docker runtime shell scripts¶
Symptom:
: invalid option nameocker-cross-windows.sh: line 2: set: pipefail
Cause: Git for Windows converted deploy/scripts/docker-cross-windows.sh to CRLF, so Linux Bash parsed pipefail\r as the option name. The repository previously had no .gitattributes.
Fix: add .gitattributes with *.sh text eol=lf and LF rules for Linux build metadata. Existing Windows worktrees require a one-time line-ending normalization.
2026-10-01: integrated XPCU driver packaging¶
The Windows release now treats the compiled Xilinx Platform Cable driver bundle as
one canonical package. The libwdi/XPCU build runs inside windows-cross, verifies
xilinx-platform-cable-windows.zip, and mounts it into the cross-build container.
The portable openFPGALoader ZIP embeds the archive and checksum under
share/openFPGALoader/drivers/. The installer consumes that embedded archive, so
there is no second driver build and no stale windows-xpcu-drivers dependency.
The XPCU Compose runtime mounts are parameterized with daemon-visible host paths.
This fixes the local act failure where the images built successfully but both
libwdi runtime services exited 127 because /src was mounted from the runner-only
/mnt/<drive>/... path instead of Docker Desktop's host-visible path.
2026-10-01: Inno Setup bind-mount access denied¶
The Windows installer job reached Inno Setup only after successfully verifying the
portable Windows archive and its embedded XPCU/libwdi driver bundle. Inno Setup then
failed with Error 5: Access denied while attempting to create its temporary
openFPGALoader-<version>-win64-setup.e32.tmp under Z:\dist.
The pinned amake/innosetup image runs Wine as the non-root xclient user, while
the GitHub workspace is a host bind mount. Inputs were readable, but the compiler
could not create its temporary executable in the mounted output directory.
Fix: build-windows-installer.sh creates a short-lived Docker named volume, makes
it writable, passes MyOutputDir=Z:\out to Inno Setup, mounts the host dist tree
read-only for installer inputs, and copies only the completed setup EXE back to the
host via an Alpine helper. The volume is always removed by a shell trap.