Skip to content

Build/Test

Build/Test #543

Workflow file for this run

# Build, test and upload executables to GitHub
# depends on pre-installed software; see image definitions:
# - https://github.com/actions/runner-images/blob/main/images/linux/Ubuntu2404-Readme.md
# - https://github.com/actions/runner-images/blob/main/images/macos/macos-12-Readme.md
# We use these tools from the runner images: git, gcc/XCode/MSVC, swig, Tcl/Tk on MacOS, pkg-config
# TODO: not building svs_viewer ('Cannot find GL, GLU, not building svs_viewer' and 'Cannot find opengl32, glu32, not building svs_viewer')
# TODO: pin more dependency versions (python, swig, gcc/XCode/MSVC, etc.)
name: Build/Test
on:
push:
pull_request:
workflow_dispatch:
release:
types:
- prereleased
- released
schedule:
# 5AM every Monday, to catch breaks due to changes in dependencies
- cron: "0 5 * * 1"
jobs:
"Posix":
name: build-*nix
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [
# Use v24 beta for now to get newer SWIG; TODO: change back to ubuntu-latest once it points to v24
ubuntu-24.04,
# latest available X86_64 target
macos-12,
# latest is ARM
macos-latest,
]
steps:
- name: Checkout
uses: actions/checkout@v1
- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: '3.12'
- name: Setup Java
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '11'
- name: Setup dotnet
uses: actions/setup-dotnet@v4
with:
dotnet-version: '6.0.X'
- name: Setup tcl (ubuntu)
if: startsWith(matrix.os, 'ubuntu-')
run: sudo apt-get update && sudo apt-get install tcl-dev
- name: Setup tcl (macos-latest)
if: matrix.os == 'macos-latest'
run: brew install tcl-tk
- name: Setup SWIG (macos-latest)
if: matrix.os == 'macos-latest'
run: brew install swig
- name: build
env:
# instructs SCons to print debug statements to stdout
SCONS_MSCOMMON_DEBUG: '-'
# Build Python bindings that are portable across Python versions
SOAR_PYTHON_ABI3: 1
run: python3 scons/scons.py --scu --opt --verbose all performance_tests sml_tcl
- name: Pack artifacts
run: tar -czvf build.tar.gz out/
- name: upload artifacts
uses: actions/upload-artifact@v3
with:
name: Soar-${{ matrix.os }}
path: ./build.tar.gz
- name: unit tests
working-directory: ./out
# TODO: why do these fail? Make them pass. testHamilton only fails on Mac, and only sometimes.
run: ./UnitTests -e PRIMS_Sanity1 -e PRIMS_Sanity2 -f testLoadLibrary -f testSmemArithmetic -f testHamilton
- name: SML Java tests
working-directory: ./out
env:
LD_LIBRARY_PATH: ${{ github.workspace }}/out
run: java -jar java/soar-smljava.jar
- name: SML Python tests
working-directory: ./out
env:
LD_LIBRARY_PATH: ${{ github.workspace }}/out
PYTHONUTF8: 1
run: python3 TestPythonSML.py
- name: SML Tcl tests
working-directory: ./out
run: tclsh TestTclSML.tcl
# TODO: run additional tests for CSharp
# reports JUnit test results as GitHub PR check.
- name: publish test report
uses: mikepenz/action-junit-report@v3
# always run even if the previous step fails
if: always()
with:
report_paths: './out/TestResults.xml'
# disabled until https://github.com/mikepenz/action-junit-report/issues/40 is resolved
# fail_on_failure: true
annotate_only: true
# TODO: run SML tests (Python, Tcl, Java)
- name: performance tests
working-directory: ./out
run: sudo ./do_performance_test.sh
- name: upload performance test results
uses: actions/upload-artifact@v3
with:
name: ${{ matrix.os }}-PerformanceTestResults.txt
path: ./out/SoarPerformanceTests/PerformanceTestResults.txt
# Using powershell means we need to explicitly stop on failure
Windows:
name: build-windows
runs-on: [windows-latest]
env:
TCL_HOME: c:\progra~1\tcl
TCL_DOWNLOAD_URL: https://kumisystems.dl.sourceforge.net/project/tcl/Tcl/8.6.13/tcl8613-src.zip
EXPECTED_TCL_HASH: 8999fcafab2d85473280e0bf6e390480496dfd53
steps:
- name: Checkout
uses: actions/checkout@v1
- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: '3.12'
- name: Setup Java
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '11'
# This does not install MSVC or Visual Studio! We rely on the software installed already on the
# GH action runner, and this step just prepares the environment. We pin the VS version here because
# the error messages are much more helpful than the mess we get from SCons, which automatically
# falls back on a combo of Mingw with MSVC libs and then fails to build.
- name: switch to VS command prompt
uses: ilammy/msvc-dev-cmd@v1
- name: Cache Tcl build
id: tcl-msvc-cache
uses: actions/cache@v3
with:
path: ${{ env.TCL_HOME }}
key: tcl-build-windows-${{ env.TCL_DOWNLOAD_URL }}
# No easy/quick way to install TCL on Windows, so we download and build it ourselves.
- name: download, build and install Tcl
if: steps.tcl-msvc-cache.outputs.cache-hit != 'true'
run: |
(new-object System.Net.WebClient).DownloadFile($Env:TCL_DOWNLOAD_URL, 'tcl8613-src.zip')
# check that the file hash matches what we expect
$FileHash = Get-FileHash -Algorithm SHA1 tcl8613-src.zip
if ( $FileHash.Hash -ne $Env:EXPECTED_TCL_HASH ) {
throw "tcl download hash mismatch: $($FileHash.Hash)"
}
Expand-Archive tcl8613-src.zip -DestinationPath tcl8613-src
cd tcl8613-src\tcl8.6.13\win
# Build and install must be done in two steps: https://core.tcl-lang.org/tcl/tktview/aa6e42643794ecff2f3508d7306c702baf4f4c0f
nmake /D /f makefile.vc INSTALLDIR="$env:TCL_HOME"
if ($lastexitcode -ne 0) {
throw "nmake build exit code: $lastexitcode"
}
nmake /D /f makefile.vc INSTALLDIR="$env:TCL_HOME" install
if ($lastexitcode -ne 0) {
throw "nmake install exit code: $lastexitcode"
}
- name: build
env:
# instructs SCons to print debug statements to stdout
SCONS_MSCOMMON_DEBUG: '-'
run: |
./build.bat --scu --opt --verbose --tcl="$env:TCL_HOME" all performance_tests sml_tcl
if ($lastexitcode -ne 0) {
throw "build.bat exit code: $lastexitcode"
}
- name: Pack artifacts
shell: bash
run: tar -czvf build.tar.gz out/
- name: upload artifacts
uses: actions/upload-artifact@v3
with:
name: Soar-Windows
path: ./build.tar.gz
- name: unit tests
working-directory: ./out
# TODO: why do these fail? Make them pass.
run: |
./UnitTests -e PRIMS_Sanity1 -e PRIMS_Sanity2 -f testSmemArithmetic
if ($lastexitcode -ne 0) {
throw "UnitTests exit code: $lastexitcode"
}
- name: SML Java tests
working-directory: ./out
run: |
java -jar java/soar-smljava.jar
if ($lastexitcode -ne 0) {
throw "soar-smljava exit code: $lastexitcode"
}
- name: SML Python tests
working-directory: ./out
env:
PYTHONUTF8: 1
run: |
python3 TestPythonSML.py
if ($lastexitcode -ne 0) {
throw "TestPythonSML.py exit code: $lastexitcode"
}
- name: SML Tcl tests
working-directory: ./out
run: |
# have to add Tcl to path every time we use it (permanent add is possible but troublesome)
$env:path += "$env:path;$env:TCL_HOME\bin"
tclsh86t TestTclSML.tcl
if ($lastexitcode -ne 0) {
throw "TestTclSML.tcl exit code: $lastexitcode"
}
# TODO: run additional tests for CSharp
# reports JUnit test results as GitHub PR check.
- name: publish test report
uses: mikepenz/action-junit-report@v3
# always run even if the previous step fails
if: always()
with:
report_paths: './out/TestResults.xml'
# disabled until https://github.com/mikepenz/action-junit-report/issues/40 is resolved
# fail_on_failure: true
annotate_only: true
- name: performance tests
working-directory: ./out
run: |
bash ./do_performance_test.sh
if ($lastexitcode -ne 0) {
throw "do_performance_test exit code: $lastexitcode"
}
- name: upload performance test results
uses: actions/upload-artifact@v3
with:
name: Windows-PerformanceTestResults.txt
path: ./out/SoarPerformanceTests/PerformanceTestResults.txt
python_wheels:
name: wheel-*nix
runs-on: ${{ matrix.os }}
strategy:
fail-fast: true
matrix:
os: [
# 20.04 to preserve compatibility with testing stage
ubuntu-20.04,
# latest available X86_64 target
macos-12,
# latest is ARM
macos-latest,
windows-latest,
]
steps:
- name: Checkout
uses: actions/checkout@v4
with:
# Do a complete clone, not a shallow one.
# https://github.com/actions/checkout/#usage
#
# We need a complete clone, as versioningit uses `git describe`,
# which requires a commit tree to determine the latest tag.
fetch-depth: 0
- name: Show tags
run: git describe --long --dirty --always --tags
- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: "3.12"
# - name: Setup tcl (ubuntu)
# if: matrix.os == 'ubuntu-latest'
# run: sudo apt-get update && sudo apt-get install tcl-dev
# - name: Setup tcl (macos-latest)
# if: matrix.os == 'macos-latest'
# run: brew install tcl-tk
- name: Setup SWIG (macos-latest)
if: matrix.os == 'macos-latest'
run: brew install swig
- name: Setup SWIG (windows-latest)
if: matrix.os == 'windows-latest'
uses: MinoruSekine/setup-scoop@v4
with:
apps: swig
- name: Build wheels
uses: pypa/cibuildwheel@v2.17.0
with:
package-dir: Core/ClientSMLSWIG/Python/
- name: Ensure unit tests built (ubuntu-20.04)
if: matrix.os == 'ubuntu-20.04'
# On Ubuntu, we run cibuildwheel inside docker containers, which don't retain the outputs.
# However, we want out/SoarUnitTests/ to be availible for future tests, so we build it again here.
run: python scons/scons.py tests
# Save out/SoarUnitTests/
- uses: actions/cache/save@v3
id: cache
with:
path: out/SoarUnitTests/
key: ${{ runner.os }}-${{ github.sha }}
- name: ABI3Audit (*nix)
if: matrix.os != 'windows-latest'
run: pipx run abi3audit -S -v wheelhouse/*
- name: ABI3Audit (Windows)
if: matrix.os == 'windows-latest'
# For windows we can't use glob expansion, so we need to enumerate the files manually.
# https://stackoverflow.com/a/16804630/8700553
run: Get-ChildItem -File wheelhouse | Foreach {pipx run abi3audit -S -v $_.fullname}
- uses: actions/upload-artifact@v4
with:
name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }}
path: ./wheelhouse/*.whl
test_python:
name: Test wheel on all python versions
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
# linux target which supports all python versions we want to install for
- ubuntu-20.04
# latest available X86_64 target
- macos-12
# latest is ARM
- macos-latest
- windows-latest
python-minor:
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
# for macos-latest, we can't use python 3.5 - 3.7
exclude:
- os: macos-latest
python-minor: 5
- os: macos-latest
python-minor: 6
- os: macos-latest
python-minor: 7
needs:
# We depend on the python wheel builds because we need their artifacts
- python_wheels
# We depend on the builds themselves to gatekeep the upload if build + testing fails,
# usually then also the python wheel build should fail, but the normal builds do more thorough checking.
- Posix
- Windows
steps:
- name: Checkout
uses: actions/checkout@v4
- uses: actions/download-artifact@v4
with:
pattern: cibw-wheels-*
path: wheelhouse/
merge-multiple: true
- name: Setup Base Python
uses: actions/setup-python@v4
with:
python-version: 3.${{ matrix.python-minor }}
env:
# Older python versions fail install if we dont do this: https://github.com/actions/setup-python/issues/866
PIP_TRUSTED_HOST: "pypi.python.org pypi.org files.pythonhosted.org"
# Restore out/SoarUnitTests/
- uses: actions/cache/restore@v3
id: cache
with:
path: out/SoarUnitTests/
key: ${{ runner.os }}-${{ github.sha }}
fail-on-cache-miss: true
- name: Install soar-sml
run: |
pip3.${{ matrix.python-minor }} install soar-sml -f wheelhouse --no-index
- name: Run test command (Non-Windows)
if: matrix.os != 'windows-latest'
env:
# Ensures unicode outputs properly on all versions
PYTHONUTF8: 1
PYTHONIOENCODING: utf-8
run: python3.${{ matrix.python-minor }} Core/ClientSMLSWIG/Python/TestPythonSML.py
- name: Run test command (Windows)
if: matrix.os == 'windows-latest'
env:
# Ensures unicode outputs properly on all versions
PYTHONUTF8: 1
PYTHONIOENCODING: utf-8
run: py -3.${{ matrix.python-minor }} Core/ClientSMLSWIG/Python/TestPythonSML.py
python_push_dev:
name: Publish to test.pypi.org
runs-on: ubuntu-latest
# - Upload only every monday to prevent spamming the index with too many build artifacts.
# - Allow uploading on manual workflow dispatch, to enable quick dev releases.
if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'
# Alternative, to upload on every commit to development;
# if: github.event_name != 'schedule' && github.event_name != 'release'
needs: test_python
# We use Trusted Publishing to manage our access to pypi:
# https://github.com/marketplace/actions/pypi-publish#trusted-publishing
environment:
name: test-pypi
url: https://test.pypi.org/p/soar-sml/
permissions:
id-token: write
steps:
- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: "3.12"
- uses: actions/download-artifact@v4
with:
pattern: cibw-wheels-*
path: wheelhouse/
merge-multiple: true
- name: Publish package distributions to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
repository-url: https://test.pypi.org/legacy/
packages-dir: wheelhouse
skip-existing: true
verbose: true
python_push_release:
name: Publish to pypi.org
runs-on: ubuntu-latest
if: github.event_name == 'release'
needs: test_python
# We use Trusted Publishing to manage our access to pypi:
# https://github.com/marketplace/actions/pypi-publish#trusted-publishing
environment:
name: pypi
url: https://pypi.org/p/soar-sml/
permissions:
id-token: write
steps:
- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: "3.12"
- uses: actions/download-artifact@v4
with:
pattern: cibw-wheels-*
path: wheelhouse/
merge-multiple: true
- name: Publish package distributions to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
packages-dir: wheelhouse
skip-existing: true
verbose: true