From 2ec573c77cdc8a7e21e055188d5ce9f62da374b1 Mon Sep 17 00:00:00 2001 From: Kevin Marchais Date: Sun, 25 Jan 2026 21:49:24 +0100 Subject: [PATCH 01/12] Refactor CI workflows: reduce duplication, update actions, add release workflow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ci.yml: Convert 3 separate jobs to single matrix strategy (~26% reduction) - carma-conda.yml: Refactor 4 jobs to matrix, use API token auth (83→41 lines) - conda-packaging.yml: Remove PR trigger, add upload input for manual control - build.yml: Update checkout v5→v6, setup-uv v6→v7 - build-doc.yml: Fix deprecated set-output, update cache v3→v4, checkout v6 - release.yml: New workflow for automated releases on tag/publish - Delete 4 obsolete platform-specific conda workflows (superseded by conda-packaging.yml) --- .github/workflows/build-doc.yml | 6 +- .github/workflows/build.yml | 4 +- .github/workflows/carma-conda.yml | 100 +++++--------- .github/workflows/ci.yml | 120 +++++++---------- .github/workflows/conda-packaging-linux.yml | 37 ------ .github/workflows/conda-packaging-osx-64.yml | 43 ------ .../workflows/conda-packaging-osx-arm64.yml | 43 ------ .github/workflows/conda-packaging-windows.yml | 35 ----- .github/workflows/conda-packaging.yml | 18 +-- .github/workflows/release.yml | 122 ++++++++++++++++++ 10 files changed, 207 insertions(+), 321 deletions(-) delete mode 100644 .github/workflows/conda-packaging-linux.yml delete mode 100644 .github/workflows/conda-packaging-osx-64.yml delete mode 100644 .github/workflows/conda-packaging-osx-arm64.yml delete mode 100644 .github/workflows/conda-packaging-windows.yml create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/build-doc.yml b/.github/workflows/build-doc.yml index 5be02d4d5..bd97a0478 100644 --- a/.github/workflows/build-doc.yml +++ b/.github/workflows/build-doc.yml @@ -18,7 +18,7 @@ jobs: shell: bash -el {0} steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: conda-incubator/setup-miniconda@v3 with: miniconda-version: "latest" @@ -29,10 +29,10 @@ jobs: - name: Get Date id: get-date - run: echo "::set-output name=today::$(/bin/date -u '+%Y%m%d')" + run: echo "today=$(/bin/date -u '+%Y%m%d')" >> $GITHUB_OUTPUT - name: Cache Conda env - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: ${{ env.CONDA }}/envs key: conda-${{ runner.os }}--${{ runner.arch }}--${{ steps.get-date.outputs.today }}-${{ hashFiles('environment_doc.yml') }}-${{ env.CACHE_NUMBER }} diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e1e1edcf1..7b13f9415 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -32,7 +32,7 @@ jobs: name: ${{ matrix.os }} steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - name: Install system dependencies if: matrix.sys-package-install-command != '' @@ -43,7 +43,7 @@ jobs: run: ${{ matrix.setup-env-command }} - name: Setup uv - uses: astral-sh/setup-uv@v6 + uses: astral-sh/setup-uv@v7 - name: Editable install run: | diff --git a/.github/workflows/carma-conda.yml b/.github/workflows/carma-conda.yml index 42527c6a5..8acb7ef0f 100644 --- a/.github/workflows/carma-conda.yml +++ b/.github/workflows/carma-conda.yml @@ -4,79 +4,37 @@ on: workflow_dispatch: jobs: - Linux: - name: Linux - runs-on: "ubuntu-latest" - steps: - - uses: actions/checkout@v2 - - uses: conda-incubator/setup-miniconda@v2 - with: - miniconda-version: "latest" - activate-environment: packaging - - name: Conda build for Linux - shell: bash -l {0} - run: | - conda update --all - conda install python=3.11 conda-build anaconda-client conda-verify - conda-build carma.recipe -c conda-forge -c set3mah --output-folder . - anaconda login --username ${{ secrets.ANACONDA_USERNAME }} --password ${{ secrets.ANACONDA_PASSWORD }} - anaconda upload linux-64/*.conda --force - anaconda logout - - macos: - name: MacOS - runs-on: "macos-14" - steps: - - uses: actions/checkout@v2 - - uses: conda-incubator/setup-miniconda@v2 - with: - miniconda-version: "latest" - activate-environment: packaging - - name: Conda build for MacOS - shell: bash -l {0} - run: | - conda update --all - conda install python=3.11 conda-build anaconda-client conda-verify - conda-build carma.recipe -c conda-forge -c set3mah --output-folder . - anaconda login --username ${{ secrets.ANACONDA_USERNAME }} --password ${{ secrets.ANACONDA_PASSWORD }} - anaconda upload osx-64/*.conda --force - anaconda logout - - macos-arm64: - name: MacOS-arm64 - runs-on: "macos-14-arm64" - steps: - - uses: actions/checkout@v2 - - uses: conda-incubator/setup-miniconda@v2 - with: - miniconda-version: "latest" - activate-environment: packaging - - name: Conda build for MacOS - arm64 - shell: bash -l {0} - run: | - conda update --all - conda install python=3.11 conda-build anaconda-client conda-verify - conda-build carma.recipe -c conda-forge -c set3mah --output-folder . - anaconda login --username ${{ secrets.ANACONDA_USERNAME }} --password ${{ secrets.ANACONDA_PASSWORD }} - anaconda upload osx-arm64/*.conda --force - anaconda logout + build: + name: ${{ matrix.os }} + runs-on: ${{ matrix.runner }} + strategy: + fail-fast: false + matrix: + include: + - os: Linux + runner: ubuntu-latest + target-platform: linux-64 + - os: MacOS + runner: macos-latest + target-platform: osx-arm64 + - os: Windows + runner: windows-latest + target-platform: win-64 - - windows: - name: Windows - runs-on: "windows-latest" steps: - - uses: actions/checkout@v2 - - uses: conda-incubator/setup-miniconda@v2 + - uses: actions/checkout@v6 + + - uses: conda-incubator/setup-miniconda@v3 with: - miniconda-version: "latest" + miniconda-version: latest activate-environment: packaging - - name: Conda build for Windows - shell: pwsh + + - name: Conda build and upload + shell: bash -l {0} + env: + ANACONDA_API_TOKEN: ${{ secrets.ANACONDA_API_TOKEN }} run: | - conda update --all - conda install python=3.11 conda-build anaconda-client conda-verify - conda-build carma.recipe -c conda-forge -c set3mah --output-folder . - anaconda login --username ${{ secrets.ANACONDA_USERNAME }} --password ${{ secrets.ANACONDA_PASSWORD }} - anaconda upload win-64/*.conda --force - anaconda logout + conda update --all -y + conda install -y python=3.11 conda-build anaconda-client conda-verify + conda-build carma.recipe -c conda-forge -c set3mah --output-folder . + anaconda upload ${{ matrix.target-platform }}/*.conda --force diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f55dd4335..4061c8066 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,5 +1,4 @@ name: Build & Test -#build and test on the three OS on: workflow_dispatch: @@ -13,96 +12,61 @@ permissions: actions: read jobs: - Linux: - name: Linux - runs-on: "ubuntu-latest" + build-and-test: + name: ${{ matrix.os }} + runs-on: ${{ matrix.runner }} + strategy: + fail-fast: false + matrix: + include: + - os: Linux + runner: ubuntu-latest + environment-file: environment.yml + shell: bash -l {0} + - os: MacOS + runner: macos-latest + environment-file: environment_arm64.yml + shell: bash -l {0} + - os: Windows + runner: windows-latest + environment-file: environment_win.yml + shell: pwsh + + defaults: + run: + shell: ${{ matrix.shell }} + steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 + - uses: conda-incubator/setup-miniconda@v3 with: miniconda-version: "latest" activate-environment: foo - python-version: "3.12" - environment-file: environment.yml + python-version: ${{ matrix.os == 'Linux' && '3.12' || '' }} + environment-file: ${{ matrix.environment-file }} channels: conda-forge,set3mah - - name: Prepare conda environment - shell: bash -l {0} + - name: Prepare conda environment (Unix) + if: runner.os != 'Windows' run: | conda config --env --add channels conda-forge conda config --env --add channels set3mah conda config --env --set channel_priority strict - - name: Build for Linux - shell: bash -l {0} + - name: Build (Unix) + if: runner.os != 'Windows' run: | - cmake -S . -B ${{github.workspace}}/build -G Ninja \ + cmake -S . -B ${{ github.workspace }}/build -G Ninja \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_INCLUDE_PATH=$CONDA_PREFIX/include \ -DCMAKE_LIBRARY_PATH=$CONDA_PREFIX/lib \ -DCMAKE_INSTALL_PREFIX=$CONDA_PREFIX \ -Wno-dev - cmake --build ${{github.workspace}}/build - - - name: Tests - shell: bash -l {0} - run: ctest --test-dir ${{github.workspace}}/build --output-on-failure - - - name: Upload test logs as artifact - if: always() # Ensure this step runs even if the tests fail - uses: actions/upload-artifact@v4 - with: - name: test-logs-Linux - path: build/Testing/Temporary/LastTest.log - retention-days: 7 + cmake --build ${{ github.workspace }}/build - MacOS: - name: MacOS - runs-on: "macos-latest" - steps: - - uses: actions/checkout@v5 - - uses: conda-incubator/setup-miniconda@v3 - with: - miniconda-version: "latest" - activate-environment: foo - environment-file: environment_arm64.yml - - - name: Build for MacOS - shell: bash -l {0} - run: | - cmake -S . -B ${{github.workspace}}/build -G Ninja \ - -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_INCLUDE_PATH=$CONDA_PREFIX/include \ - -DCMAKE_LIBRARY_PATH=$CONDA_PREFIX/lib \ - -DCMAKE_INSTALL_PREFIX=$CONDA_PREFIX \ - -Wno-dev - cmake --build ${{github.workspace}}/build - - - name: Tests - shell: bash -l {0} - run: ctest --test-dir ${{github.workspace}}/build --output-on-failure - - - name: Upload test logs as artifact - if: always() # Ensure this step runs even if the tests fail - uses: actions/upload-artifact@v4 - with: - name: test-logs-OSX - path: build/Testing/Temporary/LastTest.log - retention-days: 7 - - Windows: - name: Windows - runs-on: "windows-latest" - steps: - - uses: actions/checkout@v5 - - uses: conda-incubator/setup-miniconda@v3 - with: - miniconda-version: "latest" - activate-environment: foo - environment-file: environment_win.yml - - - name: Build for Windows - shell: pwsh + - name: Build (Windows) + if: runner.os == 'Windows' run: | cmake -S . -B build ` -DCMAKE_BUILD_TYPE=Release ` @@ -110,14 +74,18 @@ jobs: -Wno-dev cmake --build build --config Release - - name: Tests - shell: pwsh + - name: Tests (Unix) + if: runner.os != 'Windows' + run: ctest --test-dir ${{ github.workspace }}/build --output-on-failure + + - name: Tests (Windows) + if: runner.os == 'Windows' run: ctest --test-dir build -C Release --output-on-failure -VV - name: Upload test logs as artifact - if: always() # Ensure this step runs even if the tests fail + if: always() uses: actions/upload-artifact@v4 with: - name: test-logs-Win + name: test-logs-${{ matrix.os }} path: build/Testing/Temporary/LastTest.log retention-days: 7 diff --git a/.github/workflows/conda-packaging-linux.yml b/.github/workflows/conda-packaging-linux.yml deleted file mode 100644 index 3f931864e..000000000 --- a/.github/workflows/conda-packaging-linux.yml +++ /dev/null @@ -1,37 +0,0 @@ -name: Conda packaging linux - -on: - workflow_dispatch: - -jobs: - Linux: - name: Linux - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - uses: conda-incubator/setup-miniconda@v2 - with: - miniconda-version: "latest" - auto-update-conda: true - - - name: Install Dependencies - shell: bash -l {0} - run: | - conda update --all - conda clean --all - conda install conda-build anaconda-client conda-verify - conda config --set anaconda_upload no - - - name: Build Package - shell: bash -l {0} - run: | - conda-build conda.recipe -c set3mah -c conda-forge --no-test --output-folder . - - - name: Upload to Anaconda - shell: bash -l {0} - env: - ANACONDA_API_TOKEN: ${{ secrets.ANACONDA_TOKEN }} - run: | - anaconda upload linux-64/*.conda --force - diff --git a/.github/workflows/conda-packaging-osx-64.yml b/.github/workflows/conda-packaging-osx-64.yml deleted file mode 100644 index e531ef9cf..000000000 --- a/.github/workflows/conda-packaging-osx-64.yml +++ /dev/null @@ -1,43 +0,0 @@ -name: Conda packaging osx-x86-64 - -on: - workflow_dispatch: - -jobs: - macos: - name: MacOS - runs-on: macos-latest - - steps: - - uses: actions/checkout@v4 - - - uses: conda-incubator/setup-miniconda@v2 - with: - miniconda-version: "latest" - auto-update-conda: true - - - name: Configure Conda for osx-64 - shell: bash -l {0} - run: | - conda config --set subdir osx-64 - echo "CONDA_SUBDIR=osx-64" >> $GITHUB_ENV - - - name: Install Dependencies - shell: bash -l {0} - run: | - conda update --all - conda clean --all - conda install conda-build anaconda-client conda-verify - conda config --set anaconda_upload no - - - name: Build Package - shell: bash -l {0} - run: | - conda-build conda.recipe -c set3mah -c conda-forge --no-test --output-folder . - - - name: Upload Conda Packages - shell: bash -l {0} - env: - ANACONDA_API_TOKEN: ${{ secrets.ANACONDA_TOKEN }} - run: | - anaconda upload osx-64/*.conda --force diff --git a/.github/workflows/conda-packaging-osx-arm64.yml b/.github/workflows/conda-packaging-osx-arm64.yml deleted file mode 100644 index 95a83fb50..000000000 --- a/.github/workflows/conda-packaging-osx-arm64.yml +++ /dev/null @@ -1,43 +0,0 @@ -name: Conda packaging osx-arm64 - -on: - workflow_dispatch: - -jobs: - macos: - name: MacOS - runs-on: macos-latest - - steps: - - uses: actions/checkout@v4 - - - uses: conda-incubator/setup-miniconda@v2 - with: - miniconda-version: "latest" - auto-update-conda: true - - - name: Configure Conda for osx-arm64 - shell: bash -l {0} - run: | - conda config --set subdir osx-arm64 - echo "CONDA_SUBDIR=osx-arm64" >> $GITHUB_ENV - - - name: Install Dependencies - shell: bash -l {0} - run: | - conda update --all - conda clean --all - conda install conda-build anaconda-client conda-verify - conda config --set anaconda_upload no - - - name: Build Package - shell: bash -l {0} - run: | - conda-build conda.recipe -c set3mah -c conda-forge --no-test --output-folder . - - - name: Upload Conda Packages - shell: bash -l {0} - env: - ANACONDA_API_TOKEN: ${{ secrets.ANACONDA_TOKEN }} - run: | - anaconda upload osx-arm64/*.conda --force \ No newline at end of file diff --git a/.github/workflows/conda-packaging-windows.yml b/.github/workflows/conda-packaging-windows.yml deleted file mode 100644 index 116d7faa7..000000000 --- a/.github/workflows/conda-packaging-windows.yml +++ /dev/null @@ -1,35 +0,0 @@ -name: Conda packaging windows - -on: - workflow_dispatch: - -jobs: - windows: - name: Windows - runs-on: windows-latest - steps: - - uses: actions/checkout@v4 - - uses: conda-incubator/setup-miniconda@v2 - with: - miniconda-version: "latest" - - - name: Install Dependencies - shell: pwsh - run: | - conda update --all - conda clean --all - conda install conda-build anaconda-client conda-verify - conda config --set anaconda_upload no - - - name: Build Package - shell: pwsh - run: | - conda-build conda.recipe -c set3mah -c conda-forge --no-test --output-folder . - - - name: Upload to Anaconda - shell: pwsh - env: - ANACONDA_API_TOKEN: ${{ secrets.ANACONDA_TOKEN }} - run: | - set ANACONDA_API_TOKEN=${{ secrets.ANACONDA_TOKEN }} - anaconda upload win-64/*.conda --force \ No newline at end of file diff --git a/.github/workflows/conda-packaging.yml b/.github/workflows/conda-packaging.yml index 74a885ce4..9a3f31222 100644 --- a/.github/workflows/conda-packaging.yml +++ b/.github/workflows/conda-packaging.yml @@ -2,13 +2,11 @@ name: Conda packaging on: workflow_dispatch: - pull_request: - paths: - - "CMakeLists.txt" - - "**/CMakeLists.txt" - - "conda.recipe/**" - - ".github/workflows/conda-packaging.yml" - - "environment*.yml" + inputs: + upload: + description: 'Upload packages to Anaconda' + type: boolean + default: true permissions: contents: read @@ -33,7 +31,7 @@ jobs: target-platform: win-64 steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: conda-incubator/setup-miniconda@v3 with: miniforge-version: latest @@ -42,8 +40,6 @@ jobs: conda-solver: libmamba - name: Conda build - env: - CONDA_BUILD_LOCAL: ${{ github.event_name == 'pull_request' && '1' || '' }} shell: bash -l {0} run: | conda install -y conda-build conda-index @@ -166,7 +162,7 @@ jobs: conda run -n test-install python -c "import simcoon; import simcoon.simmit; print('Import successful')" - name: Upload to Anaconda - if: github.event_name == 'workflow_dispatch' + if: inputs.upload env: ANACONDA_API_TOKEN: ${{ secrets.ANACONDA_API_TOKEN }} run: | diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000..a979cb31a --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,122 @@ +name: Release + +on: + release: + types: [published] + push: + tags: + - 'v*' + workflow_dispatch: + inputs: + tag: + description: 'Tag to release (e.g., v1.0.0)' + required: true + +permissions: + contents: write + actions: read + +jobs: + build-conda: + name: Build ${{ matrix.os }} + runs-on: ${{ matrix.runner }} + strategy: + fail-fast: false + matrix: + include: + - os: Linux + runner: ubuntu-latest + target-platform: linux-64 + - os: MacOS + runner: macos-latest + target-platform: osx-arm64 + - os: Windows + runner: windows-latest + target-platform: win-64 + + steps: + - uses: actions/checkout@v6 + with: + ref: ${{ inputs.tag || github.ref }} + + - uses: conda-incubator/setup-miniconda@v3 + with: + miniforge-version: latest + activate-environment: packaging + auto-update-conda: true + conda-solver: libmamba + + - name: Conda build + shell: bash -l {0} + run: | + conda install -y conda-build conda-index + conda build conda.recipe -c conda-forge -c set3mah --output-folder . + python -m conda_index . + + - name: Install and verify package (Unix) + if: runner.os != 'Windows' + shell: bash -l {0} + run: | + conda create -n test-install -y python simcoon -c file://$PWD -c conda-forge -c set3mah + conda run -n test-install python -c "import simcoon; import simcoon.simmit; print('Import successful')" + + - name: Install and verify package (Windows) + if: runner.os == 'Windows' + shell: pwsh + run: | + $localChannel = "file:///" + ($PWD.Path -replace '\\', '/') + conda create -n test-install -y python simcoon -c $localChannel -c conda-forge -c set3mah + conda run -n test-install python -c "import simcoon; import simcoon.simmit; print('Import successful')" + + - name: Upload conda package artifact + uses: actions/upload-artifact@v4 + with: + name: conda-${{ matrix.target-platform }} + path: ${{ matrix.target-platform }}/*.conda + retention-days: 30 + + upload-anaconda: + name: Upload to Anaconda + needs: build-conda + runs-on: ubuntu-latest + steps: + - uses: actions/download-artifact@v4 + with: + pattern: conda-* + merge-multiple: false + + - uses: conda-incubator/setup-miniconda@v3 + with: + miniforge-version: latest + activate-environment: upload + + - name: Upload all packages to Anaconda + shell: bash -l {0} + env: + ANACONDA_API_TOKEN: ${{ secrets.ANACONDA_API_TOKEN }} + run: | + conda install -y anaconda-client + for dir in conda-*/; do + echo "Uploading packages from $dir" + anaconda upload "$dir"*.conda --force --no-progress + done + + upload-release-assets: + name: Attach to GitHub Release + needs: build-conda + runs-on: ubuntu-latest + if: github.event_name == 'release' + steps: + - uses: actions/download-artifact@v4 + with: + pattern: conda-* + merge-multiple: false + + - name: Upload release assets + env: + GH_TOKEN: ${{ github.token }} + run: | + for file in conda-*/*.conda; do + echo "Uploading $file to release" + gh release upload "${{ github.event.release.tag_name }}" "$file" --repo "${{ github.repository }}" + done From 1e282c3d7e4ee2fedbf1fa8cb680f065a42798a5 Mon Sep 17 00:00:00 2001 From: Kevin Marchais Date: Sun, 25 Jan 2026 21:59:58 +0100 Subject: [PATCH 02/12] Add PR trigger for conda-packaging.yml self-changes --- .github/workflows/conda-packaging.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/conda-packaging.yml b/.github/workflows/conda-packaging.yml index 9a3f31222..ad239f10d 100644 --- a/.github/workflows/conda-packaging.yml +++ b/.github/workflows/conda-packaging.yml @@ -7,6 +7,9 @@ on: description: 'Upload packages to Anaconda' type: boolean default: true + pull_request: + paths: + - '.github/workflows/conda-packaging.yml' permissions: contents: read From 54381c0c7d3e4a8a3de50287ba526c054a579a92 Mon Sep 17 00:00:00 2001 From: Kevin Marchais Date: Sun, 25 Jan 2026 22:07:22 +0100 Subject: [PATCH 03/12] Remove upload-release-assets job (GitHub auto-creates source archives) --- .github/workflows/release.yml | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a979cb31a..56bd49f0e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -101,22 +101,3 @@ jobs: anaconda upload "$dir"*.conda --force --no-progress done - upload-release-assets: - name: Attach to GitHub Release - needs: build-conda - runs-on: ubuntu-latest - if: github.event_name == 'release' - steps: - - uses: actions/download-artifact@v4 - with: - pattern: conda-* - merge-multiple: false - - - name: Upload release assets - env: - GH_TOKEN: ${{ github.token }} - run: | - for file in conda-*/*.conda; do - echo "Uploading $file to release" - gh release upload "${{ github.event.release.tag_name }}" "$file" --repo "${{ github.repository }}" - done From ffbf3666b9579cb78197d706af5ff3736b20e7fa Mon Sep 17 00:00:00 2001 From: Kevin Marchais Date: Mon, 26 Jan 2026 09:00:14 +0100 Subject: [PATCH 04/12] Make conda-packaging.yml reusable, simplify release.yml to call it --- .github/workflows/conda-packaging.yml | 17 +++++ .github/workflows/release.yml | 95 ++------------------------- 2 files changed, 24 insertions(+), 88 deletions(-) diff --git a/.github/workflows/conda-packaging.yml b/.github/workflows/conda-packaging.yml index ad239f10d..48b47fdf6 100644 --- a/.github/workflows/conda-packaging.yml +++ b/.github/workflows/conda-packaging.yml @@ -7,6 +7,19 @@ on: description: 'Upload packages to Anaconda' type: boolean default: true + workflow_call: + inputs: + upload: + description: 'Upload packages to Anaconda' + type: boolean + default: true + ref: + description: 'Git ref to checkout' + type: string + required: false + secrets: + ANACONDA_API_TOKEN: + required: false pull_request: paths: - '.github/workflows/conda-packaging.yml' @@ -35,6 +48,9 @@ jobs: steps: - uses: actions/checkout@v6 + with: + ref: ${{ inputs.ref || github.ref }} + - uses: conda-incubator/setup-miniconda@v3 with: miniforge-version: latest @@ -166,6 +182,7 @@ jobs: - name: Upload to Anaconda if: inputs.upload + shell: bash -l {0} env: ANACONDA_API_TOKEN: ${{ secrets.ANACONDA_API_TOKEN }} run: | diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 56bd49f0e..ec97ea89a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,92 +12,11 @@ on: description: 'Tag to release (e.g., v1.0.0)' required: true -permissions: - contents: write - actions: read - jobs: - build-conda: - name: Build ${{ matrix.os }} - runs-on: ${{ matrix.runner }} - strategy: - fail-fast: false - matrix: - include: - - os: Linux - runner: ubuntu-latest - target-platform: linux-64 - - os: MacOS - runner: macos-latest - target-platform: osx-arm64 - - os: Windows - runner: windows-latest - target-platform: win-64 - - steps: - - uses: actions/checkout@v6 - with: - ref: ${{ inputs.tag || github.ref }} - - - uses: conda-incubator/setup-miniconda@v3 - with: - miniforge-version: latest - activate-environment: packaging - auto-update-conda: true - conda-solver: libmamba - - - name: Conda build - shell: bash -l {0} - run: | - conda install -y conda-build conda-index - conda build conda.recipe -c conda-forge -c set3mah --output-folder . - python -m conda_index . - - - name: Install and verify package (Unix) - if: runner.os != 'Windows' - shell: bash -l {0} - run: | - conda create -n test-install -y python simcoon -c file://$PWD -c conda-forge -c set3mah - conda run -n test-install python -c "import simcoon; import simcoon.simmit; print('Import successful')" - - - name: Install and verify package (Windows) - if: runner.os == 'Windows' - shell: pwsh - run: | - $localChannel = "file:///" + ($PWD.Path -replace '\\', '/') - conda create -n test-install -y python simcoon -c $localChannel -c conda-forge -c set3mah - conda run -n test-install python -c "import simcoon; import simcoon.simmit; print('Import successful')" - - - name: Upload conda package artifact - uses: actions/upload-artifact@v4 - with: - name: conda-${{ matrix.target-platform }} - path: ${{ matrix.target-platform }}/*.conda - retention-days: 30 - - upload-anaconda: - name: Upload to Anaconda - needs: build-conda - runs-on: ubuntu-latest - steps: - - uses: actions/download-artifact@v4 - with: - pattern: conda-* - merge-multiple: false - - - uses: conda-incubator/setup-miniconda@v3 - with: - miniforge-version: latest - activate-environment: upload - - - name: Upload all packages to Anaconda - shell: bash -l {0} - env: - ANACONDA_API_TOKEN: ${{ secrets.ANACONDA_API_TOKEN }} - run: | - conda install -y anaconda-client - for dir in conda-*/; do - echo "Uploading packages from $dir" - anaconda upload "$dir"*.conda --force --no-progress - done - + conda-packaging: + uses: ./.github/workflows/conda-packaging.yml + with: + upload: true + ref: ${{ inputs.tag || github.ref }} + secrets: + ANACONDA_API_TOKEN: ${{ secrets.ANACONDA_API_TOKEN }} From 045804d0cd197082a0c0441070f9e8a81a27f76f Mon Sep 17 00:00:00 2001 From: Kevin Marchais Date: Mon, 26 Jan 2026 09:27:40 +0100 Subject: [PATCH 05/12] Use Python 3.14 consistently, expand conda-packaging PR triggers - ci.yml: Replace conditional python-version logic with 3.14 for all platforms - conda-packaging.yml: Trigger on conda.recipe/**, environment*.yml changes --- .github/workflows/ci.yml | 2 +- .github/workflows/conda-packaging.yml | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4061c8066..c50e3a1cd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -43,7 +43,7 @@ jobs: with: miniconda-version: "latest" activate-environment: foo - python-version: ${{ matrix.os == 'Linux' && '3.12' || '' }} + python-version: "3.14" environment-file: ${{ matrix.environment-file }} channels: conda-forge,set3mah diff --git a/.github/workflows/conda-packaging.yml b/.github/workflows/conda-packaging.yml index 48b47fdf6..4690ce010 100644 --- a/.github/workflows/conda-packaging.yml +++ b/.github/workflows/conda-packaging.yml @@ -22,7 +22,9 @@ on: required: false pull_request: paths: + - 'conda.recipe/**' - '.github/workflows/conda-packaging.yml' + - 'environment*.yml' permissions: contents: read From d77b8362fafb81caced4fb22f6f31150cc306a3a Mon Sep 17 00:00:00 2001 From: Kevin Marchais Date: Mon, 26 Jan 2026 09:35:32 +0100 Subject: [PATCH 06/12] Use Python 3.13 (carma doesn't support 3.14 yet) --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c50e3a1cd..d4d89e62a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -43,7 +43,7 @@ jobs: with: miniconda-version: "latest" activate-environment: foo - python-version: "3.14" + python-version: "3.13" environment-file: ${{ matrix.environment-file }} channels: conda-forge,set3mah From d8871d868bbff2c44b92a0d63b8e1eddeb131327 Mon Sep 17 00:00:00 2001 From: Kevin Marchais Date: Mon, 26 Jan 2026 11:52:23 +0100 Subject: [PATCH 07/12] Remove unnecessary ${{ github.workspace }} from ci.yml --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d4d89e62a..b7c0479f9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -57,13 +57,13 @@ jobs: - name: Build (Unix) if: runner.os != 'Windows' run: | - cmake -S . -B ${{ github.workspace }}/build -G Ninja \ + cmake -S . -B build -G Ninja \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_INCLUDE_PATH=$CONDA_PREFIX/include \ -DCMAKE_LIBRARY_PATH=$CONDA_PREFIX/lib \ -DCMAKE_INSTALL_PREFIX=$CONDA_PREFIX \ -Wno-dev - cmake --build ${{ github.workspace }}/build + cmake --build build - name: Build (Windows) if: runner.os == 'Windows' @@ -76,7 +76,7 @@ jobs: - name: Tests (Unix) if: runner.os != 'Windows' - run: ctest --test-dir ${{ github.workspace }}/build --output-on-failure + run: ctest --test-dir build --output-on-failure - name: Tests (Windows) if: runner.os == 'Windows' From 2b794e1a212a79b2e6f63a95610b7d384455a639 Mon Sep 17 00:00:00 2001 From: Kevin Marchais Date: Mon, 26 Jan 2026 15:12:11 +0100 Subject: [PATCH 08/12] Use Python 3.14, align Windows env with Linux/macOS - Use unqualified carma from conda-forge (like other platforms) - Align channel order: conda-forge first, then set3mah - Bump Python to 3.14 --- .github/workflows/ci.yml | 2 +- environment_win.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b7c0479f9..1e2aaee8b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -43,7 +43,7 @@ jobs: with: miniconda-version: "latest" activate-environment: foo - python-version: "3.13" + python-version: "3.14" environment-file: ${{ matrix.environment-file }} channels: conda-forge,set3mah diff --git a/environment_win.yml b/environment_win.yml index a397726ee..7074b37c0 100644 --- a/environment_win.yml +++ b/environment_win.yml @@ -1,8 +1,8 @@ name: my-env channels: - - set3mah - conda-forge + - set3mah dependencies: - pkg-config @@ -16,7 +16,7 @@ dependencies: - gtest - pybind11 - armadillo >= 12.6 - - set3mah::carma + - carma - pytest - ninja - mkl From 00932faaef16856d81f5d4049ba736f8f235689b Mon Sep 17 00:00:00 2001 From: Kevin Marchais Date: Mon, 26 Jan 2026 15:36:51 +0100 Subject: [PATCH 09/12] Add Python 3.14 support --- conda.recipe/conda_build_config.yaml | 1 + pyproject.toml | 1 + 2 files changed, 2 insertions(+) diff --git a/conda.recipe/conda_build_config.yaml b/conda.recipe/conda_build_config.yaml index 9ad4bc7a3..8f30a6e0d 100755 --- a/conda.recipe/conda_build_config.yaml +++ b/conda.recipe/conda_build_config.yaml @@ -3,3 +3,4 @@ python: - 3.11 - 3.12 - 3.13 + - 3.14 diff --git a/pyproject.toml b/pyproject.toml index fc127051b..20defb5a3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -33,6 +33,7 @@ classifiers = [ "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", "Topic :: Scientific/Engineering", "Topic :: Scientific/Engineering :: Physics", "Topic :: Scientific/Engineering :: Mathematics", From 2a91706738b75391a29b2bdff7fde7ad4b4c2634 Mon Sep 17 00:00:00 2001 From: Kevin Marchais Date: Mon, 26 Jan 2026 15:42:41 +0100 Subject: [PATCH 10/12] Remove Python 3.14 from conda package build matrix libboost-python on conda-forge doesn't have Python 3.14 builds yet. Python 3.14 still works for pip install (CI uses pip). --- conda.recipe/conda_build_config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conda.recipe/conda_build_config.yaml b/conda.recipe/conda_build_config.yaml index 8f30a6e0d..47de4a59f 100755 --- a/conda.recipe/conda_build_config.yaml +++ b/conda.recipe/conda_build_config.yaml @@ -3,4 +3,4 @@ python: - 3.11 - 3.12 - 3.13 - - 3.14 + # Python 3.14 not supported yet: libboost-python lacks 3.14 builds on conda-forge From 056ee7da2a762489777ff816f7595865cffda867 Mon Sep 17 00:00:00 2001 From: Kevin Marchais Date: Mon, 26 Jan 2026 15:43:44 +0100 Subject: [PATCH 11/12] Remove boost dependency (no longer required) --- conda.recipe/meta.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/conda.recipe/meta.yaml b/conda.recipe/meta.yaml index 52505d8b6..785aa72c1 100755 --- a/conda.recipe/meta.yaml +++ b/conda.recipe/meta.yaml @@ -36,7 +36,6 @@ requirements: - numpy >=2.0 - libblas - liblapack - - boost >=1.84 run: - python - numpy >=2.0 @@ -47,7 +46,6 @@ requirements: - mkl # [x86] - blas * openblas # [not (osx and arm64) and not x86] - lapack * openblas # [not (osx and arm64) and not x86] - - boost >=1.84 - armadillo >=12.6 # [not win] test: From 44603f259328a7081992a5157eb388ce12308024 Mon Sep 17 00:00:00 2001 From: Kevin Marchais Date: Mon, 26 Jan 2026 15:44:14 +0100 Subject: [PATCH 12/12] Re-add Python 3.14 to conda build (boost removed) --- conda.recipe/conda_build_config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conda.recipe/conda_build_config.yaml b/conda.recipe/conda_build_config.yaml index 47de4a59f..8f30a6e0d 100755 --- a/conda.recipe/conda_build_config.yaml +++ b/conda.recipe/conda_build_config.yaml @@ -3,4 +3,4 @@ python: - 3.11 - 3.12 - 3.13 - # Python 3.14 not supported yet: libboost-python lacks 3.14 builds on conda-forge + - 3.14