Skip to content

Build

Build #642

Workflow file for this run

name: Build
# Build + package (cpack) on each platform, uploaded as workflow
# artifacts. This does NOT install or run anything -- see test.yml, which
# runs the three regression suites.
#
# (This header used to say that installing and running the GUI apps needed
# "a lot more complexity than a build-and-package health check warrants".
# That turned out to be `apt install xvfb` plus letting the app wrapper
# start its own services, so test.yml does it now. The parser and dialog
# suites need neither a display nor services and run on every push in
# about three minutes.)
# Packaging itself needs neither: cpack just archives already-built
# binaries, no display involved. The goal is early, continuous signal on
# "does this even compile (and package) here", especially for platforms
# nobody is routinely building on locally.
#
# RPM packages built here are real .rpm artifacts, but incomplete ones --
# CPACK_RPM_PACKAGE_REQUIRES (the RPM equivalent of the existing
# CPACK_DEBIAN_PACKAGE_DEPENDS) isn't set yet, so the package won't
# auto-pull its runtime deps (apache2 equivalent, mosquitto, wx python
# bindings, ...) the way the .deb does. Worth fixing before treating
# these as real release artifacts, not before treating them as "does
# cpack's RPM generator work at all here" signal.
#
# Target platforms and why:
# - Debian: what the primary maintainer actually develops on.
# - Ubuntu: most popular desktop/CI Linux distro.
# - RHEL family: what a lot of institutional/cluster environments run.
# GitHub Actions has no real RHEL runner (needs a subscription), so
# this uses Rocky Linux -- a bug-for-bug free rebuild of RHEL from
# the same sources, the standard stand-in for "does this work on
# RHEL" in CI that doesn't have a Red Hat subscription to spend.
# - WSL2: NOT a separate job. WSL2 runs a real Linux kernel with a real
# distro userland (Ubuntu by default) on top of it -- there's no
# separate "WSL2 build" to test, the Ubuntu/Debian jobs below already
# cover it directly. The one WSL2-relevant wrinkle, filename
# case-collisions (#40), is actually a non-issue for WSL2 specifically
# (its ext4-backed filesystem is case-sensitive like any other Linux
# disk) -- it only bites on a native-Windows checkout or a default
# case-insensitive macOS volume.
# - macOS: tracks GitHub #3 (currently expected to fail -- see the job
# below for why).
on:
push:
branches: [main]
pull_request:
branches: [main]
workflow_dispatch:
inputs:
only:
description: "Run just this job (debian, vendored-inventor, ubuntu, rocky, fedora, macos, windows); empty runs all"
required: false
default: ""
# One run per branch. Without this every push starts a full run and none
# of them cancel the older ones, so a run of quick pushes leaves a dozen
# stale runs competing for the same runners -- which is exactly what
# happened on 2026-09-23: nine pushes in a day, eleven jobs each, and CI
# stopped completing anything for six hours. A superseded run tells you
# nothing a newer one will not.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
debian:
if: ${{ github.event_name != 'workflow_dispatch' || inputs.only == '' || inputs.only == 'debian' }}
name: Debian (apt, containerized)
runs-on: ubuntu-latest
# Bounded so a hung job cannot hold a runner slot for GitHub's
# 6-hour default; see the concurrency note above.
timeout-minutes: 90
container: debian:trixie
steps:
- name: Install build dependencies
run: |
apt-get update
apt-get install -y \
build-essential gfortran cmake ninja-build \
libwxgtk3.2-dev libxerces-c-dev libgl-dev libglu1-mesa-dev \
libgtk-3-dev libx11-dev libice-dev libxt-dev libjpeg-dev \
libmosquitto-dev mosquitto-dev libaprutil1-dev mosquitto git dpkg-dev file libssh-dev libssl-dev \
python3 libcoin-dev libegl-dev libxc-dev libeigen3-dev
- uses: actions/checkout@v4
- name: Configure
run: cmake -G Ninja -B build-cmake -DECCE_REQUIRE_LIBSSH=ON
- name: Build
# -k 0: report every failing file, not only the first few.
run: cmake --build build-cmake -- -k 0
- name: Package
working-directory: build-cmake
run: cpack -G DEB
# ecce-qm is in the client package, stripped, and gives ORCA's energies.
- name: ecce-qm in the package
run: |
d=$(mktemp -d)
dpkg-deb -x build-cmake/ecce-client*.deb "$d"
q=$(find "$d" -path '*/bin/ecce-qm')
test -n "$q"
file "$q"
python3 tests/qm/package_check.py "$q" "$(dirname "$q")/../data/admin/basissets" --max-mb 40
- uses: actions/upload-artifact@v4
with:
name: ecce-debian-trixie-deb
path: build-cmake/*.deb
# Build only, no packaging: keeps the vendored Inventor core
# (-DECCE_USE_COIN=OFF, #166) compiling for the one release it stays a
# fallback.
vendored-inventor:
if: ${{ github.event_name != 'workflow_dispatch' || inputs.only == '' || inputs.only == 'vendored-inventor' }}
name: Debian, vendored Inventor viewer (build only)
runs-on: ubuntu-latest
timeout-minutes: 90
container: debian:trixie
steps:
- name: Install build dependencies
run: |
apt-get update
apt-get install -y \
build-essential gfortran cmake ninja-build python3 \
libwxgtk3.2-dev libxerces-c-dev libgl-dev libglu1-mesa-dev \
libgtk-3-dev libx11-dev libice-dev libxt-dev libjpeg-dev \
libmosquitto-dev mosquitto-dev libaprutil1-dev mosquitto git dpkg-dev file libssh-dev
- uses: actions/checkout@v4
- name: Configure
run: cmake -G Ninja -B build-oiv -DECCE_USE_COIN=OFF -DECCE_REQUIRE_LIBSSH=ON
- name: Build
run: cmake --build build-oiv
ubuntu:
if: ${{ github.event_name != 'workflow_dispatch' || inputs.only == '' || inputs.only == 'ubuntu' }}
name: Ubuntu (apt)
runs-on: ubuntu-latest
# Bounded so a hung job cannot hold a runner slot for GitHub's
# 6-hour default; see the concurrency note above.
timeout-minutes: 90
steps:
- uses: actions/checkout@v4
- name: Install build dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
build-essential gfortran cmake ninja-build \
libwxgtk3.2-dev libxerces-c-dev libgl-dev libglu1-mesa-dev \
libgtk-3-dev libx11-dev libice-dev libxt-dev libjpeg-dev \
libmosquitto-dev mosquitto-dev libaprutil1-dev mosquitto git dpkg-dev libssh-dev libssl-dev \
python3 libcoin-dev libegl-dev libxc-dev libeigen3-dev
- name: Configure
run: cmake -G Ninja -B build-cmake -DECCE_REQUIRE_LIBSSH=ON
- name: Build
# -k 0: report every failing file, not only the first few.
run: cmake --build build-cmake -- -k 0
- name: Package
working-directory: build-cmake
run: cpack -G DEB
# ecce-qm is in the client package, stripped, and gives ORCA's energies.
- name: ecce-qm in the package
run: |
d=$(mktemp -d)
dpkg-deb -x build-cmake/ecce-client*.deb "$d"
q=$(find "$d" -path '*/bin/ecce-qm')
test -n "$q"
file "$q"
python3 tests/qm/package_check.py "$q" "$(dirname "$q")/../data/admin/basissets" --max-mb 40
- uses: actions/upload-artifact@v4
with:
name: ecce-ubuntu-latest-deb
path: build-cmake/*.deb
rocky:
if: ${{ github.event_name != 'workflow_dispatch' || inputs.only == '' || inputs.only == 'rocky' }}
name: Rocky Linux (dnf, RHEL family, containerized)
runs-on: ubuntu-latest
# Bounded so a hung job cannot hold a runner slot for GitHub's
# 6-hour default; see the concurrency note above.
timeout-minutes: 90
container: rockylinux:9
steps:
- name: Install build dependencies
run: |
dnf install -y epel-release 'dnf-command(config-manager)'
# ninja-build and a few -devel packages live in the CodeReady
# Builder repo, not EPEL itself -- EPEL's own release package
# prints a reminder about this ("Many EPEL packages require the
# CRB repository... /usr/bin/crb enable") but doesn't enable it
# automatically.
dnf config-manager --set-enabled crb
dnf install -y \
gcc gcc-c++ gcc-gfortran make cmake ninja-build git rpm-build \
wxGTK-devel xerces-c-devel \
mesa-libGL-devel mesa-libGLU-devel \
gtk3-devel libX11-devel libICE-devel libXt-devel libjpeg-turbo-devel \
mosquitto-devel apr-util-devel mosquitto libssh-devel openssl-devel \
Coin4-devel mesa-libEGL-devel python3
# actions/checkout doesn't work reliably inside an arbitrary
# container image (no git-installed-as-a-prereq guarantee, and the
# container user often isn't the checkout action's expected uid) --
# install git above first, then check out manually instead.
- name: Check out source
run: |
git config --global --add safe.directory "$GITHUB_WORKSPACE"
git clone --depth 1 --branch "${GITHUB_REF_NAME}" \
"https://github.com/${GITHUB_REPOSITORY}.git" "$GITHUB_WORKSPACE" \
|| git clone --depth 1 "https://github.com/${GITHUB_REPOSITORY}.git" "$GITHUB_WORKSPACE"
- name: Configure
working-directory: ${{ github.workspace }}
run: cmake -G Ninja -B build-cmake -DECCE_REQUIRE_LIBSSH=ON
- name: Build
working-directory: ${{ github.workspace }}
# -k 0: report every failing file, not only the first few.
run: cmake --build build-cmake -- -k 0
- name: Package
working-directory: ${{ github.workspace }}/build-cmake
run: cpack -G RPM
- name: ecce-qm in the package
run: |
d=$(mktemp -d)
for f in ${{ github.workspace }}/build-cmake/ecce-client*.rpm; do (cd "$d" && rpm2cpio "$OLDPWD/$f" | cpio -idm 2>/dev/null); done
q=$(find "$d" -path '*/bin/ecce-qm')
test -n "$q"
file "$q"
python3 tests/qm/package_check.py "$q" "$(dirname "$q")/../data/admin/basissets" --max-mb 40
- uses: actions/upload-artifact@v4
with:
name: ecce-rockylinux9-rpm
path: build-cmake/*.rpm
fedora:
if: ${{ github.event_name != 'workflow_dispatch' || inputs.only == '' || inputs.only == 'fedora' }}
name: Fedora (dnf, containerized)
runs-on: ubuntu-latest
# Bounded so a hung job cannot hold a runner slot for GitHub's
# 6-hour default; see the concurrency note above.
timeout-minutes: 90
container: fedora:latest
steps:
- name: Install build dependencies
run: |
dnf install -y \
gcc gcc-c++ gcc-gfortran make cmake ninja-build git rpm-build \
wxGTK-devel xerces-c-devel \
mesa-libGL-devel mesa-libGLU-devel \
gtk3-devel libX11-devel libICE-devel libXt-devel libjpeg-turbo-devel \
mosquitto-devel apr-util-devel mosquitto libssh-devel openssl-devel \
Coin4-devel mesa-libEGL-devel python3 libxc-devel eigen3-devel
- name: Check out source
run: |
git config --global --add safe.directory "$GITHUB_WORKSPACE"
git clone --depth 1 --branch "${GITHUB_REF_NAME}" \
"https://github.com/${GITHUB_REPOSITORY}.git" "$GITHUB_WORKSPACE" \
|| git clone --depth 1 "https://github.com/${GITHUB_REPOSITORY}.git" "$GITHUB_WORKSPACE"
- name: Configure
working-directory: ${{ github.workspace }}
run: cmake -G Ninja -B build-cmake -DECCE_REQUIRE_LIBSSH=ON
- name: Build
working-directory: ${{ github.workspace }}
# -k 0: report every failing file, not only the first few.
run: cmake --build build-cmake -- -k 0
- name: Package
working-directory: ${{ github.workspace }}/build-cmake
run: cpack -G RPM
- name: ecce-qm in the package
run: |
d=$(mktemp -d)
for f in ${{ github.workspace }}/build-cmake/ecce-client*.rpm; do (cd "$d" && rpm2cpio "$OLDPWD/$f" | cpio -idm 2>/dev/null); done
q=$(find "$d" -path '*/bin/ecce-qm')
test -n "$q"
file "$q"
python3 tests/qm/package_check.py "$q" "$(dirname "$q")/../data/admin/basissets" --max-mb 40
- uses: actions/upload-artifact@v4
with:
name: ecce-fedora-latest-rpm
path: build-cmake/*.rpm
macos:
if: ${{ github.event_name != 'workflow_dispatch' || inputs.only == '' || inputs.only == 'macos' }}
name: macOS (${{ matrix.arch }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- { os: macos-latest, arch: arm64, target: "11.0", experimental: false }
# Catalina: the oldest macOS many 2012-2014 Intel Macs can run.
- { os: macos-15-intel, arch: x86_64, target: "10.15", experimental: true }
env:
# Oldest macOS the app is built for (#133). Our code and every
# bundled library are built to this; the minimum-macOS step fails
# the job on any Mach-O above it.
MACOSX_DEPLOYMENT_TARGET: ${{ matrix.target }}
ECCE_DEPS: /Users/runner/ecce-deps
# Bounded so a hung job cannot hold a runner slot for GitHub's
# 6-hour default; see the concurrency note above.
timeout-minutes: 90
# Known-unsupported today (GitHub #3) -- ECCE's offscreen-rendering
# path (src/inv/dbso/SoOffscreenRenderer.inc) calls raw Xlib/GLX
# (XOpenDisplay/glXCreateContext), which has no macOS-native
# equivalent (Cocoa/NSOpenGL, or GLX only via XQuartz). This job is
# here to track the gap with a real, current compile log instead of
# nothing -- it's expected to fail until #3 gets real porting work,
# not a sign the workflow itself is broken.
# x86_64 may fail until it is proven; arm64 must be green.
continue-on-error: ${{ matrix.experimental }}
steps:
- uses: actions/checkout@v4
- name: Install build tools
# Only tools: the libraries come from build-deps.sh, because
# Homebrew bottles are built for the runner's own macOS.
run: brew install cmake ninja pkgconf gcc bash
- name: Cache libraries built for macOS ${{ env.MACOSX_DEPLOYMENT_TARGET }}
id: deps
uses: actions/cache/restore@v4
with:
path: ${{ env.ECCE_DEPS }}
key: macos-deps-${{ matrix.arch }}-${{ env.MACOSX_DEPLOYMENT_TARGET }}-${{ hashFiles('packaging/macos/build-deps.sh') }}
- name: Build libraries (wxWidgets, Coin, Xerces, Mosquitto, libssh, OpenSSL)
if: steps.deps.outputs.cache-hit != 'true'
run: packaging/macos/build-deps.sh "$ECCE_DEPS"
- name: Save the libraries
if: steps.deps.outputs.cache-hit != 'true'
uses: actions/cache/save@v4
with:
path: ${{ env.ECCE_DEPS }}
key: ${{ steps.deps.outputs.cache-primary-key }}
- name: Configure
# ECCE_HOME_DIR/ECCE_WRAPPER_DESTINATION point the install at a
# staging tree inside the workspace for the run step below.
# Homebrew's prefixes are ignored so nothing is picked up from
# them by accident.
run: |
export PATH="$ECCE_DEPS/bin:$PATH"
export PKG_CONFIG_LIBDIR="$ECCE_DEPS/lib/pkgconfig"
cmake -G Ninja -B build-cmake -DECCE_USE_COIN=ON \
-DCMAKE_OSX_DEPLOYMENT_TARGET="$MACOSX_DEPLOYMENT_TARGET" \
-DCMAKE_PREFIX_PATH="$ECCE_DEPS" \
-DCMAKE_IGNORE_PREFIX_PATH="/opt/homebrew;/usr/local" \
-DCMAKE_MAKE_PROGRAM="$(command -v ninja)" -DPKG_CONFIG_EXECUTABLE="$(command -v pkg-config)" \
-DCMAKE_Fortran_COMPILER="$(ls $(brew --prefix)/bin/gfortran-* | head -1)" \
-DFREETYPE_UNQUALIFIED_INCLUDE_DIR="$ECCE_DEPS/include/freetype2/freetype" \
-DFREETYPE_ROOT_INCLUDE_DIR="$ECCE_DEPS/include/freetype2" \
-DECCE_HOME_DIR="$PWD/stage/ecce" -DECCE_WRAPPER_DESTINATION="$PWD/stage/bin" \
-DCMAKE_INSTALL_PREFIX="$PWD/stage/ecce"
- name: Build
# -k 0: report every failing file, not only the first few.
run: cmake --build build-cmake -- -k 0
# Does it run? (#133) Starts the installed apps on the runner's
# logged-in desktop and screenshots them. Allowed to fail; the
# verdict is in the summary and the "macos-run" artifact.
- name: Install to a staging prefix and run
continue-on-error: true
timeout-minutes: 25
run: |
export PATH="$ECCE_DEPS/sbin:$ECCE_DEPS/bin:$PATH"
cmake --install build-cmake
rc=0; tests/macos/run.sh stage macos-run || rc=$?
cat macos-run/summary.txt >> "$GITHUB_STEP_SUMMARY"
exit $rc
- uses: actions/upload-artifact@v4
if: always()
with:
name: macos-run-${{ matrix.arch }}
path: macos-run/
if-no-files-found: ignore
# ECCE.app in a .dmg (#133), then the start test again on a copy of
# the app taken out of the mounted image, away from the build tree.
# The two steps below fail the job when they fail. The job itself
# is continue-on-error (the native build is still experimental), so
# the workflow stays green but the job and these steps show red and
# the summary says FAILED.
- name: Package ECCE.app
run: |
export PATH="$ECCE_DEPS/bin:$PATH"
packaging/macos/make-app.sh stage dist
# Oldest macOS the bundle can run on (#133): the step fails when any
# Mach-O needs more than the deployment target or is not this runner's arch.
- name: Minimum macOS of every Mach-O in the app
run: |
mkdir -p minos
app=$(mktemp -d)
mnt=$(mktemp -d)
hdiutil attach dist/ECCE-*.dmg -mountpoint "$mnt" -nobrowse -quiet
cp -R "$mnt/ECCE.app" "$app/"
hdiutil detach "$mnt" -quiet
python3 packaging/macos/minos.py "$app/ECCE.app" minos/minos.txt \
--floor "$MACOSX_DEPLOYMENT_TARGET" --arch "${{ matrix.arch }}" > /dev/null || rc=$?
echo "runner: $(sw_vers -productVersion) $(uname -m)" >> minos/minos.txt
{ echo '### Minimum macOS (ECCE.app)'; echo '```';
sed -n '/^Mach-O files/,$p' minos/minos.txt; echo '```'; } >> "$GITHUB_STEP_SUMMARY"
exit ${rc:-0}
- name: ecce-qm in the app
run: |
mnt=$(mktemp -d)
hdiutil attach dist/ECCE-*.dmg -mountpoint "$mnt" -nobrowse -quiet
q="$mnt/ECCE.app/Contents/Resources/bin/ecce-qm"
test -x "$q"
python3 tests/qm/package_check.py "$q" "$mnt/ECCE.app/Contents/Resources/data/admin/basissets" --max-mb 40 | tee -a "$GITHUB_STEP_SUMMARY" || rc=$?
hdiutil detach "$mnt" -quiet
exit ${rc:-0}
- name: Run the packaged app
if: always() && hashFiles('dist/*.dmg') != ''
timeout-minutes: 25
run: |
pkill -f "$PWD/stage" || true
mnt=$(mktemp -d)
hdiutil attach dist/ECCE-*.dmg -mountpoint "$mnt" -nobrowse -quiet
appdir=$(mktemp -d)
cp -R "$mnt/ECCE.app" "$appdir/"
hdiutil detach "$mnt" -quiet
# The build tree and the staging prefix must not be needed.
mv build-cmake build-cmake.gone
mv stage stage.gone
rc=0
ECCE_APP="$appdir/ECCE.app" tests/macos/run.sh "$appdir/ECCE.app/Contents/Resources" macos-app-run || rc=$?
cat macos-app-run/summary.txt >> "$GITHUB_STEP_SUMMARY"
exit $rc
- name: Summary on failure
if: failure()
run: echo '### macOS packaging FAILED (see the failed step above)' >> "$GITHUB_STEP_SUMMARY"
- uses: actions/upload-artifact@v4
if: always()
with:
name: ECCE-macos-dmg-${{ matrix.arch }}
path: |
dist/*.dmg
minos/minos.txt
if-no-files-found: ignore
- uses: actions/upload-artifact@v4
if: always()
with:
name: macos-app-run-${{ matrix.arch }}
path: macos-app-run/
if-no-files-found: ignore
# Windows client (#133), experimental: MSYS2 UCRT64 toolchain, the same
# package set as tests/windows/README.md. Never turns the workflow red.
windows:
if: ${{ github.event_name != 'workflow_dispatch' || inputs.only == '' || inputs.only == 'windows' }}
name: Windows (MSYS2 UCRT64)
runs-on: windows-latest
timeout-minutes: 120
continue-on-error: true
steps:
# LF in the checkout: fixtures and shell scripts must not get CRLF.
- run: git config --global core.autocrlf false
- uses: actions/checkout@v4
- uses: msys2/setup-msys2@v2
with:
msystem: UCRT64
update: false
cache: true
install: >-
base git
mingw-w64-ucrt-x86_64-apr-util mingw-w64-ucrt-x86_64-ccache mingw-w64-ucrt-x86_64-cmake
mingw-w64-ucrt-x86_64-coin mingw-w64-ucrt-x86_64-freetype
mingw-w64-ucrt-x86_64-gcc mingw-w64-ucrt-x86_64-gcc-fortran
mingw-w64-ucrt-x86_64-glib2 mingw-w64-ucrt-x86_64-libjpeg-turbo
mingw-w64-ucrt-x86_64-libssh mingw-w64-ucrt-x86_64-mosquitto
mingw-w64-ucrt-x86_64-ninja mingw-w64-ucrt-x86_64-pkgconf
mingw-w64-ucrt-x86_64-python mingw-w64-ucrt-x86_64-wxwidgets3.2-msw
mingw-w64-ucrt-x86_64-xerces-c
# The build is ~20 minutes cold; ccache makes a rerun after a small
# change a few.
- uses: actions/cache@v4
with:
path: .ccache
key: ccache-windows-${{ github.run_id }}
restore-keys: ccache-windows-
- name: Configure
shell: msys2 {0}
env:
CCACHE_DIR: ${{ github.workspace }}/.ccache
CCACHE_MAXSIZE: 600M
run: |
cmake -G Ninja -B build -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_BUILD_TYPE=Release -DECCE_REQUIRE_LIBSSH=ON \
-DECCE_HOME_DIR="$PWD/stage/ecce" -DCMAKE_INSTALL_PREFIX="$PWD/stage/ecce"
- name: Build
shell: msys2 {0}
env:
CCACHE_DIR: ${{ github.workspace }}/.ccache
CCACHE_MAXSIZE: 600M
# -k 0: report every failing file, not only the first few.
run: cmake --build build -- -k 0
- name: Tests
id: tests
shell: msys2 {0}
continue-on-error: true
run: |
cd build
ctest -R 'transport_process|fragreaders|fragreaders_de|parsers' --output-on-failure --timeout 600 \
| tee ../ctest.log
exit "${PIPESTATUS[0]}"
- name: Install to a staging tree
shell: msys2 {0}
run: |
cmake --install build > install.log 2>&1 || { tail -30 install.log; exit 1; }
ls stage/ecce stage/ecce/bin
# The shell the job scripts run with, next to the apps (#133).
- name: Bundle the POSIX shell
shell: msys2 {0}
run: packaging/windows/bundle-shell.sh "$PWD/stage/ecce" "$(cygpath -m /)"
# MinGW runtime DLLs and the broker, then Perl and Python, so the tree
# runs with no MSYS2 on the machine.
- name: Bundle the runtime
shell: msys2 {0}
run: |
packaging/windows/bundle-runtime.sh "$PWD/stage/ecce"
cp packaging/windows/ecce.cmd packaging/windows/make-shortcuts.ps1 stage/ecce/
- name: Download cache (Strawberry Perl, Python, wxPython)
uses: actions/cache@v4
with:
path: ${{ runner.temp }}/ecce-dl
key: windows-tools-${{ hashFiles('packaging/windows/bundle-tools.ps1') }}
- name: Bundle Perl and Python
shell: pwsh
run: packaging/windows/bundle-tools.ps1 -Install stage\ecce -Cache "$env:RUNNER_TEMP\ecce-dl"
- name: Zip the install tree
shell: pwsh
run: |
$v = (Get-Content data/client/config/Version -TotalCount 1).Trim()
New-Item -ItemType Directory -Force dist | Out-Null
Compress-Archive -Path stage\ecce -DestinationPath "dist\ECCE-windows-$v.zip"
Get-ChildItem dist | Format-Table Name, Length
$d = "$env:RUNNER_TEMP\unpacked"
Remove-Item -Recurse -Force $d -ErrorAction SilentlyContinue
Expand-Archive "dist\ECCE-windows-$v.zip" $d
"unpacked: $((Get-ChildItem $d -Recurse -File | Measure-Object Length -Sum).Sum / 1MB) MB" | Tee-Object -Append $env:GITHUB_STEP_SUMMARY
Get-ChildItem "$d\ecce" | Format-Table Name
# launchjob is a test driver, not part of the package.
Copy-Item build\launchjob.exe "$d\ecce\bin\"
- name: ecce-qm in the zip
shell: pwsh
run: |
$r = "$env:RUNNER_TEMP\unpacked\ecce"
$env:Path = "$env:SystemRoot\System32;$env:SystemRoot"
& "$r\python\python3.exe" tests/qm/package_check.py "$r\bin\ecce-qm.exe" "$r\data\admin\basissets" --max-mb 40 2>&1 | Tee-Object -Append $env:GITHUB_STEP_SUMMARY
exit $LASTEXITCODE
# Local job end to end from the unpacked zip, with System32 as the only
# PATH outside it (tests/windows/launch_local.py): no MSYS2 involved.
- name: Local jobs (complete, cancel)
id: localjobs
shell: pwsh
continue-on-error: true
run: |
$r = "$env:RUNNER_TEMP\unpacked\ecce"
New-Item -ItemType Directory -Force localjobs | Out-Null
$sys = "$env:SystemRoot\System32;$env:SystemRoot"
$env:Path = $sys
$env:WINTEST_HOME = $r
$env:WINTEST_BASE_PATH = "$r\bin;$r\usr\bin;$r\python;$r\strawberry\perl\site\bin;$r\strawberry\perl\bin;$r\strawberry\c\bin;$sys"
$env:Path = $env:WINTEST_BASE_PATH
& "$r\usr\bin\bash.exe" -c 'echo "$PATH"; command -v mosquitto mosquitto_sub perl python3; ls -l "$ECCE_HOME/bin/mosquitto.exe"' 2>&1 | Tee-Object localjobs\probe.log
$env:Path = $sys
$rc = 0
foreach ($c in "complete", "cancel") {
& "$r\python\python3.exe" tests/windows/launch_local.py $c --build "$r\bin" --state "$PWD\localjobs\state-$c" 2>&1 | Tee-Object "localjobs\$c.log"
"$c rc=$LASTEXITCODE" | Tee-Object -Append localjobs\summary.txt
if ($LASTEXITCODE -ne 0) { $rc = 1 }
}
Get-Content localjobs\summary.txt >> $env:GITHUB_STEP_SUMMARY
exit $rc
# Does it run? (#133) Starts the unpacked apps on the runner's desktop
# (PATH: the package and System32 only) and screenshots them. Allowed
# to fail; see summary.txt.
- name: Start the apps
id: apps
shell: pwsh
continue-on-error: true
timeout-minutes: 20
run: |
$env:Path = "$env:SystemRoot\System32;$env:SystemRoot"
tests\windows\ci-run.ps1 -Stage "$env:RUNNER_TEMP\unpacked" -Out windows-run
Get-Content windows-run\summary.txt >> $env:GITHUB_STEP_SUMMARY
- uses: actions/upload-artifact@v4
if: always()
with:
name: ECCE-windows-zip
path: dist/*.zip
if-no-files-found: ignore
- uses: actions/upload-artifact@v4
if: always()
with:
name: windows-run
path: |
windows-run/
localjobs/
ctest.log
install.log
if-no-files-found: ignore
# continue-on-error steps show green; say what really happened, and
# fail this (experimental) job when any of them did.
- name: Verdict
if: always()
shell: bash
run: |
{ echo '### Windows'
echo "- ctest: ${{ steps.tests.outcome }}"
echo "- local jobs: ${{ steps.localjobs.outcome }}"
echo "- start the apps: ${{ steps.apps.outcome }}"; } >> "$GITHUB_STEP_SUMMARY"
[ "${{ steps.tests.outcome }}${{ steps.localjobs.outcome }}${{ steps.apps.outcome }}" = successsuccesssuccess ]