From daad68b43cbb581365e6780cf3fdbe2fafa41299 Mon Sep 17 00:00:00 2001 From: "Adam J. Jackson" Date: Fri, 20 Dec 2024 14:50:07 +0000 Subject: [PATCH] Separate release test workflows for PyPI and Conda-forge (#350) * These workflows are generally needed on different days so it is quite inconvenient having them so firmly tied together. (i.e. conda test always fails when testing the just-pushed PyPI release...) * This also allows us to simplify the infrastructure a bit. As tox 4 and conda don't play together very nicely, we use a conda-free tox setup for PyPI and a bigger conda-only test-matrix for conda-forge tests. Neither workflow is using stuff it doesn't need. * Leave test_release.yml as a double-launcher, this was useful while working on the branch as we can't workflow-dispatch the components until they hit master in some form. * Each release test pushes its own "check" report so we can now easily see that PyPI passes while Conda-forge fails. Co-authored-by: Jacob Wilkins <46597752+oerc0122@users.noreply.github.com> --- .github/workflows/test_release.yml | 88 +++-------------- .github/workflows/test_release_conda.yml | 69 ++++++++++++++ .github/workflows/test_release_pypi.yml | 95 +++++++++++++++++++ .../conda_release_test_requirements.yml | 12 +++ .../{release_tox.ini => pypi_release_tox.ini} | 42 +------- 5 files changed, 191 insertions(+), 115 deletions(-) create mode 100644 .github/workflows/test_release_conda.yml create mode 100644 .github/workflows/test_release_pypi.yml create mode 100644 build_utils/conda_release_test_requirements.yml rename build_utils/{release_tox.ini => pypi_release_tox.ini} (57%) diff --git a/.github/workflows/test_release.yml b/.github/workflows/test_release.yml index ee61504eb..f1387cdd9 100644 --- a/.github/workflows/test_release.yml +++ b/.github/workflows/test_release.yml @@ -1,86 +1,20 @@ -name: test-release +name: Run release tests from PyPI and Conda-forge + on: workflow_dispatch: inputs: version: description: 'The Euphonic release version to test e.g. 0.6.1' required: true + type: string jobs: - test: - strategy: - matrix: - os: [ubuntu-latest, windows-latest, macos-latest, macos-13] - fail-fast: false - runs-on: ${{ matrix.os }} - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 # Ensure tags are fetched for versioning - - uses: actions/setup-python@v5 - with: - python-version: | - 3.10 - 3.11 - 3.12 - - name: Install llvm on MacOS - if: startsWith(matrix.os, 'macos') - shell: bash -l {0} - env: - # Homebrew location is different on Intel Mac - LLVM_DIR: ${{ (matrix.os == 'macos-13') && '/usr/local/opt/llvm' || '/opt/homebrew/opt/llvm' }} - run: | - brew install llvm - echo CC="${LLVM_DIR}/bin/clang" >> $GITHUB_ENV - echo LDFLAGS="-L${LLVM_DIR}/lib $LDFLAGS" >> $GITHUB_ENV - echo CPPFLAGS="-I${LLVM_DIR}/include $CPPFLAGS" >> $GITHUB_ENV - - - name: Windows - find MSVC and set environment variables - if: startsWith(matrix.os, 'windows') - shell: bash -l {0} - env: - MSVC_PREFIX: 'C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC' - run: | - echo "Available MSVC installations:" - ls "$MSVC_PREFIX" - - MSVC_BIN=$(ls "$MSVC_PREFIX" | tail -n 1)\\bin\\HostX64\\x64 - CC="$MSVC_PREFIX\\$MSVC_BIN\\cl.exe" - echo "CC: $CC" - echo "CC=$CC" >> $GITHUB_ENV - - CC_LD="$MSVC_PREFIX\\$MSVC_BIN\\link.exe" - echo "CC_LD: $CC_LD" - echo "CC_LD=$CC_LD" >> $GITHUB_ENV - - - name: Update pip and install dependencies - shell: bash -l {0} - run: | - python -m pip install --upgrade pip - python -m pip install -r tests_and_analysis/ci_requirements.txt - - - name: Run tests - shell: bash -l {0} - env: - EUPHONIC_VERSION: ${{ github.event.inputs.version }} - run: python -m tox -c build_utils/release_tox.ini - - name: Upload test results - if: always() - uses: actions/upload-artifact@v4 - with: - name: Unit test results ${{ matrix.os }} - path: tests_and_analysis/test/reports/junit_report*.xml + pypi: + uses: ./.github/workflows/test_release_pypi.yml + with: + version: ${{ inputs.version }} - publish-test-results: - needs: test - runs-on: ubuntu-latest - if: success() || failure() - steps: - - name: Download Artifacts - uses: actions/download-artifact@v4 - with: - path: artifacts - - name: Publish test results - uses: EnricoMi/publish-unit-test-result-action@v2 - with: - junit_files: artifacts/**/junit_report*.xml + conda-forge: + uses: ./.github/workflows/test_release_conda.yml + with: + version: ${{ inputs.version }} diff --git a/.github/workflows/test_release_conda.yml b/.github/workflows/test_release_conda.yml new file mode 100644 index 000000000..43a063be8 --- /dev/null +++ b/.github/workflows/test_release_conda.yml @@ -0,0 +1,69 @@ +name: Test Conda-forge release +on: + workflow_call: + inputs: + version: + description: 'The Euphonic release version to test e.g. 0.6.1' + required: true + type: string + + workflow_dispatch: + inputs: + version: + description: 'The Euphonic release version to test e.g. 0.6.1' + required: true + type: string + +jobs: + test: + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, windows-latest, macos-latest, macos-13] + python-version: ['3.10', '3.11', '3.12'] + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v4 + + - name: Delete source (to be sure we are testing Conda package!) + shell: bash -el {0} + run: rm -r euphonic + + - uses: conda-incubator/setup-miniconda@v3 + with: + python-version: ${{ matrix.python-version }} + + - name: Install euphonic and dependencies from Conda-forge + shell: bash -el {0} + env: + EUPHONIC_VERSION: ${{ inputs.version }} + + run: | + conda env update --file build_utils/conda_release_test_requirements.yml + conda install -c conda-forge euphonic=$EUPHONIC_VERSION + + - name: Run tests + shell: bash -el {0} + run: python tests_and_analysis/test/run_tests.py --report -m "not brille" + + - name: Upload test results + if: always() + uses: actions/upload-artifact@v4 + with: + name: Conda-forge unit test results ${{ matrix.os }} ${{ matrix.python-version }} + path: tests_and_analysis/test/reports/junit_report*.xml + + publish-conda-test-results: + needs: test + runs-on: ubuntu-latest + if: success() || failure() + steps: + - name: Download Artifacts + uses: actions/download-artifact@v4 + with: + path: artifacts + - name: Publish Conda test results + uses: EnricoMi/publish-unit-test-result-action@v2 + with: + junit_files: artifacts/Conda***/junit_report*.xml + check_name: Conda-forge test results diff --git a/.github/workflows/test_release_pypi.yml b/.github/workflows/test_release_pypi.yml new file mode 100644 index 000000000..a2a2aa39c --- /dev/null +++ b/.github/workflows/test_release_pypi.yml @@ -0,0 +1,95 @@ +name: Test PyPI release +on: + workflow_call: + inputs: + version: + description: 'The Euphonic release version to test e.g. 0.6.1' + required: true + type: string + + workflow_dispatch: + inputs: + version: + description: 'The Euphonic release version to test e.g. 0.6.1' + required: true + type: string + +jobs: + test: + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, windows-latest, macos-latest, macos-13] + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 # Ensure tags are fetched for versioning + - uses: actions/setup-python@v5 + with: + python-version: | + 3.10 + 3.11 + 3.12 + - name: Install llvm on MacOS + if: startsWith(matrix.os, 'macos') + shell: bash -l {0} + env: + # Homebrew location is different on Intel Mac + LLVM_DIR: ${{ (matrix.os == 'macos-13') && '/usr/local/opt/llvm' || '/opt/homebrew/opt/llvm' }} + run: | + brew install llvm + echo CC="${LLVM_DIR}/bin/clang" >> $GITHUB_ENV + echo LDFLAGS="-L${LLVM_DIR}/lib $LDFLAGS" >> $GITHUB_ENV + echo CPPFLAGS="-I${LLVM_DIR}/include $CPPFLAGS" >> $GITHUB_ENV + + - name: Windows - find MSVC and set environment variables + if: startsWith(matrix.os, 'windows') + shell: bash -l {0} + env: + MSVC_PREFIX: 'C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC' + run: | + echo "Available MSVC installations:" + ls "$MSVC_PREFIX" + + MSVC_BIN=$(ls "$MSVC_PREFIX" | tail -n 1)\\bin\\HostX64\\x64 + CC="$MSVC_PREFIX\\$MSVC_BIN\\cl.exe" + echo "CC: $CC" + echo "CC=$CC" >> $GITHUB_ENV + + CC_LD="$MSVC_PREFIX\\$MSVC_BIN\\link.exe" + echo "CC_LD: $CC_LD" + echo "CC_LD=$CC_LD" >> $GITHUB_ENV + + - name: Update pip and install dependencies + shell: bash -l {0} + run: | + python -m pip install --upgrade pip + python -m pip install -r tests_and_analysis/ci_requirements.txt + + - name: Run tests + shell: bash -l {0} + env: + EUPHONIC_VERSION: ${{ github.event.inputs.version }} + run: python -m tox -c build_utils/pypi_release_tox.ini + - name: Upload test results + if: always() + uses: actions/upload-artifact@v4 + with: + name: PyPI unit test results ${{ matrix.os }} + path: tests_and_analysis/test/reports/junit_report*.xml + + publish-pypi-test-results: + needs: test + runs-on: ubuntu-latest + if: success() || failure() + steps: + - name: Download Artifacts + uses: actions/download-artifact@v4 + with: + path: artifacts + - name: Publish PyPI test results + uses: EnricoMi/publish-unit-test-result-action@v2 + with: + junit_files: artifacts/PyPI**/junit_report*.xml + check_name: PyPI test results diff --git a/build_utils/conda_release_test_requirements.yml b/build_utils/conda_release_test_requirements.yml new file mode 100644 index 000000000..4b1da9bb3 --- /dev/null +++ b/build_utils/conda_release_test_requirements.yml @@ -0,0 +1,12 @@ +channels: + - conda-forge +dependencies: + - pytest=7.* + - coverage + - pytest-mock + - pytest-lazy-fixture + - pytest-xvfb + - python-slugify + - matplotlib-base + - pyyaml + - h5py diff --git a/build_utils/release_tox.ini b/build_utils/pypi_release_tox.ini similarity index 57% rename from build_utils/release_tox.ini rename to build_utils/pypi_release_tox.ini index 0ed260e2b..8b340edf1 100644 --- a/build_utils/release_tox.ini +++ b/build_utils/pypi_release_tox.ini @@ -2,7 +2,7 @@ # Use conda to set up the python environments to run in requires = tox>=4 # The python environments to run the tests in -envlist = pypi-py310-min,conda-py310-old-np,{pypi,conda}-{py310,py311,py312},pypisource-{py310,py312} +envlist = py310-min,py310,py311,py312,source-{py310,py312} skip_install = True [testenv] @@ -16,7 +16,7 @@ passenv = extras_str = [test,matplotlib,phonopy-reader,brille] # Test PyPI source distribution -[testenv:pypisource-{py310,py312}] +[testenv:source-{py310,py312}] passenv = CC CC_LD @@ -29,7 +29,7 @@ commands_pre = --no-binary 'euphonic' commands = {[testenv]test_command} -[testenv:pypi-{py310,py311,py312}] +[testenv:{py310,py311,py312}] commands_pre = python -m pip install \ --force-reinstall \ @@ -37,7 +37,7 @@ commands_pre = --only-binary 'euphonic' commands = {[testenv]test_command} -[testenv:pypi-py310-min] +[testenv:py310-min] platform = (linux)|(win32) deps = numpy==1.24 @@ -49,37 +49,3 @@ commands_pre = euphonic{[testenv]extras_str}=={env:EUPHONIC_VERSION} \ --only-binary 'euphonic' commands = {[testenv]test_command} - -[testenv:conda-{py310,py311,py312}] -whitelist_externals = conda -install_command = conda install {packages} -conda_channels = - conda-forge - default -extras = - test - matplotlib - phonopy-reader - -commands_pre = - conda install -c conda-forge euphonic={env:EUPHONIC_VERSION} -# Brille not available on conda -commands = {[testenv]test_command} -m "not brille" - -# Test against a version of Numpy less than the latest for Conda -# See https://github.com/conda-forge/euphonic-feedstock/pull/20 -[testenv:conda-py310-old-np] -whitelist_externals = conda -install_command = conda install {packages} -conda_channels = - conda-forge - default -deps = numpy==1.24 -extras = - test - matplotlib - phonopy-reader -commands_pre = - conda install -c conda-forge euphonic={env:EUPHONIC_VERSION} -# Brille not available on conda -commands = {[testenv]test_command} -m "not brille"