Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 35 additions & 8 deletions .github/workflows/build_matrix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ jobs:
- name: "SCM Checkout"
uses: actions/checkout@v4

- name: "Runner info"
shell: bash
run: bash ci/runner_info.sh

- name: "Exclude workspace from Windows Defender"
if: runner.os == 'Windows'
shell: pwsh
Expand Down Expand Up @@ -175,6 +179,16 @@ jobs:
echo "SCCACHE_DIR=${{ runner.temp }}/sccache" >> $GITHUB_ENV
echo "SCCACHE_GHA_ENABLED=false" >> $GITHUB_ENV
echo "ZERO_AR_DATE=1" >> $GITHUB_ENV
# SCCACHE_CACHE_SIZE bounds the slot: the default is 10G, and a slot grows to its bound
# with objects of commits long gone. Unbounded slots fill the repository's cache quota,
# and the slots the nightly cells save once a day are the ones evicted, before the next
# nightly reads them. A windows /Z7 object is ~5x a posix one (debug info embedded in
# every .obj), hence its own bound.
if [ "$RUNNER_OS" = "Windows" ]; then
echo "SCCACHE_CACHE_SIZE=5000M" >> $GITHUB_ENV
else
echo "SCCACHE_CACHE_SIZE=2000M" >> $GITHUB_ENV
fi
# Non-Windows: export the launcher via env (also wraps the GLFW/libhv
# ExternalProject sub-builds — harmless on gcc/clang). Windows must NOT
# export it: CMake seeds CMAKE_<LANG>_COMPILER_LAUNCHER from the env
Expand All @@ -192,17 +206,18 @@ jobs:
# no-op, so we delete first). PRs read-only. Bounded footprint: N configs ×
# one tarball, no run_id pileup. Every run restores, the cron included: the
# nightly cells are the slow ones, and the cron's save is the seeder every PR
# lane warms from. A sanitizer cell's three phase jobs share one
# slot; only the tests phase writes it, so there is one writer per key.
# lane warms from. A sanitizer cell's tests and backend jobs share one
# slot the tests job writes; the slow job reads and writes a slot of its own,
# since the full test_aot it compiles is in no other job's objects. One writer per key.
- name: "Restore sccache objects"
uses: actions/cache/restore@v4
with:
path: |
${{ runner.temp }}/sccache
.cache/daslang/test_cache
.cache/daslang/_anon_*
key: sccache-${{ matrix.target }}-${{ matrix.architecture }}-${{ matrix.cmake_preset }}-${{ matrix.sanitizers }}${{ matrix.fast_math == 'ON' && '-fastmath' || '' }}@${{ github.run_id }}
restore-keys: sccache-${{ matrix.target }}-${{ matrix.architecture }}-${{ matrix.cmake_preset }}-${{ matrix.sanitizers }}${{ matrix.fast_math == 'ON' && '-fastmath' || '' }}@
key: sccache-${{ matrix.target }}-${{ matrix.architecture }}-${{ matrix.cmake_preset }}-${{ matrix.sanitizers }}${{ matrix.fast_math == 'ON' && '-fastmath' || '' }}${{ matrix.phase == 'slow' && '-slow' || '' }}@${{ github.run_id }}
restore-keys: sccache-${{ matrix.target }}-${{ matrix.architecture }}-${{ matrix.cmake_preset }}-${{ matrix.sanitizers }}${{ matrix.fast_math == 'ON' && '-fastmath' || '' }}${{ matrix.phase == 'slow' && '-slow' || '' }}@

- name: "Override das_llvm_disabled for LLVM-free matrix cells"
if: (matrix.target == 'windows' && matrix.architecture == 32) || matrix.llvm_disabled == 'ON'
Expand All @@ -227,6 +242,13 @@ jobs:
cmake --build ./build --config ${{ matrix.cmake_preset }} --target $lane --parallel \
|| cmake --build ./build --config ${{ matrix.cmake_preset }} --target ${lane}_isolated --parallel

# windows 64 Debug: the default build and nothing else. windows Release and the posix Debug
# cells run the sweeps; what only this cell says is that the tree compiles and links as
# MSVC Debug.
- name: "Compile"
if: matrix.phase == 'compile'
run: cmake --build ./build --config ${{ matrix.cmake_preset }} --parallel

- name: "Nightly Tests"
# Full AOT suite: builds the full test_aot (EXCLUDE_FROM_ALL, ~1080 AOT
# TUs — the single biggest CI cost) via the run_tests_aot dependency and
Expand Down Expand Up @@ -254,19 +276,19 @@ jobs:
# The lane targets above are what compiles (Build only configures), so the slot is saved
# here, and on a red sweep too: the objects a failed run compiled are as good as any.
- name: "Save sccache objects"
if: ${{ !cancelled() && github.ref == 'refs/heads/master' && matrix.phase != 'slow' && matrix.phase != 'backend' }}
if: ${{ !cancelled() && github.ref == 'refs/heads/master' && matrix.phase != 'backend' }}
uses: actions/cache/save@v4
with:
path: |
${{ runner.temp }}/sccache
.cache/daslang/test_cache
.cache/daslang/_anon_*
key: sccache-${{ matrix.target }}-${{ matrix.architecture }}-${{ matrix.cmake_preset }}-${{ matrix.sanitizers }}${{ matrix.fast_math == 'ON' && '-fastmath' || '' }}@${{ github.run_id }}
key: sccache-${{ matrix.target }}-${{ matrix.architecture }}-${{ matrix.cmake_preset }}-${{ matrix.sanitizers }}${{ matrix.fast_math == 'ON' && '-fastmath' || '' }}${{ matrix.phase == 'slow' && '-slow' || '' }}@${{ github.run_id }}
- name: "Prune older sccache slots"
if: ${{ !cancelled() && github.ref == 'refs/heads/master' && matrix.phase != 'slow' && matrix.phase != 'backend' }}
if: ${{ !cancelled() && github.ref == 'refs/heads/master' && matrix.phase != 'backend' }}
env:
GH_TOKEN: ${{ github.token }}
SCKEY: sccache-${{ matrix.target }}-${{ matrix.architecture }}-${{ matrix.cmake_preset }}-${{ matrix.sanitizers }}${{ matrix.fast_math == 'ON' && '-fastmath' || '' }}@
SCKEY: sccache-${{ matrix.target }}-${{ matrix.architecture }}-${{ matrix.cmake_preset }}-${{ matrix.sanitizers }}${{ matrix.fast_math == 'ON' && '-fastmath' || '' }}${{ matrix.phase == 'slow' && '-slow' || '' }}@
run: |
# best effort, and the newest entry survives whatever this run saved: a save that produced
# nothing must not wipe the last good slot, and a listing hiccup must not fail the lane
Expand All @@ -275,3 +297,8 @@ jobs:
--jq 'sort_by(.createdAt) | reverse | .[1:] | .[].id' \
| while read -r id; do gh cache delete "$id" -R ${{ github.repository }}; done
true

- name: "Runner info at the end"
if: ${{ !cancelled() }}
shell: bash
run: bash ci/runner_info.sh
15 changes: 9 additions & 6 deletions .github/workflows/extended_checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ jobs:
# Full history so the lint step can `git diff` against the PR base branch.
fetch-depth: 0

- name: "Runner info"
shell: bash
run: bash ci/runner_info.sh

- name: "Exclude workspace from Windows Defender"
if: runner.os == 'Windows'
shell: pwsh
Expand Down Expand Up @@ -112,12 +116,6 @@ jobs:
run: |
set -eux
case "${{ matrix.target }}" in
darwin15)
brew install bison openssl
echo 'export PATH="/usr/local/opt/bison/bin:$PATH"' >> ~/.bash_profile
export LDFLAGS="-L/usr/local/opt/bison/lib -L$(brew --prefix openssl)/lib"
export CPPFLAGS="-I$(brew --prefix openssl)/include"
;;
linux)
echo "MARCH=64" >> $GITHUB_ENV
# apt.llvm.org carries LLVM 22 per Ubuntu codename; ubuntu-latest moves between them.
Expand Down Expand Up @@ -294,6 +292,11 @@ jobs:
| while read -r id; do gh cache delete "$id" -R ${{ github.repository }}; done
true

- name: "Runner info at the end"
if: ${{ !cancelled() }}
shell: bash
run: bash ci/runner_info.sh

commit_messages:
if: github.event_name == 'pull_request' && inputs.lane != 'extended_nightly'
runs-on: ubuntu-latest
Expand Down
10 changes: 8 additions & 2 deletions ci/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,14 @@ das_lane_group(run_extended_modules "Running the extended checks (modules)" ${DA
das_lane_group(run_extended_all "Running every extended check"
${DAS_EXTENDED_CORE} ${DAS_EXTENDED_MODULES} ${DAS_EXTENDED_NIGHTLY})

# The dasLLVM vector-math rail pins vecmath's answers on Apple silicon; the extended checks have
# no macOS cell, so the darwin build cells run it.
set(DAS_BUILD_LANE_APPLE "")
if(APPLE AND TARGET run_tests_llvm_vector_math AND NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
list(APPEND DAS_BUILD_LANE_APPLE run_tests_llvm_vector_math)
endif()
das_lane_group(run_build "Running the build lane"
run_tests_sweeps test-small run_tests_aot_subset)
run_tests_sweeps test-small run_tests_aot_subset ${DAS_BUILD_LANE_APPLE})
das_lane_group(run_build_nightly "Running the build lane's nightly sweeps"
run_tests_slow run_backend_sweeps test_aot_subset)
das_lane_group(run_build_sanitizers "Running the sanitizer lane"
Expand All @@ -133,7 +139,7 @@ das_lane_group(run_build_mingw "Running the mingw lane"
# The isolated retry of a lane whose sweep failed: the workflow chains `<lane> || <lane>_isolated`
# (cmake has no retry primitive inside one target).
das_lane_group(run_build_isolated "Retrying the build lane's sweeps in isolated mode"
run_tests_sweeps_isolated test-small run_tests_aot_subset)
run_tests_sweeps_isolated test-small run_tests_aot_subset ${DAS_BUILD_LANE_APPLE})
das_lane_group(run_build_sanitizers_isolated "Retrying the sanitizer lane's sweep in isolated mode"
run_tests_interpreter_isolated test-small)
das_lane_group(run_build_mingw_isolated "Retrying the mingw lane's sweeps in isolated mode"
Expand Down
23 changes: 12 additions & 11 deletions ci/ci_matrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
LINUX_ARM_EXTRA = CLANG + " -DDAS_GLFW_DISABLED=ON -DDAS_HV_DISABLED=OFF -DDAS_SQLITE_DISABLED=OFF"
WINDOWS_EXTRA = ("-DCMAKE_C_COMPILER_LAUNCHER=sccache -DCMAKE_CXX_COMPILER_LAUNCHER=sccache"
" -DCMAKE_TOOLCHAIN_FILE=$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake")
# dastest's whole-suite watchdogs, raised for the cells whose sweep runs at half speed (windows
# Debug, the sanitizers) and then rides the hosted runner's ~1.4x swing; every other cell keeps
# dastest's whole-suite watchdogs, raised for the cells whose sweep runs at half speed (the
# sanitizers) and then rides the hosted runner's ~1.4x swing; every other cell keeps
# tests/CMakeLists.txt's defaults, so a hang there still fails fast
SLOW_SWEEP_BUDGETS = " -DDAS_TEST_TIMEOUT=3600 -DDAS_TEST_TIMEOUT_ISOLATED=7200 -DDAS_TEST_TIMEOUT_AOT=3600"

Expand All @@ -37,7 +37,8 @@ def _cells(target, architecture, presets, **props):
def build_cells(nightly):
"""build.yml: Release + Debug on every platform per PR; the sanitizer cells and windows
64 Debug are nightly-only. A sanitizer cell is three jobs, one per test step (`phase`);
every other cell runs every step (`phase` all)."""
windows 64 Debug compiles and runs no test (`phase` compile); every other cell runs every
step (`phase` all)."""
cmake = dict(build_system="cmake", cmake_generator="Ninja")
cells = []
cells += _cells("linux", 64, ["Debug", "Release"], release_target="linux", release_arch="x86_64",
Expand All @@ -62,7 +63,7 @@ def build_cells(nightly):
if nightly:
cells += _cells("windows", 64, ["Debug"], release_target="windows", release_arch="x86_64",
runner="windows-latest", architecture_string="x64", archive_ext="zip",
jit_disabled="ON", nightly_only="ON", cmake_extra=WINDOWS_EXTRA + SLOW_SWEEP_BUDGETS,
jit_disabled="ON", nightly_only="ON", phase="compile", cmake_extra=WINDOWS_EXTRA,
**cmake)
for san in SANITIZERS:
for phase in SANITIZER_PHASES:
Expand All @@ -79,18 +80,18 @@ def build_cells(nightly):


def extended_cells(nightly):
"""extended_checks.yml: per PR two darwin15 jobs split by role (core: the tree's own gates and
utils; modules: the module and service suites); the nightly runs every step on linux, darwin15
and windows in one job each (role all)."""
"""extended_checks.yml: per PR two linux jobs split by role (core: the tree's own gates and
utils; modules: the module and service suites); the nightly runs every step on linux and
windows in one job each (role all). No macOS cell: the hosted macOS runner is 3 cores and
7 GB against linux's 4 and 16, and ran the same steps in about twice the time."""
cmake = dict(build_system="cmake", cmake_generator="Ninja")
darwin = dict(target="darwin15", architecture="arm64", runner="macos-15", architecture_string="arm64", **cmake)
linux = dict(target="linux", architecture=64, runner="ubuntu-latest", **cmake)
if nightly:
return [
dict(target="linux", architecture=64, role="all", runner="ubuntu-latest", **cmake),
dict(role="all", **darwin),
dict(role="all", **linux),
dict(target="windows", architecture=64, role="all", runner="windows-latest", architecture_string="x64", **cmake),
]
return [dict(role="core", **darwin), dict(role="modules", **darwin)]
return [dict(role="core", **linux), dict(role="modules", **linux)]


def main(argv):
Expand Down
26 changes: 26 additions & 0 deletions ci/runner_info.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/usr/bin/env bash
# Prints what the hosted runner gave this job: cores, memory, load, free disk. A job that runs
# several times slower than the night before is read against these lines first.
set -u
os=$(uname -s)
echo "runner: os=$os arch=$(uname -m) name=${RUNNER_NAME:-?} image=${ImageOS:-?} ${ImageVersion:-}"
case "$os" in
Linux)
echo "runner: cpus=$(nproc) model=$(grep -m1 'model name' /proc/cpuinfo | cut -d: -f2- | xargs)"
awk '/MemTotal|MemAvailable|SwapTotal/ { printf "runner: %s %d MiB\n", $1, $2 / 1024 }' /proc/meminfo
echo "runner: load=$(cut -d' ' -f1-3 /proc/loadavg)"
;;
Darwin)
echo "runner: cpus=$(sysctl -n hw.ncpu) model=$(sysctl -n machdep.cpu.brand_string)"
echo "runner: MemTotal: $(( $(sysctl -n hw.memsize) / 1048576 )) MiB"
page=$(sysctl -n hw.pagesize)
free=$(vm_stat | awk '/Pages free|Pages inactive|Pages speculative/ { gsub("\\.", "", $NF); s += $NF } END { print s }')
echo "runner: MemAvailable: $(( free * page / 1048576 )) MiB"
echo "runner: load=$(sysctl -n vm.loadavg)"
;;
*)
echo "runner: cpus=${NUMBER_OF_PROCESSORS:-?} model=${PROCESSOR_IDENTIFIER:-?}"
powershell -NoProfile -Command '$o = Get-CimInstance Win32_OperatingSystem; "runner: MemTotal: {0} MiB`nrunner: MemAvailable: {1} MiB" -f [int]($o.TotalVisibleMemorySize / 1024), [int]($o.FreePhysicalMemory / 1024)' || true
;;
esac
echo "runner: disk $(df -h . | awk 'NR == 2 { print "size=" $2 " free=" $4 }')"
Loading
Loading