Comment change #3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Run OpenMDAO Tests | |
name: OpenMDAO Tests | |
on: | |
# Trigger on push or pull request events for the master branch | |
push: | |
branches: [ master ] | |
pull_request: | |
branches: [ master ] | |
# Allow running the workflow manually from the Actions tab | |
workflow_dispatch: | |
jobs: | |
tests: | |
timeout-minutes: 120 | |
strategy: | |
fail-fast: false | |
matrix: | |
include: | |
# test baseline versions on Ubuntu | |
- NAME: Ubuntu Baseline | |
OS: ubuntu-latest | |
PY: '3.11' | |
NUMPY: '1.24' | |
SCIPY: '1.10' | |
PETSc: '3.18' | |
PYOPTSPARSE: 'v2.9.2' | |
PAROPT: true | |
SNOPT: '7.7' | |
OPTIONAL: '[all]' | |
JAX: '0.4.2' | |
BANDIT: true | |
TESTS: true | |
# set DEBUG to create an interactive debugging session just before testflo is run. | |
# Note that the workflow will run until you cancel the debugging session. | |
# To access the terminal through the web-interface: | |
# 1. Click on the web-browser link printed out in this action from the github | |
# workflow terminal | |
# 2. Press cntrl + c in the new tab that opens up to reveal the terminal | |
# 3. To activate the conda environment run: | |
# $ source $CONDA/etc/profile.d/conda.sh | |
# $ conda activate test | |
# See https://github.com/mxschmitt/action-tmate for more details | |
# DEBUG: true | |
# test baseline versions on MacOS | |
- NAME: MacOS Baseline | |
OS: macos-latest | |
PY: '3.11' | |
NUMPY: '1.24' | |
SCIPY: '1.10' | |
PETSc: '3.18' | |
# PYOPTSPARSE: 'v2.9.2' | |
# PAROPT: true | |
# SNOPT: '7.7' | |
OPTIONAL: '[all]' | |
JAX: '0.4.2' | |
TESTS: true | |
# test minimal install | |
- NAME: Ubuntu Minimal | |
OS: ubuntu-latest | |
PY: '3' | |
NUMPY: '1.24' | |
SCIPY: '1.10' | |
OPTIONAL: '[test]' | |
TESTS: true | |
# test oldest supported versions | |
- NAME: Ubuntu Oldest | |
OS: ubuntu-latest | |
PY: '3.7' | |
NUMPY: '1.21' | |
SCIPY: '1.7' | |
OPENMPI: '4.0' | |
MPI4PY: '3.0' | |
PETSc: '3.13' | |
PYOPTSPARSE: 'v1.2' | |
SNOPT: '7.2' | |
OPTIONAL: '[all]' | |
TESTS: true | |
# build docs (baseline versions) | |
- NAME: Build Docs | |
OS: ubuntu-latest | |
PY: '3.11' | |
NUMPY: '1.24' | |
SCIPY: '1.10' | |
PETSc: '3.18' | |
PYOPTSPARSE: 'v2.9.2' | |
SNOPT: '7.7' | |
OPTIONAL: '[all]' | |
JAX: '0.4.2' | |
BUILD_DOCS: true | |
runs-on: ${{ matrix.OS }} | |
name: ${{ matrix.NAME }} | |
defaults: | |
run: | |
shell: bash -l {0} | |
steps: | |
- name: Display run details | |
run: | | |
echo "=============================================================" | |
echo "Run #${GITHUB_RUN_NUMBER}" | |
echo "Run ID: ${GITHUB_RUN_ID}" | |
echo "Testing: ${GITHUB_REPOSITORY}" | |
echo "Triggered by: ${GITHUB_EVENT_NAME}" | |
echo "Initiated by: ${GITHUB_ACTOR}" | |
echo "=============================================================" | |
- name: Create SSH key | |
if: (matrix.SNOPT || matrix.BUILD_DOCS) | |
env: | |
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} | |
SSH_KNOWN_HOSTS: ${{ secrets.SSH_KNOWN_HOSTS }} | |
run: | | |
mkdir -p ~/.ssh/ | |
echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa | |
sudo chmod 600 ~/.ssh/id_rsa | |
echo "$SSH_KNOWN_HOSTS" > ~/.ssh/known_hosts | |
- name: Checkout code | |
uses: actions/checkout@v3 | |
- name: Fetch tags | |
run: | | |
git fetch --prune --unshallow --tags | |
- name: Setup conda | |
uses: conda-incubator/setup-miniconda@v2 | |
with: | |
python-version: ${{ matrix.PY }} | |
conda-version: "*" | |
channels: conda-forge,defaults | |
channel-priority: true | |
- name: Install OpenMDAO | |
run: | | |
conda install numpy=${{ matrix.NUMPY }} scipy=${{ matrix.SCIPY }} -q -y | |
python -m pip install --upgrade pip | |
echo "=============================================================" | |
echo "Install OpenMDAO" | |
echo "=============================================================" | |
python -m pip install .${{ matrix.OPTIONAL }} | |
- name: Install jax | |
if: matrix.JAX | |
run: | | |
echo "=============================================================" | |
echo "Install jax" | |
echo "=============================================================" | |
python -m pip install jaxlib=='${{ matrix.JAX }}' jax=='${{ matrix.JAX }}' | |
- name: Install PETSc | |
if: matrix.PETSc | |
run: | | |
echo "=============================================================" | |
echo "Install compilers for PETSc" | |
echo "=============================================================" | |
if [[ "${{ matrix.OPENMPI }}" ]]; then | |
COMPILERS="cython compilers openmpi-mpicc=${{ matrix.OPENMPI }}" | |
else | |
COMPILERS="cython compilers openmpi-mpicc" | |
fi | |
conda install $COMPILERS -q -y | |
echo "=============================================================" | |
echo "Install PETSc" | |
echo "=============================================================" | |
if [[ "${{ matrix.PETSc }}" == "3" ]]; then | |
python -m pip install git+https://github.com/mpi4py/mpi4py | |
python -m pip install petsc petsc4py | |
else | |
if [[ "${{ matrix.MPI4PY }}" ]]; then | |
conda install mpi4py=${{ matrix.MPI4PY }} petsc4py=${{ matrix.PETSc }} -q -y | |
else | |
conda install mpi4py petsc4py=${{ matrix.PETSc }} -q -y | |
fi | |
fi | |
echo "=============================================================" | |
echo "Check MPI and PETSc installation" | |
echo "=============================================================" | |
export OMPI_MCA_rmaps_base_oversubscribe=1 | |
echo "-----------------------" | |
echo "Quick test of mpi4py:" | |
mpirun -n 3 python -c "from mpi4py import MPI; print(f'Rank: {MPI.COMM_WORLD.rank}')" | |
echo "-----------------------" | |
echo "Quick test of petsc4py:" | |
mpirun -n 3 python -c "import numpy; from mpi4py import MPI; comm = MPI.COMM_WORLD; \ | |
import petsc4py; petsc4py.init(); \ | |
x = petsc4py.PETSc.Vec().createWithArray(numpy.ones(5)*comm.rank, comm=comm); \ | |
print(x.getArray())" | |
echo "-----------------------" | |
echo "OMPI_MCA_rmaps_base_oversubscribe=1" >> $GITHUB_ENV | |
echo "Workaround for intermittent failures with OMPI https://github.com/open-mpi/ompi/issues/7393" | |
echo "TMPDIR=/tmp" >> $GITHUB_ENV | |
- name: Install pyOptSparse | |
if: matrix.PYOPTSPARSE | |
run: | | |
echo "=============================================================" | |
echo "Install pyoptsparse" | |
echo "=============================================================" | |
if [[ "${{ matrix.PYOPTSPARSE }}" == "conda-forge" ]]; then | |
if [[ "${{ matrix.SNOPT }}" ]]; then | |
echo "SNOPT ${{ matrix.SNOPT }} was requested but is not available on conda-forge" | |
fi | |
conda install -c conda-forge pyoptsparse | |
else | |
python -m pip install git+https://github.com/OpenMDAO/build_pyoptsparse | |
if [[ "${{ matrix.PYOPTSPARSE }}" == "latest" ]]; then | |
function latest_version() { | |
local REPO_URL=$1/releases/latest | |
local LATEST_URL=`curl -fsSLI -o /dev/null -w %{url_effective} $REPO_URL` | |
local LATEST_VER=`echo $LATEST_URL | awk '{split($0,a,"/tag/"); print a[2]}'` | |
echo $LATEST_VER | |
} | |
BRANCH="-b $(latest_version https://github.com/mdolab/pyoptsparse)" | |
else | |
BRANCH="-b ${{ matrix.PYOPTSPARSE }}" | |
fi | |
if [[ "${{ matrix.PAROPT }}" ]]; then | |
PAROPT="-a" | |
fi | |
if [[ "${{ matrix.SNOPT }}" == "7.7" && "${{ secrets.SNOPT_LOCATION_77 }}" ]]; then | |
echo " > Secure copying SNOPT 7.7 over SSH" | |
mkdir SNOPT | |
scp -qr ${{ secrets.SNOPT_LOCATION_77 }} SNOPT | |
SNOPT="-s SNOPT/src" | |
elif [[ "${{ matrix.SNOPT }}" == "7.2" && "${{ secrets.SNOPT_LOCATION_72 }}" ]]; then | |
echo " > Secure copying SNOPT 7.2 over SSH" | |
mkdir SNOPT | |
scp -qr ${{ secrets.SNOPT_LOCATION_72 }} SNOPT | |
SNOPT="-s SNOPT/source" | |
elif [[ "${{ matrix.SNOPT }}" ]]; then | |
echo "SNOPT version ${{ matrix.SNOPT }} was requested but source is not available" | |
fi | |
build_pyoptsparse $BRANCH $PAROPT $SNOPT | |
fi | |
- name: Install optional dependencies | |
if: matrix.OPTIONAL == '[all]' | |
run: | | |
echo "=============================================================" | |
echo "Install additional packages for testing/coverage" | |
echo "=============================================================" | |
python -m pip install pyparsing psutil objgraph pyxdsm | |
- name: Display environment info | |
run: | | |
conda info | |
conda list | |
echo "=============================================================" | |
echo "Check installed versions of Python, Numpy and Scipy" | |
echo "=============================================================" | |
python -c "import platform; assert platform.python_version().startswith(str(${{ matrix.PY }})), \ | |
f'Python version {platform.python_version()} is not the requested version (${{ matrix.PY }})'" | |
python -c "import numpy; assert str(numpy.__version__).startswith(str(${{ matrix.NUMPY }})), \ | |
f'Numpy version {numpy.__version__} is not the requested version (${{ matrix.NUMPY }})'" | |
python -c "import scipy; assert str(scipy.__version__).startswith(str(${{ matrix.SCIPY }})), \ | |
f'Scipy version {scipy.__version__} is not the requested version (${{ matrix.SCIPY }})'" | |
- name: Setup tmate session | |
if: matrix.DEBUG | |
uses: mxschmitt/action-tmate@v3 | |
- name: Run tests | |
if: matrix.TESTS | |
run: | | |
echo "=============================================================" | |
echo "Run tests with coverage (from directory other than repo root)" | |
echo "=============================================================" | |
echo "############ .coveragerc contents #################" | |
cat .coveragerc | |
echo "###################################################" | |
cp .coveragerc $HOME | |
cd $HOME | |
testflo -n 2 openmdao --timeout=240 --show_skipped --coverage --coverpkg openmdao --durations=20 | |
- name: Submit coverage | |
if: matrix.TESTS | |
env: | |
COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
COVERALLS_SERVICE_NAME: "github" | |
COVERALLS_PARALLEL: true | |
run: | | |
echo "=============================================================" | |
echo "Submit coverage" | |
echo "=============================================================" | |
cp $HOME/.coverage . | |
python -m pip install coveralls | |
SITE_DIR=`python -c 'import site; print(site.getsitepackages()[-1])'` | |
coveralls --basedir $SITE_DIR | |
- name: Build docs | |
if: matrix.BUILD_DOCS | |
id: build_docs | |
run: | | |
export OPENMDAO_REPORTS=0 | |
export PYDEVD_DISABLE_FILE_VALIDATION=1 | |
cd openmdao/docs | |
if [[ "${{ secrets.SNOPT_LOCATION_72 }}" || "${{ secrets.SNOPT_LOCATION_77 }}" ]]; then | |
echo "=============================================================" | |
echo "Building docs with SNOPT examples." | |
echo "=============================================================" | |
else | |
echo "=============================================================" | |
echo "Disabling SNOPT cells in notebooks." | |
echo "=============================================================" | |
python openmdao_book/other/disable_snopt_cells.py | |
fi | |
# start ipcluster to run MPI under notebooks | |
./ipcluster_start.sh | |
sleep 12 | |
echo "=============================================================" | |
echo "Build the docs" | |
echo "=============================================================" | |
python build_source_docs.py | |
jupyter-book build openmdao_book | |
python copy_build_artifacts.py | |
- name: Display doc build reports | |
if: failure() && matrix.BUILD_DOCS && steps.build_docs.outcome == 'failure' | |
run: | | |
for f in /home/runner/work/OpenMDAO/OpenMDAO/openmdao/docs/openmdao_book/_build/html/reports/*; do | |
echo "=============================================================" | |
echo $f | |
echo "=============================================================" | |
cat $f | |
done | |
- name: Publish docs | |
if: ${{ github.event_name == 'push' && matrix.BUILD_DOCS }} | |
env: | |
DOCS_LOCATION: ${{ secrets.DOCS_LOCATION }} | |
run: | | |
if [[ "${#DOCS_LOCATION}" ]]; then | |
echo "=============================================================" | |
echo "Publish docs" | |
echo "=============================================================" | |
cd openmdao/docs | |
python upload_doc_version.py openmdao_book/_build/html/ ${{ secrets.DOCS_LOCATION }} | |
else | |
echo "Docs destination not available." | |
fi | |
- name: Scan for security issues | |
if: matrix.BANDIT | |
id: bandit | |
run: | | |
python -m pip install bandit | |
echo "=============================================================" | |
echo "Run bandit scan for high/medium severity issues" | |
echo "=============================================================" | |
cd $GITHUB_WORKSPACE | |
python -m bandit -c bandit.yml -ll -r openmdao | |
- name: Notify slack | |
uses: act10ns/slack@v1.6.0 | |
env: | |
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} | |
with: | |
status: ${{ job.status }} | |
if: always() | |
windows_tests: | |
runs-on: windows-latest | |
timeout-minutes: 60 | |
strategy: | |
fail-fast: false | |
matrix: | |
include: | |
# baseline versions | |
- NAME: Windows Baseline | |
PY: '3.10' | |
NUMPY: 1.22 | |
SCIPY: 1.7 | |
PYOPTSPARSE: '2.9.1' | |
name: ${{ matrix.NAME }} | |
defaults: | |
run: | |
shell: pwsh | |
steps: | |
- name: Display run details | |
run: | | |
echo "=============================================================" | |
echo "Run #$env:GITHUB_RUN_NUMBER" | |
echo "Run ID: $env:GITHUB_RUN_ID" | |
echo "Testing: $env:GITHUB_REPOSITORY" | |
echo "Triggered by: $env:GITHUB_EVENT_NAME" | |
echo "Initiated by: $env:GITHUB_ACTOR" | |
echo "=============================================================" | |
- name: Checkout code | |
uses: actions/checkout@v3 | |
- name: Fetch tags | |
run: | | |
git fetch --prune --unshallow --tags | |
- name: Setup conda | |
uses: conda-incubator/setup-miniconda@v2 | |
with: | |
python-version: ${{ matrix.PY }} | |
conda-version: "*" | |
channels: conda-forge,defaults | |
channel-priority: true | |
- name: Install OpenDMAO | |
run: | | |
conda install numpy=${{ matrix.NUMPY }} scipy=${{ matrix.SCIPY }} -q -y | |
python -m pip install --upgrade pip | |
echo "=============================================================" | |
echo "Install lxml for Windows (No Python 3.11 version on pypi)" | |
echo "=============================================================" | |
conda install lxml | |
echo "=============================================================" | |
echo "Install OpenMDAO" | |
echo "=============================================================" | |
python -m pip install .[all] | |
- name: Install pyOptSparse | |
if: matrix.PYOPTSPARSE | |
run: | | |
echo "=============================================================" | |
echo "Install pyoptsparse from conda-forge" | |
echo "=============================================================" | |
conda install -c conda-forge pyoptsparse=${{ matrix.PYOPTSPARSE }} -q -y | |
- name: Install optional dependencies | |
run: | | |
echo "=============================================================" | |
echo "Install additional packages for testing/coverage" | |
echo "=============================================================" | |
python -m pip install psutil objgraph git+https://github.com/mdolab/pyxdsm | |
- name: Display environment info | |
run: | | |
conda info | |
conda list | |
echo "=============================================================" | |
echo "Check installed versions of Python, Numpy and Scipy" | |
echo "=============================================================" | |
python -c "import sys; assert str(sys.version).startswith(str(${{ matrix.PY }})), \ | |
f'Python version {sys.version} is not the requested version (${{ matrix.PY }})'" | |
python -c "import numpy; assert str(numpy.__version__).startswith(str(${{ matrix.NUMPY }})), \ | |
f'Numpy version {numpy.__version__} is not the requested version (${{ matrix.NUMPY }})'" | |
python -c "import scipy; assert str(scipy.__version__).startswith(str(${{ matrix.SCIPY }})), \ | |
f'Scipy version {scipy.__version__} is not the requested version (${{ matrix.SCIPY }})'" | |
- name: Run tests | |
run: | | |
echo "=============================================================" | |
echo "Run tests with coverage (from directory other than repo root)" | |
echo "=============================================================" | |
copy .coveragerc $HOME | |
cd $HOME | |
testflo -n 2 openmdao --timeout=240 --show_skipped --coverage --coverpkg openmdao --durations=20 | |
- name: Submit coverage | |
env: | |
COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
COVERALLS_SERVICE_NAME: "github" | |
COVERALLS_PARALLEL: true | |
run: | | |
echo "=============================================================" | |
echo "Submit coverage" | |
echo "=============================================================" | |
copy $HOME\.coverage . | |
python -m pip install coveralls | |
$SITE_DIR=python -c "import site; print(site.getsitepackages()[-1].replace('lib\\site-', 'Lib\\site-'))" | |
coveralls --basedir $SITE_DIR | |
- name: Notify slack | |
uses: act10ns/slack@v2.0.0 | |
with: | |
webhook-url: ${{ secrets.SLACK_WEBHOOK_URL }} | |
status: ${{ job.status }} | |
if: always() | |
coveralls: | |
name: Finish coverage | |
needs: [tests, windows_tests] | |
runs-on: ubuntu-latest | |
steps: | |
- uses: coverallsapp/github-action@master | |
with: | |
github-token: ${{ secrets.GITHUB_TOKEN }} | |
parallel-finished: true | |
dymos_tests: | |
name: Run Dymos Tests | |
needs: [tests, windows_tests] | |
runs-on: ubuntu-latest | |
steps: | |
- uses: benc-uk/workflow-dispatch@v1 | |
with: | |
workflow: Dymos Tests | |
repo: ${{ github.repository_owner }}/dymos | |
token: ${{ secrets.ACCESS_TOKEN }} | |
if: github.event_name == 'push' |