Skip to content

NEURON ModelDB CI #1625

NEURON ModelDB CI

NEURON ModelDB CI #1625

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