NEURON ModelDB CI #1665
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
name: NEURON ModelDB CI | |
on: | |
push: | |
branches: [master] | |
pull_request: | |
branches: [ master ] | |
schedule: | |
# Run at 2am every day | |
- cron: '0 2 * * *' | |
workflow_call: | |
inputs: | |
neuron_v1: | |
description: Last official release (neuron) / NEURON pinned version / Azure drop (artifacts) url | |
default: 'neuron' | |
required: true | |
type: string | |
neuron_v2: | |
description: Last nightly release (neuron-nightly) / NEURON pinned version / Azure drop (artifacts) url | |
default: 'neuron-nightly' | |
required: true | |
type: string | |
models_to_run: | |
description: 'Empty for all models, space separated accession numbers for specific models' | |
default: '' | |
required: false | |
type: string | |
repo: | |
default: 'neuronsimulator/nrn-modeldb-ci' | |
type: string | |
required: false | |
workflow_dispatch: | |
inputs: | |
neuron_v1: | |
description: Last official release (neuron) / NEURON pinned version / Azure drop (artifacts) url | |
default: 'neuron' | |
required: true | |
neuron_v2: | |
description: Last nightly release (neuron-nightly) / NEURON pinned version / Azure drop (artifacts) url | |
default: 'neuron-nightly' | |
required: true | |
models_to_run: | |
description: 'Empty for all models, space separated accession numbers for specific models' | |
default: '' | |
required: false | |
jobs: | |
nrn-modeldb-ci: | |
runs-on: ubuntu-latest | |
strategy: | |
fail-fast: false | |
env: | |
DISPLAY: ${{ ':0' }} | |
NEURON_V1: ${{ github.event.inputs.neuron_v1 || inputs.neuron_v1 || 'neuron' }} | |
NEURON_V2: ${{ github.event.inputs.neuron_v2 || inputs.neuron_v2 || 'neuron-nightly' }} | |
MODELS_TO_RUN: ${{ github.event.inputs.models_to_run || inputs.models_to_run || '' }} | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
repository: ${{ inputs.repo || github.repository }} | |
- name: check for Azure drop NEURON_V1 -> ${{ env.NEURON_V1 }} | |
if: startsWith(env.NEURON_V1, 'https://dev.azure.com/neuronsimulator/') | |
run: | | |
# check URI | |
curl -sfSI -X GET '${{ env.NEURON_V1 }}' | |
# Download Azure drop and unzip | |
AZURE_DROP_URL="$NEURON_V1" | |
rm -rf drop | |
wget --tries=4 -LO DROP_V1.zip ${AZURE_DROP_URL} | |
unzip DROP_V1.zip | |
mv drop DROP_V1 | |
# Set drop dir in the env | |
echo "DROP_DIR_V1=`pwd`/DROP_V1" >> $GITHUB_ENV | |
- name: check for Azure drop NEURON_V2 -> ${{ env.NEURON_V2 }} | |
if: startsWith(env.NEURON_V2, 'https://dev.azure.com/neuronsimulator/') | |
run: | | |
# check URI | |
curl -sfSI -X GET '${{ env.NEURON_V2 }}' | |
# Download Azure drop and unzip | |
AZURE_DROP_URL="$NEURON_V2" | |
rm -rf drop | |
wget --tries=4 -LO DROP_V2.zip ${AZURE_DROP_URL} | |
unzip DROP_V2.zip | |
mv drop DROP_V2 | |
# Set drop dir in the env | |
echo "DROP_DIR_V2=`pwd`/DROP_V2" >> $GITHUB_ENV | |
- uses: actions/setup-python@v5 | |
with: | |
python-version: 3.9 | |
- name: Set models to run for PR | |
run: | | |
# For PRs we only have a few models for quick sanity checking. | |
# Once the PR is green you need to manually run the ModelDB CI workflow by simply selecting your branch in the UI. | |
# The follwing selection aims to target different features (since we haven't worked on unit testing yet -> #38 ). | |
# Select a few models to run CI for PRs: | |
# 64195 -> run: null | |
# 22203 -> skip: true | |
# 156120 -> several model directories | |
# 97868 -> failed nrnivmodl | |
# 146030 -> curate_patterns | |
# 244679 -> no entry in modeldb-run.yaml | |
# rest: -> currently yielding differences in the pipeline | |
echo 'MODELS_TO_RUN=64195 22203 156120 51781 97868 22203 97756 97917 105507 136803 138379 138382 146030 244679 251881' >> $GITHUB_ENV | |
# parse PR description for models to run | |
parse_models=$(gh pr view $PR_URL --json body -q '.body | capture("(MODELS_TO_RUN=)(?<models>\\d+( \\d+)*)")') | |
if [ ! -z "$parse_models" ]; then | |
echo "MODELS_TO_RUN=$(echo $parse_models | jq -r .models)" >> $GITHUB_ENV | |
fi | |
if: github.event_name == 'pull_request' && inputs.repo == '' | |
env: | |
PR_URL: ${{ github.event.pull_request.html_url }} | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
- name: Install dependencies and project | |
id: install-deps | |
run: | | |
set | |
# Set up Xvfb | |
sudo apt-get install xvfb | |
sudo /usr/bin/Xvfb $DISPLAY -screen 0 1600x1200x24 -noreset -nolock -shmem & # run in bg | |
# Install python dependencies | |
python -m pip install --upgrade 'pip<=24.0' | |
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi | |
#Install project in editable mode | |
python -m pip install -e . | |
- name: Cache ModelDB models | |
uses: actions/cache@v4 | |
with: | |
path: | | |
cache | |
modeldb/modeldb-meta.yaml | |
key: dynamic-models | |
- name: Get ModelDB models | |
run: getmodels $MODELS_TO_RUN | |
- name: Run Models with NEURON V1 -> ${{ env.NEURON_V1 }} | |
run: | | |
# Install NEURON V1 | |
if [[ -d "${DROP_DIR_V1}" ]]; then | |
# due to https://github.com/pypa/pip/issues/12110 we cannot rely on `--find-links` | |
# so we use a workaround | |
for wheel in "${DROP_DIR_V1}"/*.whl | |
do | |
if ! python -m pip install --user "${wheel}" | |
then | |
echo "Unable to install ${wheel}, trying another one" | |
else | |
echo "Successfully installed ${wheel}" | |
break | |
fi | |
done | |
else | |
python -m pip install $NEURON_V1 | |
fi | |
nrn_ver=`python -c "from neuron import __version__ as nrn_ver; print(nrn_ver)"` | |
runmodels --gout --workdir=$nrn_ver $MODELS_TO_RUN | |
# Filter out the gout data before generating HTML reports. The HTML | |
# diff uses the original gout files on disk anyway. Compress the large | |
# JSON file including gout data for inclusion in the artifacts | |
mv ${nrn_ver}.json ${nrn_ver}-full.json | |
jq -r 'del(.[].gout)' ${nrn_ver}-full.json > ${nrn_ver}.json | |
xz ${nrn_ver}-full.json | |
report2html ${nrn_ver}.json | |
if [[ -d "${DROP_DIR_V1}" ]]; then | |
python -m pip uninstall --yes neuron-nightly==${nrn_ver} | |
else | |
python -m pip uninstall --yes $NEURON_V1 | |
fi | |
echo "nrn1_ver=$nrn_ver" >> $GITHUB_ENV | |
- name: Run Models with NEURON V2 -> ${{ env.NEURON_V2 }} | |
if: env.NEURON_V1 != env.NEURON_V2 | |
run: | | |
# Install NEURON V2 | |
if [[ -d "${DROP_DIR_V2}" ]]; then | |
# due to https://github.com/pypa/pip/issues/12110 we cannot rely on `--find-links` | |
# so we use a workaround | |
for wheel in "${DROP_DIR_V2}"/*.whl | |
do | |
if ! python -m pip install --user "${wheel}" | |
then | |
echo "Unable to install ${wheel}, trying another one" | |
else | |
echo "Successfully installed ${wheel}" | |
break | |
fi | |
done | |
else | |
python -m pip install $NEURON_V2 | |
fi | |
nrn_ver=`python -c "from neuron import __version__ as nrn_ver; print(nrn_ver)"` | |
runmodels --gout --workdir=$nrn_ver $MODELS_TO_RUN | |
# Filter out the gout data before generating HTML reports. The HTML | |
# diff uses the original gout files on disk anyway. Compress the large | |
# JSON file including gout data for inclusion in the artifacts | |
mv ${nrn_ver}.json ${nrn_ver}-full.json | |
jq -r 'del(.[].gout)' ${nrn_ver}-full.json > ${nrn_ver}.json | |
xz ${nrn_ver}-full.json | |
report2html ${nrn_ver}.json | |
if [[ -d "${DROP_DIR_V2}" ]]; then | |
python -m pip uninstall --yes neuron-nightly==${nrn_ver} | |
else | |
python -m pip uninstall --yes $NEURON_V2 | |
fi | |
echo "nrn2_ver=$nrn_ver" >> $GITHUB_ENV | |
- name: diffreports2html ${{ env.nrn1_ver }}.json <-> ${{ env.nrn2_ver }}.json | |
if: env.NEURON_V1 != env.NEURON_V2 | |
run: | | |
diffreports2html ${nrn1_ver}.json ${nrn2_ver}.json | |
- uses: actions/upload-artifact@v4 | |
if: ${{ always() }} | |
with: | |
name: ${{ env.nrn1_ver }}-vs-${{ env.nrn2_ver }} | |
path: | | |
./*.json.xz | |
./*.html |