diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml deleted file mode 100644 index afd8251f73..0000000000 --- a/.github/workflows/coverage.yml +++ /dev/null @@ -1,292 +0,0 @@ -name: NEURON Code Coverage - -concurrency: - # Don't cancel on master, creating a PR when a push workflow is already going will cancel the push workflow in favour of the PR workflow - group: ${{ github.workflow }}-${{ github.ref == 'refs/heads/master' && github.run_id || github.event.number && github.head_ref || github.ref_name }} - cancel-in-progress: true - -on: - merge_group: - push: - branches: - - master - - release/** - pull_request: - branches: - - master - - release/** -# TODO : https://github.com/neuronsimulator/nrn/issues/1063 -# paths-ignore: -# - '**.md' -# - '**.rst' -# - 'docs/**' - -env: - PY_MIN_VERSION: '3.9' - PY_MID_VERSION: '3.10' - PY_MAX_VERSION: '3.14' - # The Linux runners have 4 cores: - # https://docs.github.com/en/actions/using-github-hosted-runners/using-github-hosted-runners/about-github-hosted-runners#standard-github-hosted-runners-for-public-repositories - CMAKE_BUILD_PARALLEL_LEVEL: '4' - CTEST_PARALLEL_LEVEL: '4' - CCACHE_DIR: ${{ github.workspace }}/ccache - -jobs: - coverage: - runs-on: ubuntu-22.04 - - name: Code Coverage - - timeout-minutes: 60 - - env: - DISPLAY: ${{ ':0' }} - MUSIC_INSTALL_DIR: /opt/MUSIC - # hash of commit containing mpi4py 4 fix - MUSIC_VERSION: '13f312338dcccebfe74d391b1b24f1b6d816ac6c' - - steps: - - - name: Install apt packages - run: | - sudo apt-get install xfonts-100dpi build-essential doxygen lcov libboost-all-dev libopenmpi-dev libmpich-dev libx11-dev libxcomposite-dev mpich openmpi-bin gpg ninja-build flex bison libfl-dev - shell: bash - - - name: Install a new ccache - run: | - # versions older than 4.10 do not support -fprofile-update=atomic - wget 'https://github.com/ccache/ccache/releases/download/v4.11.3/ccache-4.11.3-linux-x86_64.tar.xz' - tar xf ccache-4.11.3-linux-x86_64.tar.xz - sudo cp -a ccache-4.11.3-linux-x86_64/ccache /usr/bin/ccache - working-directory: ${{runner.temp}} - - - name: Setup cmake - uses: jwlawson/actions-setup-cmake@v2 - with: - cmake-version : '3.19' - - - name: Setup Caliper profiler - run: | - git clone --branch v2.12.1 --depth 1 --recurse-submodules --shallow-submodules https://github.com/LLNL/Caliper.git - cd Caliper - cmake -B build -G Ninja . - sudo cmake --build build --target install - working-directory: ${{runner.temp}} - - - name: Setup Xvfb - run: | - sudo apt-get install xvfb - sudo /usr/bin/Xvfb $DISPLAY -screen 0 1600x1200x24 -noreset -nolock -shmem & # run in bg - - - uses: actions/checkout@v4 - with: - fetch-depth: 2 - - # Restore (and later save) dependencies for min version of Python - - name: Restore Python@${{ env.PY_MIN_VERSION }} dependencies - id: cache-python-min-packages-restore - uses: actions/cache/restore@v4 - with: - path: ${{ github.workspace }}/pip_cache${{ env.PY_MIN_VERSION }} - key: cache-${{ env.PY_MIN_VERSION }}-${{ hashFiles('ci/requirements.txt') }} - - - name: Set up Python@${{ env.PY_MIN_VERSION }} - uses: actions/setup-python@v5 - with: - python-version: ${{ env.PY_MIN_VERSION }} - - - name: Install Python@${{ env.PY_MIN_VERSION }} dependencies - working-directory: ${{runner.workspace}}/nrn - run: | - python -m pip install -r ci/uv_requirements.txt - python -m uv pip install -r ci/requirements.txt --cache-dir ${{ github.workspace }}/pip_cache${{ env.PY_MIN_VERSION }} - - - name: Save Python@${{ env.PY_MIN_VERSION }} dependencies - id: cache-python-min-packages-save - if: always() && steps.cache-python-min-packages-restore.outputs.cache-hit != 'true' - uses: actions/cache/save@v4 - with: - key: ${{ steps.cache-python-min-packages-restore.outputs.cache-primary-key }} - path: ${{ github.workspace }}/pip_cache${{ env.PY_MIN_VERSION }} - - # Restore (and later save) dependencies for mid version of Python - - name: Restore Python@${{ env.PY_MID_VERSION }} dependencies - id: cache-python-mid-packages-restore - uses: actions/cache/restore@v4 - with: - path: ${{ github.workspace }}/pip_cache${{ env.PY_MID_VERSION }} - key: cache-${{ env.PY_MID_VERSION }}-${{ hashFiles('ci/requirements.txt') }} - - - name: Set up Python@${{ env.PY_MID_VERSION }} - uses: actions/setup-python@v5 - with: - python-version: ${{ env.PY_MID_VERSION }} - - - name: Install Python@${{ env.PY_MID_VERSION }} dependencies - working-directory: ${{runner.workspace}}/nrn - run: | - python -m pip install -r ci/uv_requirements.txt - python -m uv pip install -r ci/requirements.txt --cache-dir ${{ github.workspace }}/pip_cache${{ env.PY_MID_VERSION }} - - - name: Save Python@${{ env.PY_MID_VERSION }} dependencies - id: cache-python-mid-packages-save - if: always() && steps.cache-python-mid-packages-restore.outputs.cache-hit != 'true' - uses: actions/cache/save@v4 - with: - key: ${{ steps.cache-python-mid-packages-restore.outputs.cache-primary-key }} - path: ${{ github.workspace }}/pip_cache${{ env.PY_MID_VERSION }} - - # Restore (and later save) dependencies for max version of Python - - name: Restore Python@${{ env.PY_MAX_VERSION }} dependencies - id: cache-python-max-packages-restore - uses: actions/cache/restore@v4 - with: - path: ${{ github.workspace }}/pip_cache${{ env.PY_MAX_VERSION }} - key: cache-${{ env.PY_MAX_VERSION }}-${{ hashFiles('ci/requirements.txt') }} - - - name: Set up Python@${{ env.PY_MAX_VERSION }} - uses: actions/setup-python@v5 - with: - python-version: ${{ env.PY_MAX_VERSION }} - - - name: Install Python@${{ env.PY_MAX_VERSION }} dependencies - working-directory: ${{runner.workspace}}/nrn - run: | - python -m pip install -r ci/uv_requirements.txt - python -m uv pip install -r ci/requirements.txt --cache-dir ${{ github.workspace }}/pip_cache${{ env.PY_MAX_VERSION }} - - - name: Save Python@${{ env.PY_MAX_VERSION }} dependencies - id: cache-python-max-packages-save - if: always() && steps.cache-python-max-packages-restore.outputs.cache-hit != 'true' - uses: actions/cache/save@v4 - with: - key: ${{ steps.cache-python-max-packages-restore.outputs.cache-primary-key }} - path: ${{ github.workspace }}/pip_cache${{ env.PY_MAX_VERSION }} - - - name: Setup MUSIC@${{ env.MUSIC_VERSION }} - run: | - python -m venv music-venv - source music-venv/bin/activate - python -m pip install -r ${{ github.workspace }}/ci/uv_requirements.txt - python -m uv pip install -r ${{ github.workspace }}/ci/requirements.txt --cache-dir ${{ github.workspace }}/pip_cache${{ env.PY_MAX_VERSION }} - sudo mkdir -p $MUSIC_INSTALL_DIR - sudo chown -R $USER $MUSIC_INSTALL_DIR - curl -L -o MUSIC.zip https://github.com/INCF/MUSIC/archive/${MUSIC_VERSION}.zip - unzip MUSIC.zip && mv MUSIC-* MUSIC && cd MUSIC - ./autogen.sh - ./configure --with-python-sys-prefix --prefix=$MUSIC_INSTALL_DIR --disable-anysource - make -j install - deactivate - working-directory: ${{runner.temp}} - - # Restore (and later save) ccache - - name: Restore compiler cache - id: restore-compiler-cache - uses: actions/cache/restore@v4 - with: - path: ${{ github.workspace }}/ccache - key: ccache-coverage-${{runner.os}}-${{github.ref_name}} - restore-keys: | - ccache-coverage-${{runner.os}}-master - - - name: Build & Test - id: build-test - shell: bash - working-directory: ${{runner.workspace}}/nrn - run: | - export SHELL="/bin/bash" - - # Compiler setup - export CC=gcc - export CXX=g++ - - # Python setup - export PYTHON_MIN=$(which $PYTHON_MIN_NAME); - export PYTHON_MID=$(which $PYTHON_MID_NAME); - export PYTHON_MAX=$(which $PYTHON_MAX_NAME); - - # Update all submodules with depth 1 - git submodule update --init --recursive --depth 1 - - mkdir build && cd build; - - # CMake options & flags - cmake_args=(-G Ninja \ - -DCMAKE_BUILD_TYPE=Debug \ - -DCMAKE_C_COMPILER="$CC" \ - -DCMAKE_CXX_COMPILER="$CXX" \ - -DCMAKE_C_COMPILER_LAUNCHER=ccache \ - -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ - -DNRN_ENABLE_BACKTRACE=ON \ - -DNRN_ENABLE_CORENEURON=ON \ - -DNRN_ENABLE_COVERAGE=ON \ - -DNRN_ENABLE_INTERVIEWS=ON \ - -DNRN_ENABLE_MPI=ON \ - -DNRN_ENABLE_PERFORMANCE_TESTS=OFF \ - -DNRN_ENABLE_PROFILING=ON \ - -DNRN_ENABLE_PYTHON=ON \ - -DNRN_ENABLE_PYTHON_DYNAMIC=ON \ - -DNRN_PYTHON_DYNAMIC="${PYTHON_MIN};${PYTHON_MAX}" \ - -DNRN_PYTHON_EXTRA_FOR_TESTS=${PYTHON_MID} \ - -DNRN_ENABLE_TESTS=ON \ - -DNRN_ENABLE_MUSIC=ON \ - -DCMAKE_PREFIX_PATH="${MUSIC_INSTALL_DIR}" \ - -DMUSIC_ROOT="${MUSIC_INSTALL_DIR}") - cmake .. "${cmake_args[@]}" - # Coverage - ccache -z - ccache -s -v || ccache -s - cmake --build . - ccache -s -v || ccache -s - cmake --build . --target cover_baseline - xvfb-run ctest --rerun-failed --output-on-failure - for python in "${PYTHON_MIN}" "${PYTHON_MAX}" - do - echo "Using ${python}" - NEURONHOME="${PWD}/share/nrn" \ - PYTHONPATH="${PWD}/lib/python:${PYTHONPATH}" \ - PATH="${PWD}/bin:${PATH}" \ - LD_LIBRARY_PATH="${PWD}/lib:${LD_LIBRARY_PATH}" \ - DYLD_LIBRARY_PATH="${PWD}/lib:${DYLD_LIBRARY_PATH}" \ - "${python}" -c "from neuron import h; import neuron; neuron.test();neuron.test_rxd(); from neuron.tests import test_nmodl; test_nmodl.test_nmodl()" - done - cmake --build . --target cover_collect - cmake --build . --target cover_combine - env: - MATRIX_EVAL: "CC=gcc CXX=g++" - PYTHON_MIN_NAME: "python${{ env.PY_MIN_VERSION }}" - PYTHON_MID_NAME: "python${{ env.PY_MID_VERSION }}" - PYTHON_MAX_NAME: "python${{ env.PY_MAX_VERSION }}" - - - name: Upload build artifacts - if: always() - uses: actions/upload-artifact@v4 - with: - name: coverage-${{runner.os}} - path: | - ${{runner.workspace}}/nrn/build/CMakeCache.txt - ${{runner.workspace}}/nrn/build/build.ninja - ${{runner.workspace}}/nrn/build/cmake_install.cmake - - - name: Save compiler cache - id: save-compiler-cache - if: always() && steps.restore-compiler-cache.outputs.cache-hit != 'true' - uses: actions/cache/save@v4 - with: - key: ${{ steps.restore-compiler-cache.outputs.cache-primary-key }} - path: ${{ github.workspace }}/ccache - - # This step will set up an SSH connection on tmate.io for live debugging. - # To enable it, you have to: - # * add 'live-debug-coverage' to your PR title - # * push something to your PR branch (note that just re-running the pipeline disregards the title update) - - name: live debug session on failure (manual steps required, check `.github/coverage.yml`) - if: failure() && contains(github.event.pull_request.title, 'live-debug-coverage') - uses: mxschmitt/action-tmate@v3 - - - uses: codecov/codecov-action@v4 - with: - directory: ./build - fail_ci_if_error: true - verbose: true - token: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/external.yml b/.github/workflows/external.yml deleted file mode 100644 index ab06e55459..0000000000 --- a/.github/workflows/external.yml +++ /dev/null @@ -1,71 +0,0 @@ -name: External CIs - -concurrency: - # Don't cancel on master, creating a PR when a push workflow is already going will cancel the push workflow in favour of the PR workflow - group: ${{ github.workflow }}-${{ github.ref == 'refs/heads/master' && github.run_id || github.event.number && github.head_ref || github.ref_name }} - cancel-in-progress: true - -on: - pull_request: - types: [ labeled ] -env: - PR_URL: ${{ github.event.pull_request.html_url }} - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - -jobs: - get-last-azure-url: - runs-on: ubuntu-latest - if: ${{ github.event.label.name == 'nrn-modeldb-ci-nightly' }} - outputs: - azure_drop_url: ${{ steps.drop.outputs.azure_drop_url }} - pr_azure_sha: ${{ steps.drop.outputs.pr_azure_sha }} - steps: - - id: drop - run: | - # use jq to get the last Azure drop URL from the PR and the SHA1 from the same body - export pr_json=$(gh pr view $PR_URL --json comments -q 'last(.comments[] .body | capture(".*(?[0-9a-f]{40}).*?(?https://dev.azure.com/neuronsimulator/.*=zip)"))') - if [ -z "$pr_json" ]; then - echo "Unable to retrieve AZURE drop url and SHA from comments!" - exit 1 - fi - # use jq to get pr_azure_sha and azure_drop_url from the json - export azure_drop_url=$(echo $pr_json | jq -r .azure_drop_url) - export pr_azure_sha=$(echo $pr_json | jq -r .pr_azure_sha) - echo azure_drop_url=$azure_drop_url >> $GITHUB_OUTPUT - echo pr_azure_sha=$pr_azure_sha >> $GITHUB_OUTPUT - - - id: remove-label - if: always() - run: | - # remove the label - gh pr edit $PR_URL --remove-label nrn-modeldb-ci-nightly - # if we encounter an error in last github action step, add a comment - if [ ${{ steps.drop.outcome }} == 'failure' ]; then - gh pr comment $PR_URL --body "Unable to retrieve AZURE drop url from comments!" - else - gh pr comment $PR_URL --body "NEURON ModelDB CI: launching for ${pr_azure_sha} via its [drop url]($azure_drop_url)" - fi - env: - pr_azure_sha: ${{ steps.drop.outputs.pr_azure_sha }} - azure_drop_url: ${{ steps.drop.outputs.azure_drop_url }} - - nrn-modeldb-ci: - needs: get-last-azure-url - uses: neuronsimulator/nrn-modeldb-ci/.github/workflows/nrn-modeldb-ci.yaml@master - with: - neuron_v1: ${{needs.get-last-azure-url.outputs.azure_drop_url}} - neuron_v2: neuron-nightly - - pr-update: - needs: - - nrn-modeldb-ci - - get-last-azure-url - runs-on: ubuntu-latest - steps: - - run: | - gh pr comment $PR_URL --body "NEURON ModelDB CI: ${pr_azure_sha} -> download reports [from here](${ARTIFACTS_URL})" - name: Post NEURON ModelDB CI Artifact URL - if: always() || cancelled() - env: - ARTIFACTS_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} - pr_azure_sha: ${{ needs.get-last-azure-url.outputs.pr_azure_sha }} diff --git a/.github/workflows/formatting.yml b/.github/workflows/formatting.yml deleted file mode 100644 index 6c19d3a328..0000000000 --- a/.github/workflows/formatting.yml +++ /dev/null @@ -1,43 +0,0 @@ -name: Check formatting - -concurrency: - # Don't cancel on master, creating a PR when a push workflow is already going will cancel the push workflow in favour of the PR workflow - group: ${{ github.workflow }}-${{ github.ref == 'refs/heads/master' && github.run_id || github.event.number && github.head_ref || github.ref_name }} - cancel-in-progress: true - -on: - merge_group: - push: - branches: - - release/** - pull_request: - branches: - - master - - release/** - -jobs: - all: - name: C/C++, CMake and Python - runs-on: ubuntu-22.04 - timeout-minutes: 5 - steps: - - uses: actions/checkout@v4 - - name: Update submodule - working-directory: ${{runner.workspace}}/nrn - run: git submodule update --init external/coding-conventions - - name: Check formatting - working-directory: ${{runner.workspace}}/nrn - run: | - external/coding-conventions/bin/format - - modified_files=$(git diff --name-only) - if [ -n "$modified_files" ]; then - echo "Some files are not well formatted:" - echo "$modified_files" - echo "" - echo "The diff is:" - git --no-pager diff - exit 1 - fi - - diff --git a/.github/workflows/neuron-ci.yml b/.github/workflows/neuron-ci.yml deleted file mode 100644 index 8effe9c517..0000000000 --- a/.github/workflows/neuron-ci.yml +++ /dev/null @@ -1,508 +0,0 @@ -name: NEURON CI - -concurrency: - # Don't cancel on master, creating a PR when a push workflow is already going will cancel the push workflow in favour of the PR workflow - group: ${{ github.workflow }}-${{ github.ref == 'refs/heads/master' && github.run_id || github.event.number && github.head_ref || github.ref_name }} - cancel-in-progress: true - -on: - merge_group: - push: - branches: - # If nothing else, this is important for the ccache logic below... - - master - - release/** - pull_request: - branches: - - master - - release/** -# TODO : https://github.com/neuronsimulator/nrn/issues/1063 -# paths-ignore: -# - '**.md' -# - '**.rst' -# - 'docs/**' - - -jobs: - ci: - runs-on: ${{ matrix.os }} - - name: ${{ matrix.os }} - ${{ matrix.config.build_mode }} (${{ matrix.config.cmake_option }}${{ matrix.config.config_options }}${{ matrix.config.matrix_eval }}${{ matrix.config.sanitizer }}) - - timeout-minutes: 75 - - env: - INSTALL_DIR: install - SDK_ROOT: $(xcrun --sdk macosx --show-sdk-path) - SKIP_WHEELHOUSE_REPAIR: true - BUILD_TYPE: Release - DESIRED_CMAKE_VERSION: 3.19 - DYNAMIC_PYTHON_CMAKE_VERSION: 3.19 - PY_MIN_VERSION: ${{ matrix.config.python_min_version || '3.9' }} - PY_MAX_VERSION: ${{ matrix.config.python_max_version || '3.14' }} - MUSIC_INSTALL_DIR: /opt/MUSIC - # hash of commit containing mpi4py 4 fix - MUSIC_VERSION: '13f312338dcccebfe74d391b1b24f1b6d816ac6c' - - strategy: - matrix: - os: [macOS-15-intel, ubuntu-22.04] - config: - - { matrix_eval : "CC=gcc-10 CXX=g++-10", build_mode: "python"} - - { matrix_eval : "CC=gcc-12 CXX=g++-12", build_mode: "cmake", music: ON} - - { matrix_eval : "CC=gcc-12 CXX=g++-12", build_mode: "cmake", python_dynamic: ON} - - { matrix_eval : "CC=gcc-10 CXX=g++-10" , build_mode: "cmake", cmake_option: "-DNRN_ENABLE_CORENEURON=ON"} - - { matrix_eval : "CC=gcc-10 CXX=g++-10", build_mode: "cmake", cmake_option: "-DNRN_ENABLE_MPI=OFF -DNRN_ENABLE_INTERVIEWS=OFF -DNRN_ENABLE_CORENEURON=ON"} - - { matrix_eval : "CC=gcc-12 CXX=g++-12", build_mode: "cmake", cmake_option: "-DNRN_ENABLE_PYTHON=OFF -DNRN_ENABLE_RX3D=OFF -DNRN_ENABLE_CORENEURON=ON"} - include: - - os: ubuntu-22.04 - config: - build_mode: cmake - cmake_option: -DNRN_ENABLE_CORENEURON=ON - -DNRN_ENABLE_INTERVIEWS=OFF - flag_warnings: ON - sanitizer: undefined - - os: ubuntu-22.04 - config: - build_mode: cmake - # TODO: CoreNEURON is only LeakSanitizer-clean if we disable MPI - cmake_option: -DNRN_ENABLE_CORENEURON=ON - -DNRN_ENABLE_INTERVIEWS=OFF - # TODO: address-leak is the dream, but there are many problems, - # including external ones from the MPI implementations - sanitizer: address - - os: ubuntu-24.04 - config: - build_mode: cmake - # Cannot use a non-instrumented OpenMP with TSan, and we don't - # have a TSan-instrumented OpenMP runtime available. - # TODO: debug RX3D + TSan - cmake_option: -DNRN_ENABLE_CORENEURON=ON -DNRN_ENABLE_MPI=OFF - -DCORENRN_ENABLE_OPENMP=OFF -DNRN_ENABLE_RX3D=OFF - sanitizer: thread - - os: macOS-15-intel - config: - build_mode: cmake - # TODO: investigate rxd test timeouts in this build and re-enable them - cmake_option: -DNRN_ENABLE_CORENEURON=ON -DNRN_ENABLE_INTERVIEWS=OFF - -DNRN_ENABLE_RX3D=OFF - sanitizer: address - - os: macOS-14 - config: - build_mode: cmake - # TODO: investigate rxd test timeouts in this build and re-enable them - cmake_option: -DNRN_ENABLE_CORENEURON=ON -DNRN_ENABLE_INTERVIEWS=OFF - -DNRN_ENABLE_RX3D=OFF - sanitizer: thread - fail-fast: false - - steps: - - - name: Fix kernel mmap rnd bits - # Asan in llvm 14 provided in ubuntu 22.04 is incompatible with - # high-entropy ASLR in much newer kernels that GitHub runners are - # using leading to random crashes: https://reviews.llvm.org/D148280 - run: sudo sysctl vm.mmap_rnd_bits=28 - if: matrix.os == 'ubuntu-22.04' - - - name: Setup cmake - uses: jwlawson/actions-setup-cmake@v2 - with: - cmake-version : ${{(matrix.config.python_dynamic || matrix.config.build_mode == 'python') && env.DYNAMIC_PYTHON_CMAKE_VERSION || env.DESIRED_CMAKE_VERSION}} - - - name: Install homebrew packages - if: startsWith(matrix.os, 'macOS') - run: | - # Unlink and re-link to prevent errors when GitHub macOS runner images - # install Python outside of brew; See actions/setup-python#577 and BlueBrain/libsonata/pull/317 - brew list -1 | grep python | while read formula; do brew unlink $formula; brew link --overwrite $formula; done - brew install ccache coreutils doxygen flex bison mpich ninja xz autoconf automake libtool - # We use both for dynamic mpi in nrn - brew unlink mpich - brew install openmpi - brew install --cask xquartz - if [[ "${{matrix.os}}" == "macOS-14" ]]; then - brew uninstall cmake || echo "CMake was not pre-installed" - brew install cmake - echo "$(brew --prefix)/opt/cmake/bin" >> $GITHUB_PATH - fi - # workaround for fmt 11.1 (see https://github.com/gabime/spdlog/pull/3312) - brew unlink fmt - echo "$(brew --prefix)/opt/flex/bin:$(brew --prefix)/opt/bison/bin" >> $GITHUB_PATH - # Core https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners/about-github-hosted-runners#standard-github-hosted-runners-for-public-repositories - if [[ "${{matrix.os}}" == "macOS-15-intel" ]]; then - echo CMAKE_BUILD_PARALLEL_LEVEL=4 >> $GITHUB_ENV - echo CTEST_PARALLEL_LEVEL=4 >> $GITHUB_ENV - else - echo CMAKE_BUILD_PARALLEL_LEVEL=3 >> $GITHUB_ENV - echo CTEST_PARALLEL_LEVEL=3 >> $GITHUB_ENV - fi - echo CI_OS_NAME=osx >> $GITHUB_ENV - shell: bash - - - name: Install apt packages - if: startsWith(matrix.os, 'ubuntu') - run: | - sudo apt-get install build-essential ccache libopenmpi-dev \ - libmpich-dev libx11-dev libxcomposite-dev mpich ninja-build \ - openmpi-bin flex libfl-dev bison libreadline-dev - # Core https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners/about-github-hosted-runners#standard-github-hosted-runners-for-public-repositories - echo CMAKE_BUILD_PARALLEL_LEVEL=4 >> $GITHUB_ENV - echo CTEST_PARALLEL_LEVEL=4 >> $GITHUB_ENV - echo CI_OS_NAME=linux >> $GITHUB_ENV - shell: bash - - - uses: actions/checkout@v4 - with: - fetch-depth: 2 - - # Restore (and later save) dependencies for min version of Python - - name: Restore Python@${{ env.PY_MIN_VERSION }} dependencies - if: ${{matrix.config.python_dynamic == 'ON'}} - id: cache-python-min-packages-restore - uses: actions/cache/restore@v4 - with: - path: ${{ github.workspace }}/pip_cache${{ matrix.config.python_min_version || '3.9' }} - key: cache-${{ matrix.os }}-${{ env.PY_MIN_VERSION }}-${{ hashFiles('ci/requirements.txt') }} - - - name: Set up Python@${{ env.PY_MIN_VERSION }} - if: ${{matrix.config.python_dynamic == 'ON'}} - uses: actions/setup-python@v5 - with: - python-version: ${{ env.PY_MIN_VERSION }} - - - name: Install Python@${{ env.PY_MIN_VERSION }} dependencies - if: ${{ matrix.config.python_dynamic == 'ON' }} - working-directory: ${{runner.workspace}}/nrn - run: | - python -m pip install -r ci/uv_requirements.txt - python -m uv pip install -r ci/requirements.txt --cache-dir ${{ github.workspace }}/pip_cache${{ matrix.config.python_min_version || '3.9' }} - - - name: Save Python@${{ env.PY_MIN_VERSION }} dependencies - if: ${{matrix.config.python_dynamic == 'ON'}} && steps.cache-python-min-packages-restore.outputs.cache-hit != 'true' - id: cache-python-min-packages-save - uses: actions/cache/save@v4 - with: - key: ${{ steps.cache-python-min-packages-restore.outputs.cache-primary-key }} - path: ${{ github.workspace }}/pip_cache${{ matrix.config.python_min_version || '3.9' }} - - # Restore (and later save) dependencies for max version of Python - - name: Restore Python@${{ env.PY_MAX_VERSION }} dependencies - id: cache-python-max-packages-restore - uses: actions/cache/restore@v4 - with: - path: ${{ github.workspace }}/pip_cache${{ matrix.config.python_max_version || '3.14' }} - key: cache-${{ matrix.os }}-${{ env.PY_MAX_VERSION }}-${{ hashFiles('ci/requirements.txt') }} - - - name: Set up Python@${{ env.PY_MAX_VERSION }} - uses: actions/setup-python@v5 - with: - python-version: ${{ env.PY_MAX_VERSION }} - - - name: Install Python@${{ env.PY_MAX_VERSION }} dependencies - working-directory: ${{runner.workspace}}/nrn - run: | - python -m pip install -r ci/uv_requirements.txt - python -m uv pip install -r ci/requirements.txt --cache-dir ${{ github.workspace }}/pip_cache${{ matrix.config.python_max_version || '3.14' }} - - - name: Save Python@${{ env.PY_MAX_VERSION }} dependencies - id: cache-python-max-packages-save - if: always() && steps.cache-python-max-packages-restore.outputs.cache-hit != 'true' - uses: actions/cache/save@v4 - with: - key: ${{ steps.cache-python-max-packages-restore.outputs.cache-primary-key }} - path: ${{ github.workspace }}/pip_cache${{ matrix.config.python_max_version || '3.14' }} - - - name: Install a new automake - # A automake >= 1.16.5 is needed for python 3.12 because it generates a python script - # called py-compile and the original one is not supporting this version of python - # Once ubuntu got a newer version of automake we can remove this part. - if: matrix.config.music == 'ON' && startsWith(matrix.os, 'ubuntu') - run: | - curl -L -o automake.tar.xz https://ftpmirror.gnu.org/gnu/automake/automake-1.16.5.tar.xz - tar -xf automake.tar.xz - cd automake-1.16.5/ - ./configure --prefix=/usr/ - make -j - sudo make -j install - automake --version - working-directory: ${{runner.temp}} - - - name: Setup MUSIC@${{ env.MUSIC_VERSION }} - if: matrix.config.music == 'ON' - run: | - python3 -m venv music-venv - source music-venv/bin/activate - python3 -m pip install -r ${{ github.workspace }}/ci/uv_requirements.txt - python3 -m uv pip install -r ${{ github.workspace }}/ci/requirements.txt --cache-dir ${{ github.workspace }}/pip_cache${{ matrix.config.python_max_version || '3.14' }} - sudo mkdir -p $MUSIC_INSTALL_DIR - sudo chown -R $USER $MUSIC_INSTALL_DIR - curl -L -o MUSIC.zip https://github.com/INCF/MUSIC/archive/${MUSIC_VERSION}.zip - unzip MUSIC.zip && mv MUSIC-* MUSIC && cd MUSIC - ./autogen.sh - # on some systems MPI library detection fails, provide exact flags/compilers - ./configure --with-python-sys-prefix --prefix=$MUSIC_INSTALL_DIR --disable-anysource MPI_CXXFLAGS="-g -O3" MPI_CFLAGS="-g -O3" MPI_LDFLAGS=" " CC=mpicc CXX=mpicxx - make -j install - deactivate - working-directory: ${{runner.temp}} - - - name: Register gcc problem matcher - if: ${{matrix.config.flag_warnings == 'ON'}} - run: echo "::add-matcher::.github/problem-matchers/gcc.json" - - - name: Register sanitizer problem matcher - if: ${{matrix.config.sanitizer}} - run: echo "::add-matcher::.github/problem-matchers/${{matrix.config.sanitizer}}.json" - - - name: Hash config dictionary - run: | - cat << EOF > matrix.json - ${{toJSON(matrix.config)}} - EOF - echo matrix.config JSON: - cat matrix.json - echo ----- - - - name: Restore compiler cache - uses: actions/cache/restore@v4 - id: restore-compiler-cache - with: - path: ${{runner.workspace}}/ccache - key: ${{matrix.os}}-${{hashfiles('matrix.json')}}-${{github.ref}}-${{github.sha}} - restore-keys: | - ${{matrix.os}}-${{hashfiles('matrix.json')}}-${{github.ref}}- - ${{matrix.os}}-${{hashfiles('matrix.json')}}- - - - name: Build and Test - id: build-test - shell: bash - working-directory: ${{runner.workspace}}/nrn - run: | - # OS related - if [ "$RUNNER_OS" == "Linux" ]; then - export ${MATRIX_EVAL}; - export SHELL="/bin/bash" - else - export CXX=${CXX:-g++}; - export CC=${CC:-gcc}; - fi - if [ "$RUNNER_OS" == "macOS" ]; then - # TODO - this is a workaround that was implemented for Azure being reported as getting stuck. - # However it does not get stuck: neuron module not found and script goes to interpreter, seeming stuck. - # This needs to be addressed and SKIP_EMBEDED_PYTHON_TEST logic removed everywhere. - export SKIP_EMBEDED_PYTHON_TEST="true" - # long TMPDIR path on MacOS can results into runtime failures with OpenMPI - # Set shorter path as discussed in https://github.com/open-mpi/ompi/issues/8510 - export TMPDIR=/tmp/$GITHUB_JOB - mkdir -p $TMPDIR - fi - - # Python setup - export PYTHONPATH=$PYTHONPATH:$INSTALL_DIR/lib/python/ - # Python setup - export PYTHON_MIN=$(command -v $PYTHON_MIN_NAME); - export PYTHON_MAX=$(command -v $PYTHON_MAX_NAME); - export PYTHON=$PYTHON_MAX - if [ "$RUNNER_OS" == "macOS" ]; then - # Python is not installed as a framework, so we need to writ 'backend: TkAgg' to `matplotlibrc`. - # Since we are in a virtual environment, we cannot use `$HOME/matplotlibrc` - # The following solution is generic and relies on `matplotlib.__file__` to know where to append backend setup. - $PYTHON -c "import os,matplotlib; f =open(os.path.join(os.path.dirname(matplotlib.__file__), 'mpl-data/matplotlibrc'),'a'); f.write('backend: TkAgg');f.close();" - fi; - - # Some logging - echo $LANG - echo $LC_ALL - python3 -c 'import os,sys; os.set_blocking(sys.stdout.fileno(), True)' - cmake --version - - # different builds with CMake - if [[ "$BUILD_MODE" == "cmake" ]]; then - cmake_args=(-G Ninja) - # Sanitizer-specific setup - if [[ -n "${{matrix.config.sanitizer}}" ]]; then - if [ "$RUNNER_OS" == "Linux" ]; then - if [[ "${{matrix.config.sanitizer}}" == "thread" ]]; then - # GitHub/ubuntu-22.04 + clang-14 seems to have problems with TSan. - # Vanilla 22.04 + clang-16 from apt.llvm.org seemed to work. - # Use gcc-12 instead, as GitHub/ubuntu-22.04 already has it. - CC=$(command -v gcc-12) - CXX=$(command -v g++-12) - else - CC=$(command -v clang-14) - CXX=$(command -v clang++-14) - symbolizer_path="$(readlink -f "$(command -v llvm-symbolizer-14)")" - cmake_args+=(-DLLVM_SYMBOLIZER_PATH="${symbolizer_path}") - fi - fi - cmake_args+=(-DCMAKE_BUILD_TYPE=Custom \ - -DCMAKE_C_FLAGS="-O1 -g" \ - -DCMAKE_CXX_FLAGS="-O1 -g" \ - -DNRN_SANITIZERS=$(echo ${{matrix.config.sanitizer}} | sed -e 's/-/,/g')) - fi - cmake_args+=(-DCMAKE_C_COMPILER="${CC}" \ - -DCMAKE_C_COMPILER_LAUNCHER=ccache \ - -DCMAKE_CXX_COMPILER="${CXX}" \ - -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ - -DCMAKE_INSTALL_PREFIX="${INSTALL_DIR}" \ - -DNRN_ENABLE_TESTS=ON \ - -DNRN_ENABLE_PERFORMANCE_TESTS=OFF \ - ${{matrix.config.cmake_option}}) - if [[ "$NRN_ENABLE_PYTHON_DYNAMIC" == "ON" ]]; then - cmake_args+=(-DNRN_ENABLE_PYTHON=ON \ - -DNRN_ENABLE_PYTHON_DYNAMIC=ON \ - -DNRN_PYTHON_DYNAMIC="${PYTHON_MIN};${PYTHON_MAX}" \ - -DNRN_ENABLE_CORENEURON=ON) - else - cmake_args+=(-DPYTHON_EXECUTABLE="${PYTHON}") - fi - if [[ "$NRN_ENABLE_MUSIC" == "ON" ]]; then - cmake_args+=(-DNRN_ENABLE_MUSIC=ON \ - -DCMAKE_PREFIX_PATH=${MUSIC_INSTALL_DIR} \ - -DMUSIC_ROOT=${MUSIC_INSTALL_DIR}) - fi - # Enable more warnings in the builds whose compiler warnings we - # highlight in the GitHub UI - if [[ "${{matrix.config.flag_warnings}}" == "ON" ]]; then - cmake_args+=(-DNRN_EXTRA_CXX_FLAGS="-Wall \ - -Wno-char-subscripts \ - -Wno-unknown-pragmas \ - -Wno-unused-variable \ - -Wno-unused-function \ - -Wno-unused-but-set-variable \ - -Wno-reorder \ - -Wno-sign-compare" \ - -DNRN_EXTRA_MECH_CXX_FLAGS="-Wno-sometimes-uninitialized \ - -Wno-missing-braces") - fi - mkdir build && cd build - echo "Building with: ${cmake_args[@]}" - cmake .. "${cmake_args[@]}" - if ccache --version | grep -E '^ccache version 4\.(4|4\.1)$' - then - echo "------- Disable ccache direct mode -------" - # https://github.com/ccache/ccache/issues/935 - export CCACHE_NODIRECT=1 - fi - ccache -z - # Older versions don't support -v (verbose) - ccache -vvs 2>/dev/null || ccache -s - cmake --build . - ccache -vvs 2>/dev/null || ccache -s - if [[ "$NRN_ENABLE_PYTHON_DYNAMIC" == "ON" ]]; then - echo "--RUNNING BASIC TESTS FROM BUILD DIR--" - for python in "${PYTHON_MIN}" "${PYTHON_MAX}" - do - echo "Using ${python}" - NEURONHOME="${PWD}/share/nrn" \ - PYTHONPATH="${PWD}/lib/python" \ - PATH="${PWD}/bin" \ - LD_LIBRARY_PATH="${PWD}/lib:${LD_LIBRARY_PATH}" \ - DYLD_LIBRARY_PATH="${PWD}/lib:${DYLD_LIBRARY_PATH}" \ - "${python}" -c "from neuron import h; import neuron; neuron.test()" - done - fi - ctest --output-on-failure - cmake --build . --target install - export PATH="${INSTALL_DIR}/bin:${PATH}" - if [[ -f "${INSTALL_DIR}/bin/nrn-enable-sanitizer" ]]; then - echo --- bin/nrn-enable-sanitizer --- - cat bin/nrn-enable-sanitizer - echo --- - nrn_enable_sanitizer=${INSTALL_DIR}/bin/nrn-enable-sanitizer - nrn_enable_sanitizer_preload_python="${nrn_enable_sanitizer} --preload python" - else - echo nrn-enable-sanitizer not found, not using it - fi - elif [[ "$BUILD_MODE" == "python" ]]; then - ./packaging/python/build_wheels.bash CI "${PYTHON_MAX}"; - fi; - if [[ -z "${nrn_enable_sanitizer_preload_python}" ]]; then - nrn_enable_sanitizer_preload_python="${PYTHON}" - fi - - # basic test for cmake when python is not disabled - if [[ "$BUILD_MODE" == "cmake" && ! "${cmake_args[*]}" =~ "NRN_ENABLE_PYTHON=OFF" ]]; then - ${nrn_enable_sanitizer_preload_python} --version && ${nrn_enable_sanitizer_preload_python} -c 'import neuron; neuron.test()' - fi; - - # test neurondemo with cmake - if [[ "$BUILD_MODE" != "python" ]]; then - ${nrn_enable_sanitizer} neurondemo -nogui -c 'demo(4)' -c 'run()' -c 'quit()' - fi; - - # with cmake dynamic check python_min and python_max together - if [[ "$BUILD_MODE" == "cmake" && "$NRN_ENABLE_PYTHON_DYNAMIC" == "ON" ]]; then - ${nrn_enable_sanitizer_preload_python} -c 'import neuron; neuron.test()' - $PYTHON_MIN -c 'import neuron; neuron.test()' - fi; - - # run rxd tests manually if rxd is enabled *and CoreNEURON is - # disabled -- otherwise hh-related tests fail - if [[ "$BUILD_MODE" == "cmake" \ - && ! "${cmake_args[*]}" =~ "NRN_ENABLE_RX3D=OFF" \ - && ! "${cmake_args[*]}" =~ "NRN_ENABLE_CORENEURON=ON" ]]; then - ${nrn_enable_sanitizer_preload_python} ../share/lib/python/neuron/rxdtests/run_all.py - fi; - - if [ "$BUILD_MODE" == "python" ]; then - neuron_wheel=wheelhouse/*.whl; - # test with virtual environment - ./packaging/python/test_wheels.sh $PYTHON $neuron_wheel - # test with global installation - ./packaging/python/test_wheels.sh $PYTHON $neuron_wheel false - fi; - env: - BUILD_MODE: ${{ matrix.config.build_mode }} - CCACHE_BASEDIR: ${{runner.workspace}}/nrn - CCACHE_DIR: ${{runner.workspace}}/ccache - NRN_ENABLE_PYTHON_DYNAMIC : ${{ matrix.config.python_dynamic }} - NRN_ENABLE_MUSIC: ${{ matrix.config.music }} - PYTHON_MIN_NAME: "python${{ env.PY_MIN_VERSION }}" - PYTHON_MAX_NAME: "python${{ env.PY_MAX_VERSION }}" - INSTALL_DIR : ${{ runner.workspace }}/install - MATRIX_EVAL: ${{ matrix.config.matrix_eval }} - SKBUILD_BUILD_DIR: ${{runner.workspace}}/nrn/build - - - name: Save compiler cache - uses: actions/cache/save@v4 - if: always() && steps.restore-compiler-cache.outputs.cache-hit != 'true' - with: - path: ${{runner.workspace}}/ccache - key: | - ${{matrix.os}}-${{hashfiles('matrix.json')}}-${{github.ref}}- - ${{matrix.os}}-${{hashfiles('matrix.json')}}- - - - name: Upload build artifacts - if: always() - uses: actions/upload-artifact@v4 - with: - name: build_files-${{matrix.os}}-${{hashfiles('matrix.json')}}-${{github.sha}} - path: | - ${{runner.workspace}}/nrn/build/CMakeCache.txt - ${{runner.workspace}}/nrn/build/build.ninja - ${{runner.workspace}}/nrn/build/cmake_install.cmake - - # This step will set up an SSH connection on tmate.io for live debugging. - # To enable it, you have to: - # * add 'live-debug-ci' to your PR title - # * push something to your PR branch (note that just re-running the pipeline disregards the title update) - - name: live debug session on failure (manual steps required, check `.github/neuron-ci.yml`) - if: failure() && contains(github.event.pull_request.title, 'live-debug-ci') - uses: mxschmitt/action-tmate@v3 - - # see https://github.com/orgs/community/discussions/26822 - final: - name: Final CI - needs: [ci] - if: ${{ always() }} - runs-on: ubuntu-latest - steps: - - name: Check ci matrix all done - if: >- - ${{ - contains(needs.*.result, 'failure') - || contains(needs.*.result, 'cancelled') - || contains(needs.*.result, 'skipped') - }} - run: exit 1 diff --git a/.github/workflows/nvhpc.yml b/.github/workflows/nvhpc.yml deleted file mode 100644 index e673053926..0000000000 --- a/.github/workflows/nvhpc.yml +++ /dev/null @@ -1,121 +0,0 @@ -name: NEURON NVHPC CI - - -concurrency: - # Don't cancel on master, creating a PR when a push workflow is already going will cancel the push workflow in favour of the PR workflow - group: ${{ github.workflow }}-${{ github.ref == 'refs/heads/master' && github.run_id || github.event.number && github.head_ref || github.ref_name }} - cancel-in-progress: true - - -# NOTE: if using a self-hosted runner, NEVER add a `on: workflow_call` entry. -# The reason is that anyone could then run the workflow on our self-hosted -# machine, which is a security concern and would consume our resources. -on: - push: - branches: - - master - - release/** - - pull_request: - branches: - - master - - release/** - - workflow_dispatch: - inputs: - branch: - description: "Name of the NEURON branch to test" - type: string - required: true - - -env: - NRN_BUILD_DIR: ${{ github.workspace }}/build - - -jobs: - nvhpc: - name: "Run NVHPC CI on custom runner" - runs-on: "self-hosted" - timeout-minutes: 60 - steps: - - name: "Verify NVHPC is available" - env: - # set this to the path (in the container!) where NVHPC makes - # its executables available - NVHPC_PATH: "/opt/nvidia/hpc_sdk/Linux_x86_64/25.3/compilers/bin/" - run: | - if [[ ! -d "${NVHPC_PATH}" ]]; then - echo "ERROR: path ${NVHPC_PATH} does not exist, please verify it exists" - exit 1 - fi - echo "${NVHPC_PATH}" >> $GITHUB_PATH - - - name: "Checkout repo" - uses: actions/checkout@v4 - with: - ref: ${{ inputs.branch || github.sha || 'master' }} - fetch-depth: 1 - submodules: recursive - - - name: "Install Python dependencies" - env: - # use a cache to speed things up - PYTHON_CACHE: /opt/cache/python - run: | - PY_EXECUTABLE="${PY_EXECUTABLE:-$(command -v python3)}" - PY_MAJOR="$("${PY_EXECUTABLE}" -c 'import sys;print(sys.version_info[0])')" - PY_MINOR="$("${PY_EXECUTABLE}" -c 'import sys;print(sys.version_info[1])')" - VENV_DIR="venv_${PY_MAJOR}.${PY_MINOR}" - "${PY_EXECUTABLE}" -m venv "${VENV_DIR}" - source "${VENV_DIR}/bin/activate" - python -m pip install -r ci/uv_requirements.txt - uv pip install -r ci/requirements.txt --cache-dir ${PYTHON_CACHE} - echo "VENV_DIR=${VENV_DIR}" >> $GITHUB_ENV - - - name: "Configure NEURON" - env: - NRN_INSTALL_DIR: /tmp/nrn-install - run: | - rm -fr ${NRN_INSTALL_DIR} - source "${VENV_DIR}/bin/activate" - export NRN_CONFIG=(-DNRN_ENABLE_CORENEURON=ON -DNRN_ENABLE_MPI=ON -DCORENRN_ENABLE_GPU=ON -DCMAKE_CXX_COMPILER=nvc++ -DNRN_ENABLE_INTERVIEWS=OFF -DNRN_ENABLE_RX3D=OFF -DNRN_ENABLE_DOCS=OFF -DNRN_ENABLE_TESTS=ON -DCMAKE_C_COMPILER=nvc -DCMAKE_CUDA_COMPILER=nvcc -DCMAKE_INSTALL_PREFIX="${NRN_INSTALL_DIR}" -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DNMODL_ENABLE_FLEX_BISON_LINES=OFF -DCMAKE_CUDA_COMPILER_LAUNCHER=ccache -G Ninja -DCMAKE_BUILD_TYPE=Debug) - cmake -B ${NRN_BUILD_DIR} "${NRN_CONFIG[@]}" - - - name: "Build NEURON" - env: - # use ccache to speed things up - CCACHE_DIR: /opt/cache/ccache - # set this to how many CPUs are available - CMAKE_BUILD_PARALLEL_LEVEL: 20 - run: | - source "${VENV_DIR}/bin/activate" - # display some ccache stats - ccache -z - ccache -svv - cmake --build ${NRN_BUILD_DIR} - ccache -svv - - - name: "Test NEURON" - env: - # set this to how many CPUs are available - CTEST_PARALLEL_LEVEL: 20 - run: | - source "${VENV_DIR}/bin/activate" - ctest --output-on-failure --test-dir ${NRN_BUILD_DIR} - - - name: "Install NEURON" - run: | - source "${VENV_DIR}/bin/activate" - cmake --install ${NRN_BUILD_DIR} - - - name: "Upload build artifacts" - if: always() - uses: actions/upload-artifact@v4 - with: - name: build_files - path: | - ${{ github.workspace }}/build/CMakeCache.txt - ${{ github.workspace }}/build/build.ninja - ${{ github.workspace }}/build/cmake_install.cmake - ${{ github.workspace }}/build/install_manifest.txt diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index 9525d93e8a..0000000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,325 +0,0 @@ -name: NEURON Release - -on: - workflow_dispatch: - inputs: - rel_branch: - description: 'Release branch/commit' - default: 'release/x.y' - required: true - rel_tag: - description: 'Release version (tag name)' - default: 'x.y.z' - required: true - python_versions: - description: "Comma-separated list of supported Python versions" - default: "3.9,3.10,3.11,3.12,3.13,3.14" - required: true - type: string - os: - description: "Comma-separated list of OSes (for wheels only)" - default: "macos-15-intel,macos-14,ubuntu-24.04,ubuntu-24.04-arm" - required: true - type: string - upload: - description: "Whether to actually upload any files (releases, wheels, etc.)" - required: true - default: false - type: boolean - -env: - GH_REPO: ${{ github.server_url }}/${{ github.repository }} - REL_TAG: ${{ github.event.inputs.rel_tag }} - REL_BRANCH: ${{ github.event.inputs.rel_branch }} - -jobs: - get-latest-wheel-version: - name: Get the latest wheel version from PyPI - runs-on: ubuntu-latest - outputs: - latest_version: ${{ steps.latest-wheel-version.outputs.latest_version }} - steps: - - name: Get the latest wheel version from PyPI - id: latest-wheel-version - run: | - # taken from: - # https://safjan.com/how-to-check-latest-version-of-python-package/ - echo "latest_version=$(curl -s https://pypi.org/pypi/neuron/json | jq -r '.info.version')" >> "$GITHUB_OUTPUT" - - generate-wheel-matrix: - name: Generate platform and Python matrix for wheels - # wheels should be built once the full source package builds successfully - runs-on: ubuntu-latest - outputs: - matrix: ${{ steps.set-matrix.outputs.matrix }} - steps: - - id: set-matrix - run: | - OS_INPUT="${{ github.event.inputs.os || 'macos-15-intel,macos-14,ubuntu-24.04,ubuntu-24.04-arm' }}" - PY_INPUT="${{ github.event.inputs.python_versions || '3.9,3.10,3.11,3.12,3.13,3.14' }}" - OS_JSON=$(echo "$OS_INPUT" | jq -R 'split(",")') - PY_JSON=$(echo "$PY_INPUT" | jq -R 'split(",")') - echo "matrix=$(jq -c -n --argjson os "$OS_JSON" --argjson py "$PY_JSON" '{os: $os, python_version: $py}')" >> "$GITHUB_OUTPUT" - - # we need to build wheels _before_ running modelDB CI, since it only works - # with wheels, and not the CMake installer - build-wheels: - name: Build and test wheel on ${{ matrix.os }} with Python ${{ matrix.python_version }} - needs: - - generate-wheel-matrix - - tag-n-release - uses: ./.github/workflows/wheels-template.yml - strategy: - matrix: ${{ fromJson(needs.generate-wheel-matrix.outputs.matrix) }} - with: - platform: ${{ matrix.os }} - python_version: ${{ matrix.python_version }} - optimize_rxd: true - commit: ${{ needs.tag-n-release.outputs.ref }} # Uses tag (if upload=true) or branch - version: ${{ github.event.inputs.rel_tag }} - build_type: 'release' - - merge-wheels: - name: Merge wheel files to one artifact - runs-on: ubuntu-latest - needs: - - build-wheels - outputs: - artifacts-url: ${{ steps.merge-artifacts.outputs.artifacts-url }} - steps: - - name: Merge Artifacts - id: merge-artifacts - uses: actions/upload-artifact/merge@v4 - with: - delete-merged: true - name: wheels - pattern: wheels-* - - nrn-modeldb-ci: - name: Run modelDB CI relative to ${{ needs.get-latest-wheel-version.outputs.latest_version }} - needs: - - get-latest-wheel-version - - merge-wheels - uses: neuronsimulator/nrn-modeldb-ci/.github/workflows/nrn-modeldb-ci.yaml@master - with: - # v1 is the latest stable wheel, while v2 is the currently-built wheel. - # Note that v2 needs to at least contain an x86_64 Linux Python 3.9 wheel since that is the platform that modelDB CI uses - neuron_v1: neuron==${{ needs.get-latest-wheel-version.outputs.latest_version }} - neuron_v2: ${{ needs.merge-wheels.outputs.artifacts-url }} - - nrn-full-src-package: - name: Create the full-src package - runs-on: ubuntu-latest - outputs: - topdir: ${{ steps.create-full-src.outputs.topdir }} - filename: ${{ steps.create-full-src.outputs.filename }} - steps: - - name: Checkout feature-rich code - uses: actions/checkout@v4 - with: - submodules: recursive - fetch-depth: 1 - ref: ${{ github.event.inputs.rel_branch }} - - - name: Create nrn-full-src-package artifact - id: create-full-src - run: | - filename="nrn-full-src-package-${{ env.REL_TAG }}.tar.gz" - echo "filename=$filename" >> "$GITHUB_OUTPUT" - topdir="nrn-${{ env.REL_TAG }}" - echo "topdir=${topdir}" >> "$GITHUB_OUTPUT" - # taken from: - # https://stackoverflow.com/a/67389978 - git ls-files --recurse-submodules > nrn_files - # we also need the .git dir for now - find .git >> nrn_files - # cannot use --xform as it screws up the symbolic links. So - # do a normal tar, untar into topdir, and tar again. - mkdir -p tmp/$topdir - tar -c -T nrn_files | tar -x -C tmp/$topdir - (cd tmp && tar caf ../$filename $topdir) - rm -rf tmp - - - name: Upload nrn-full-src-package artifact - uses: actions/upload-artifact@v4 - id: upload-full-src - with: - name: nrn-full-src-package - path: ${{ steps.create-full-src.outputs.filename }} - - test-full-src-package: - name: Build and test the full-src package - runs-on: ubuntu-latest - needs: - - nrn-full-src-package - steps: - - name: Install apt packages - run: | - sudo apt-get install -y bison flex libreadline-dev libfl-dev libmpich-dev - - - name: Setup cmake - uses: jwlawson/actions-setup-cmake@v2 - with: - cmake-version : '3.19' - - - name: Set up Python - id: setup-python - uses: actions/setup-python@v5 - with: - python-version: '3.12' - - - name: Download nrn-full-src-package artifact - uses: actions/download-artifact@v4 - with: - name: nrn-full-src-package - - - name: Build nrn-full-src-package - run: | - tar xf ${filename} - python -m venv ${venv_dir} - source ${venv_dir}/bin/activate - if [[ -f "${topdir}/ci/requirements.txt" ]]; then - python -m pip install -r ${topdir}/ci/uv_requirements.txt - uv pip install -r ${topdir}/ci/requirements.txt - else - python -m pip install -r ${topdir}/nrn_requirements.txt - fi - # we build a simple configuration to save on CI time - cmake -B build -DNRN_ENABLE_INTERVIEWS=OFF -DNRN_ENABLE_MPI=OFF -DNMODL_ENABLE_PYTHON_BINDINGS=OFF -DNRN_ENABLE_CORENEURON=OFF -S ${topdir}/ - cmake --build build --parallel $(nproc) - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - topdir: ${{ needs.nrn-full-src-package.outputs.topdir }} - filename: ${{ needs.nrn-full-src-package.outputs.filename }} - venv_dir: venv_${{ steps.setup-python.outputs.python-version }} - - nrn-build-ci: - name: Run build CI - needs: - - merge-wheels - uses: neuronsimulator/nrn-build-ci/.github/workflows/build-neuron-template.yml@main - with: - artifact_url: ${{ needs.merge-wheels.outputs.artifacts-url }} - neuron_branch: ${{ github.event.inputs.rel_branch }} - repo: 'neuronsimulator/nrn-build-ci' - - pypi-publish: - name: Upload wheels to PyPI - if: github.event.inputs.upload == 'true' - needs: - - merge-wheels - runs-on: ubuntu-latest - environment: - name: pypi - url: https://pypi.org/p/neuron - permissions: - id-token: write # IMPORTANT: this permission is mandatory for trusted publishing - steps: - - name: Download wheels from artifact - uses: actions/download-artifact@v4 - with: - name: wheels - path: dist/ - - name: Publish package distributions to PyPI - uses: pypa/gh-action-pypi-publish@release/v1 - - # actually creates a git tag and a release on GitHub - tag-n-release: - runs-on: ubuntu-latest - name: tag-n-release ${{ github.event.inputs.rel_tag }} (${{ github.event.inputs.rel_branch }}) - outputs: - release_url: ${{ steps.create_release.outputs.upload_url }} - rel_tag: ${{ env.REL_TAG }} - ref: ${{ steps.build-ref.outputs.ref }} # Conditional ref for builds - steps: - - uses: actions/checkout@v4 - name: Checkout branch ${{ env.REL_BRANCH }} - with: - ref: ${{ github.event.inputs.rel_branch }} - - - name: Determine build ref # Sets ref to tag (if upload=true) or branch - id: build-ref - run: | - if [[ "${{ github.event.inputs.upload }}" == 'true' ]]; then - echo "ref=${{ env.REL_TAG }}" >> $GITHUB_OUTPUT - else - echo "ref=${{ github.event.inputs.rel_branch }}" >> $GITHUB_OUTPUT - fi - - - name: Create and upload tag ${{ env.REL_TAG }} - # Moved the earlier `if` to here so the build items can succeed with upload false - if: github.event.inputs.upload == 'true' - run: | - git config user.name github-actions - git config user.email github-actions@github.com - git tag -a $REL_TAG -m "${REL_TAG}" - git push origin $REL_TAG - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - working-directory: ${{runner.workspace}}/nrn - - - name: Create Release - if: github.event.inputs.upload == 'true' # Skip on dry runs - id: create_release - uses: ncipollo/release-action@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - tag: ${{ github.event.inputs.rel_tag }} - name: Release ${{ github.event.inputs.rel_tag }} - prerelease: true - - upload-src-package: - name: Publish full-src package - runs-on: ubuntu-latest - if: github.event.inputs.upload == 'true' - needs: - - nrn-full-src-package - - tag-n-release - steps: - - name: Download nrn-full-src-package artifact - uses: actions/download-artifact@v4 - with: - name: nrn-full-src-package - - - name: Upload to GitHub release - run: | - gh release upload ${{ env.REL_TAG }} ${{ needs.nrn-full-src-package.outputs.filename }} - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - build-windows-installer: - name: Build Windows installer - needs: - - tag-n-release - uses: neuronsimulator/nrn/.github/workflows/windows.yml@master - with: - tag: ${{ needs.tag-n-release.outputs.ref }} - - upload-windows-installer: - name: Publish Windows installer - if: github.event.inputs.upload == 'true' - needs: - - build-windows-installer - runs-on: ubuntu-latest - steps: - - name: Download Windows installer artifact - uses: actions/download-artifact@v4 - with: - name: nrn-nightly-AMD64.exe - - - name: Rename Windows installer - id: rename - run: | - # convert "3.9,3.10..." into "39-310-..." - py_version_string="$(echo "${{ github.event.inputs.python_versions }}" | sed 's/\.//g; s/,/-/g')" - win_installer_name="nrn-${{ env.REL_TAG }}.w64-mingw-py-${py_version_string}-setup.exe" - echo "win_installer_name=${win_installer_name}" >> "$GITHUB_OUTPUT" - cp nrn-nightly-AMD64.exe "${win_installer_name}" - ls -lha "${win_installer_name}" - - - name: Publish Windows installer - run: | - gh release upload ${{ env.REL_TAG }} ${{ steps.rename.outputs.win_installer_name }} - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/wheels-ci.yml b/.github/workflows/wheels-ci.yml deleted file mode 100644 index abbf81e9e5..0000000000 --- a/.github/workflows/wheels-ci.yml +++ /dev/null @@ -1,48 +0,0 @@ -name: Build NEURON Python wheels for CI - -concurrency: - # Don't cancel on master, creating a PR when a push workflow is already going will cancel the push workflow in favour of the PR workflow - group: ${{ github.workflow }}-${{ github.ref == 'refs/heads/master' && github.run_id || github.event.number && github.head_ref || github.ref_name }} - cancel-in-progress: true - -on: - push: - branches: - - master - pull_request: - branches: - - master - -jobs: - build-test: - name: Build and test NEURON Python wheels - uses: ./.github/workflows/wheels-template.yml - with: - platform: ${{ matrix.os }} - python_version: ${{ matrix.python_version }} - commit: ${{ github.sha }} - strategy: - matrix: - os: ['macos-15-intel', 'ubuntu-24.04'] - python_version: ['3.9', '3.14'] - - merge: - name: Merge artifacts and post artifacts URL - runs-on: ubuntu-latest - needs: [build-test] - steps: - - name: Merge Artifacts - id: merge-artifacts - uses: actions/upload-artifact/merge@v4 - with: - delete-merged: true - name: wheels - pattern: wheels-* - - - name: Create comment with URL to artifact - if: github.event.pull_request && github.event.pull_request.head.repo.full_name == github.repository - uses: peter-evans/create-or-update-comment@v4 - with: - issue-number: ${{ github.event.pull_request.number }} - body: | - ✔️ ${{ github.event.pull_request.head.sha }} -> [artifacts URL](${{ steps.merge-artifacts.outputs.artifact-url }}) diff --git a/.github/workflows/wheels-nightly.yml b/.github/workflows/wheels-nightly.yml deleted file mode 100644 index 3c07d7c98c..0000000000 --- a/.github/workflows/wheels-nightly.yml +++ /dev/null @@ -1,101 +0,0 @@ -name: Build NEURON Python wheels for nightly upload - -on: - schedule: - - cron: "0 0 * * *" - workflow_dispatch: - inputs: - upload: - description: "Upload wheels to PyPI" - required: false - default: "false" - type: boolean - os: - description: "Comma-separated list of OSes" - required: false - default: "macos-14,ubuntu-24.04-arm" - python_versions: - description: "Comma-separated list of Python versions" - required: false - default: "3.9,3.10,3.11,3.12,3.13,3.14" - commit: - description: The commit of NEURON for which to build the wheel - required: false - default: "master" - -jobs: - fetch-latest-commit: - runs-on: ubuntu-latest - outputs: - commit: ${{ steps.save-commit.outputs.commit }} - steps: - - name: Save commit ref - id: save-commit - run: | - commit="${{ github.event.inputs.commit }}" - if [[ -n "${commit}" ]]; then - echo "commit=${commit}" >> "$GITHUB_OUTPUT" - else - git ls-remote origin refs/heads/master | cut -f1 | xargs -I{} echo "commit={}" >> "$GITHUB_OUTPUT" - fi - - generate-matrix: - name: Generate platform and Python matrix - runs-on: ubuntu-latest - outputs: - matrix: ${{ steps.set-matrix.outputs.matrix }} - steps: - - id: set-matrix - run: | - OS_INPUT="${{ github.event.inputs.os || 'macos-14,ubuntu-24.04-arm' }}" - PY_INPUT="${{ github.event.inputs.python_versions || '3.9,3.10,3.11,3.12,3.13,3.14' }}" - OS_JSON=$(echo "$OS_INPUT" | jq -R 'split(",")') - PY_JSON=$(echo "$PY_INPUT" | jq -R 'split(",")') - echo "matrix=$(jq -c -n --argjson os "$OS_JSON" --argjson py "$PY_JSON" '{os: $os, python_version: $py}')" >> "$GITHUB_OUTPUT" - - build-test: - name: Build and test for nightly - needs: [fetch-latest-commit, generate-matrix] - uses: ./.github/workflows/wheels-template.yml - with: - platform: ${{ matrix.os }} - python_version: ${{ matrix.python_version }} - optimize_rxd: true - clone_depth: '0' - commit: ${{ needs.fetch-latest-commit.outputs.commit }} - strategy: - matrix: ${{ fromJson(needs.generate-matrix.outputs.matrix) }} - - merge: - name: Merge artifacts - runs-on: ubuntu-latest - needs: [build-test] - steps: - - name: Merge Artifacts - id: merge-artifacts - uses: actions/upload-artifact/merge@v4 - with: - delete-merged: true - name: wheels - pattern: wheels-* - - pypi-publish: - name: Upload wheels to PyPI - if: github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && github.event.inputs.upload == 'true') - needs: merge - runs-on: ubuntu-latest - environment: - name: pypi - url: https://pypi.org/p/neuron-nightly - permissions: - id-token: write # IMPORTANT: this permission is mandatory for trusted publishing - steps: - - name: Download wheels from artifact - uses: actions/download-artifact@v4 - with: - name: wheels - path: dist/ - - name: Publish package distributions to PyPI - uses: pypa/gh-action-pypi-publish@release/v1 - with: - skip-existing: true diff --git a/.github/workflows/wheels-template.yml b/.github/workflows/wheels-template.yml deleted file mode 100644 index 7549e8977a..0000000000 --- a/.github/workflows/wheels-template.yml +++ /dev/null @@ -1,147 +0,0 @@ -name: Template for building NEURON Python wheels - -on: - workflow_call: - inputs: - platform: - description: The platform (OS) for which to build the wheel - required: true - type: string - python_version: - description: The Python version for which to build the wheel - required: true - type: string - commit: - description: The commit of NEURON for which to build the wheel - required: true - type: string - version: - description: Override version (tag name), in format major.minor.patch - default: '' - type: string - build_type: - description: The type of build (release or nightly) - default: 'nightly' - type: string - clone_depth: - description: The depth to clone the repo - default: '1' - type: string - optimize_rxd: - description: Whether to optimize the RX3D Python module - default: false - type: boolean - -jobs: - build-test: - name: Build and test Python ${{ inputs.python_version }} wheel on ${{ inputs.platform }} - runs-on: ${{ inputs.platform }} - timeout-minutes: 60 - steps: - - name: Check out code at branch/commit ${{ inputs.commit }} - uses: actions/checkout@v4 - with: - ref: ${{ inputs.commit }} - submodules: recursive - fetch-depth: ${{ inputs.clone_depth }} - fetch-tags: true # Ensures tags are available for git describe - - - name: Install Python from python.org - if: runner.os == 'macOS' - run: | - # I would've preferred the versions to be in their own YAML file for - # readability, but alas, GitHub Actions does not support expanding - # nested expressions, so we do this the brute-force way with Bash - case "${{ inputs.python_version }}" in - 3.9) version="3.9.13" ;; - 3.10) version="3.10.11" ;; - 3.11) version="3.11.7" ;; - 3.12) version="3.12.0" ;; - 3.13) version="3.13.0" ;; - 3.14) version="3.14.0" ;; - *) echo "Unknown Python version"; exit 1 ;; - esac - - installer_name="macos11.pkg" - installer_filename="python-${version}-${installer_name}" - url="https://www.python.org/ftp/python/${version}/${installer_filename}" - curl $url -o $installer_filename - sudo installer -pkg $installer_filename -target / - - - name: Install system dependencies - if: runner.os == 'macOS' - run: | - brew install --cask xquartz - brew uninstall cmake || echo "CMake was not pre-installed" - brew install flex bison cmake mpich - brew unlink mpich && brew install openmpi - # Install newer version of Bash on MacOS - brew install bash - # For debugging - bash --version - cmake --version - # Uninstall libomp for compatibility with issue #817 - brew uninstall --ignore-dependencies libomp || echo "libomp doesn't exist" - echo "$(brew --prefix)/opt/cmake/bin:$(brew --prefix)/opt/flex/bin:$(brew --prefix)/opt/bison/bin" >> $GITHUB_PATH - - - name: Install readline - if: runner.os == 'macOS' - run: | - sudo mkdir -p /opt/nrnwheel/$(uname -m) - sudo bash packaging/python/build_static_readline_osx.bash - - - name: Change name of package for release - if: inputs.build_type == 'release' - run: | - python3 -m venv venv - source venv/bin/activate - python3 -m pip install tomli tomli-w - python3 packaging/python/change_name.py ./pyproject.toml neuron - - - name: Optimize RX3D Python module - if: inputs.optimize_rxd == true - run: | - echo "NRN_RX3D_OPT_LEVEL=1" >> $GITHUB_ENV - - - name: Set custom version - if: inputs.version != '' - run: | - echo SETUPTOOLS_SCM_PRETEND_VERSION=${{ inputs.version }} >> $GITHUB_ENV - - - name: Build wheel - run: | - bash packaging/python/build_wheels.bash $(uname -s) ${{ inputs.python_version }} - - - name: Upload wheel files - uses: actions/upload-artifact@v4 - with: - name: wheels-${{ inputs.python_version }}-${{ inputs.platform }} - path: wheelhouse/*.whl - - - name: Setup Python ${{ inputs.python_version }} for testing - uses: actions/setup-python@v5 - with: - python-version: ${{ inputs.python_version }} - - - name: Install test dependencies - if: runner.os == 'Linux' - run: | - sudo apt update - sudo apt install -y mpich openmpi-bin libopenmpi-dev libmpich-dev - - - name: "Apply workaround for MPICH on Ubuntu 24.04" - if: inputs.platform == 'ubuntu-24.04' - run: | - # mpich is fundamentally broken on Ubuntu 24.04 LTS, for more details see: - # https://bugs.launchpad.net/ubuntu/+source/mpich/+bug/2072338 - # This is fixed in version 4.2.0-5.1, but this version has not been - # backported, so as a workaround, we install that version manually - sudo apt install -y mpich - wget 'https://launchpad.net/ubuntu/+source/mpich/4.2.0-5.1/+build/28285882/+files/mpich_4.2.0-5.1_amd64.deb' - wget 'https://launchpad.net/ubuntu/+source/mpich/4.2.0-5.1/+build/28285882/+files/libmpich12_4.2.0-5.1_amd64.deb' - sudo dpkg --install mpich_4.2.0-5.1_amd64.deb libmpich12_4.2.0-5.1_amd64.deb - - - name: Test wheel with ${{ inputs.python_version }} - run: | - minor_version="$(python${{ inputs.python_version }} -c 'import sys;print(sys.version_info.minor)')" - bash packaging/python/test_wheels.sh $(command -v python${{ inputs.python_version }}) wheelhouse/*cp3${minor_version}*.whl diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 699ed1723f..b339ded93d 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -67,11 +67,10 @@ jobs: - name: Build and Create Installer run: | - rm.exe C:\WINDOWS\system32\bash.EXE - %MSYS2_ROOT%\usr\bin\bash -lc "$BUILD_SOURCESDIRECTORY/ci/win_build_cmake.sh" + %MSYS2_ROOT%\usr\bin\bash "$BUILD_SOURCESDIRECTORY/ci/win_build_cmake.sh" # create a manifest of the files in the build directory - %MSYS2_ROOT%\usr\bin\bash -lc "find ${BUILD_SOURCESDIRECTORY}/build > ${BUILD_SOURCESDIRECTORY}/build/build_files.txt 2>/dev/null" - shell: cmd + %MSYS2_ROOT%\usr\bin\bash "find ${BUILD_SOURCESDIRECTORY}/build > ${BUILD_SOURCESDIRECTORY}/build/build_files.txt 2>/dev/null" + shell: pwsh working-directory: ${{runner.workspace}}\nrn env: BUILD_SOURCESDIRECTORY: ${{runner.workspace}}\nrn diff --git a/.github/workflows/yaml_validator.yml b/.github/workflows/yaml_validator.yml deleted file mode 100644 index 2440e1c1dc..0000000000 --- a/.github/workflows/yaml_validator.yml +++ /dev/null @@ -1,31 +0,0 @@ -# Ironically, if this file is not formatted properly, this won't work in the CI -name: Check YAML files - -concurrency: - # Don't cancel on master, creating a PR when a push workflow is already going will cancel the push workflow in favour of the PR workflow - group: ${{ github.workflow }}-${{ github.ref == 'refs/heads/master' && github.run_id || github.event.number && github.head_ref || github.ref_name }} - cancel-in-progress: true - -on: - merge_group: - push: - branches: - - release/** - pull_request: - branches: - - master - - release/** - -jobs: - all: - name: Validate YAML files - runs-on: ubuntu-latest - timeout-minutes: 5 - steps: - - name: Checkout repo - uses: actions/checkout@v4 - - - name: Check all YAML files - working-directory: ${{runner.workspace}}/nrn - run: | - ./ci/validate_yaml.sh diff --git a/CMakeLists.txt b/CMakeLists.txt index 760aef3c37..8190d1d25a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,7 +20,7 @@ project( VERSION 9.0.0 LANGUAGES C CXX HOMEPAGE_URL "https://www.neuron.yale.edu/neuron/") - +message(FATAL_ERROR "This fails") # ============================================================================= # CMake common project settings # ============================================================================= diff --git a/azure-pipelines.yml b/azure-pipelines.yml deleted file mode 100644 index f2128a64a6..0000000000 --- a/azure-pipelines.yml +++ /dev/null @@ -1,224 +0,0 @@ -#============================================================================= -# Azure Pipeline settings -#============================================================================= - -# Nightly build master for pypi upload -schedules: -- cron: "0 0 * * *" - branches: - include: - - master - always: true - -# Auto cancel old PR builds -pr: - autoCancel: true -# TODO : https://github.com/neuronsimulator/nrn/issues/1063 -# paths: -# exclude: -# - docs -# - README.md - -# Trigger build for certain branches only -trigger: -- master -- release/* - -stages: - - stage: BuildTestDeploy - jobs: - - - job: 'ManyLinuxWheels' - timeoutInMinutes: 45 - pool: - vmImage: 'ubuntu-24.04' - strategy: - matrix: - Python39: - python.version: '3.9' - python.nodot: '39' - Python310: - python.version: '3.10' - python.nodot: '310' - Python311: - python.version: '3.11' - python.nodot: '311' - Python312: - python.version: '3.12' - python.nodot: '312' - Python313: - python.version: '3.13' - python.nodot: '313' - Python314: - python.version: '3.14' - python.nodot: '314' - - steps: - - # Secure files documentation: - # https://docs.microsoft.com/en-us/azure/devops/pipelines/library/secure-files?view=azure-devops - # NOTE: when uploading new secure files, access must be permitted from the Azure pipeline interface (check message there) - - task: DownloadSecureFile@1 - name: mpt_headersSF - displayName: 'Download mpt_headers secure file' - inputs: - secureFile: 'mpt_headears.2.21.tar.gz' - - - script: | - python3 -m pip install tomli tomli-w - python3 packaging/python/change_name.py ./pyproject.toml neuron - condition: and(in(variables['Build.Reason'], 'Manual'), eq(variables['NRN_RELEASE_UPLOAD'], 'true')) - displayName: 'Change name of package for release' - - # Note that mpt headers must be mounted in the docker imager under `/nrnwheel/mpt` - # This path is checked by `packaging/python/build_wheels.bash` when run in the image. - - script: | - if [ "$BUILD_REASON" = "Manual" ] || [ "$BUILD_REASON" = "Schedule" ]; then - export NRN_RX3D_OPT_LEVEL=1 - fi - sudo mkdir -p /opt/nrnwheel/mpt - sudo tar -zxf $(mpt_headersSF.secureFilePath) --directory /opt/nrnwheel/mpt - packaging/python/build_wheels.bash linux $(python.nodot) - displayName: 'Building ManyLinux Wheel' - - - script: | - sudo apt update - sudo apt install -y mpich openmpi-bin libopenmpi-dev libmpich-dev - # mpich is fundamentally broken on Ubuntu 24.04 LTS, for more details see: - # https://bugs.launchpad.net/ubuntu/+source/mpich/+bug/2072338 - # This is fixed in version 4.2.0-5.1, but this version has not been - # backported, so as a workaround, we install that version manually - source /etc/os-release - if [[ "$ID" == "ubuntu" && "$VERSION_ID" == "24.04" ]]; then - # mpich is fundamentally broken on Ubuntu 24.04 LTS, for more details see: - # https://bugs.launchpad.net/ubuntu/+source/mpich/+bug/2072338 - # This is fixed in version 4.2.0-5.1, but this version has not been - # backported, so as a workaround, we install that version manually - sudo apt install -y mpich - wget 'https://launchpad.net/ubuntu/+source/mpich/4.2.0-5.1/+build/28285882/+files/mpich_4.2.0-5.1_amd64.deb' - wget 'https://launchpad.net/ubuntu/+source/mpich/4.2.0-5.1/+build/28285882/+files/libmpich12_4.2.0-5.1_amd64.deb' - sudo dpkg --install mpich_4.2.0-5.1_amd64.deb libmpich12_4.2.0-5.1_amd64.deb - fi - displayName: 'Install Test System Dependencies' - - - template: ci/azure-wheel-test-upload.yml - - - # Jobs to build OSX wheels natively - - job: 'MacOSWheels' - timeoutInMinutes: 60 - pool: - vmImage: 'macOS-15' - strategy: - matrix: - Python39: - python.version: '3.9' - python.nodot: '39' - python.org.version: '3.9.13' - python.installer.name: 'macos11.pkg' - Python310: - python.version: '3.10' - python.nodot: '310' - python.org.version: '3.10.11' - python.installer.name: 'macos11.pkg' - Python311: - python.version: '3.11' - python.nodot: '311' - python.org.version: '3.11.7' - python.installer.name: 'macos11.pkg' - Python312: - python.version: '3.12' - python.nodot: '312' - python.org.version: '3.12.0' - python.installer.name: 'macos11.pkg' - Python313: - python.version: '3.13' - python.nodot: '313' - python.org.version: '3.13.0' - python.installer.name: 'macos11.pkg' - Python314: - python.version: '3.14' - python.nodot: '314' - python.org.version: '3.14.0' - python.installer.name: 'macos11.pkg' - - steps: - - - script: | - installer=python-$(python.org.version)-$(python.installer.name) - url=https://www.python.org/ftp/python/$(python.org.version)/$installer - curl $url -o $installer - sudo installer -pkg $installer -target / - displayName: 'Install Python from python.org' - - - script: | - brew install --cask xquartz - brew install flex bison mpich - brew unlink mpich && brew install openmpi - cmake --version - # the version of bash used by Azure (which is the default one - # provided by Apple) is too old and does not support associative - # arrays. This is because newer versions of bash have switched their - # license from GNU GPL v2 to GNU GPL v3, and Apple refuses to add any - # GNU GPL v3-licenced software in their stack, so we need to install - # the homebrew one - brew install bash - bash --version - # see https://github.com/BlueBrain/CoreNeuron/issues/817, uninstall libomp until we fix this - # as we are building wheels, we shouldn't enable OpenMP here anyway - brew uninstall --ignore-dependencies libomp || echo "libomp doesn't exist" - displayName: 'Install OSX System Dependencies' - - # readline has been manually built with ncurses and MACOSX_DEPLOYMENT_TARGET=10.9 and stored as secure file on Azure. - # See `packaging/python/Dockerfile` for build instructions. - # - # Secure files documentation: - # https://docs.microsoft.com/en-us/azure/devops/pipelines/library/secure-files?view=azure-devops - # NOTE: when uploading new secure files, access must be permitted from the Azure pipeline interface (check message there) - - task: DownloadSecureFile@1 - name: readlineSF - displayName: 'Download readline secure file' - inputs: - secureFile: 'readline7.0-ncurses6.4.tar.gz' - - - script: | - python3 -m pip install tomli tomli-w - python3 packaging/python/change_name.py ./pyproject.toml neuron - condition: and(in(variables['Build.Reason'], 'Manual'), eq(variables['NRN_RELEASE_UPLOAD'], 'true')) - displayName: 'Change name of package for release' - - - script: | - export PATH=/usr/local/opt/flex/bin:/usr/local/opt/bison/bin:$PATH - export SDKROOT=$(xcrun --sdk macosx --show-sdk-path) - if [ "$BUILD_REASON" = "Manual" ] || [ "$BUILD_REASON" = "Schedule" ]; then - export NRN_RX3D_OPT_LEVEL=1 - fi - sudo mkdir -p /opt/nrnwheel/$(uname -m) - sudo tar -zxf $(readlineSF.secureFilePath) --directory /opt/nrnwheel/$(uname -m) - packaging/python/build_wheels.bash osx $(python.nodot) - displayName: 'Build MacOS Wheel' - - - template: ci/azure-wheel-test-upload.yml - - - - stage: Final - jobs: - - job: AzureDropURL - pool: - vmImage: 'ubuntu-22.04' - condition: eq(variables['Build.Reason'], 'PullRequest') - steps: - - checkout: none - - script: | - export AZURE_DROP_URL=`curl -v 'https://dev.azure.com/neuronsimulator/nrn/_apis/build/builds/$(Build.BuildId)/artifacts?artifactName=drop' | jq -r '.resource.downloadUrl'` - echo "Setting dropurl to $AZURE_DROP_URL" - echo "##vso[task.setvariable variable=dropurl]$AZURE_DROP_URL" - displayName: 'Resolve Azure drop URL' - - - task: GitHubComment@0 - continueOnError: true - inputs: - gitHubConnection: 'neuronsimulator' - repositoryName: '$(Build.Repository.Name)' - comment: | - ✔️ $(system.pullRequest.sourceCommitId) -> [Azure artifacts URL]($(dropurl))