Update development setup and CI workflows #209
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Tests | |
on: | |
push: | |
branches: [ main ] | |
pull_request: | |
branches: [ main ] | |
merge_group: | |
schedule: | |
# Run tests daily at 8:24 AM UTC to catch regressions | |
- cron: '24 08 * * *' | |
concurrency: | |
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }} | |
cancel-in-progress: true | |
jobs: | |
# detect whether any code changes are included in this PR | |
changes: | |
runs-on: ubuntu-latest | |
permissions: | |
contents: read | |
pull-requests: read | |
outputs: | |
code: ${{ steps.filter.outputs.code }} | |
steps: | |
- name: Checkout Source | |
uses: actions/checkout@v4 | |
if: github.event_name != 'pull_request' | |
- name: Filter Changes | |
uses: dorny/paths-filter@v3 | |
id: filter | |
with: | |
filters: | | |
code: | |
- 'conda_self/**' | |
- 'tests/**' | |
- '*.py' | |
- 'environment-*.yml' | |
- 'recipe/**' | |
- '.github/workflows/tests.yml' | |
test: | |
name: Test (Python ${{ matrix.python-version }}, Conda ${{ matrix.conda-version }}, ${{ matrix.channel }}) | |
# only run test suite if there are code changes or it's a scheduled run | |
needs: changes | |
if: github.event_name == 'schedule' || needs.changes.outputs.code == 'true' | |
runs-on: ${{ matrix.os }} | |
env: | |
CONDA_PKGS_DIR: ${{ matrix.os == 'windows-latest' && 'D:\conda_pkgs_dir' || '~/conda_pkgs_dir' }} | |
CONDA_INSTALL_DIR: ${{ matrix.os == 'windows-latest' && 'D:\conda' || '' }} | |
strategy: | |
fail-fast: false | |
matrix: | |
os: [ubuntu-latest, windows-latest, macos-latest] | |
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] | |
conda-version: ["24.11", "25.1", "25.3", "25.5", "25.7"] | |
channel: ["conda-forge", "defaults"] | |
exclude: | |
# Windows: only test lowest and highest Python versions | |
- os: windows-latest | |
python-version: "3.10" | |
- os: windows-latest | |
python-version: "3.11" | |
- os: windows-latest | |
python-version: "3.12" | |
# macOS: reduce matrix for faster CI | |
- os: macos-latest | |
python-version: "3.10" | |
- os: macos-latest | |
python-version: "3.11" | |
- os: macos-latest | |
python-version: "3.12" | |
# Older conda versions may not support Python 3.13 | |
- conda-version: "24.11" | |
python-version: "3.13" | |
- conda-version: "25.1" | |
python-version: "3.13" | |
# Older conda versions: only test with conda-forge | |
- conda-version: "24.11" | |
channel: "defaults" | |
- conda-version: "25.1" | |
channel: "defaults" | |
defaults: | |
run: | |
shell: bash -el {0} | |
steps: | |
- name: Checkout code | |
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
with: | |
fetch-depth: 0 | |
- name: Hash + Timestamp | |
run: echo "HASH=${{ runner.os }}-${{ runner.arch }}-Py${{ matrix.python-version }}-$(date -u "+%Y%m")" >> $GITHUB_ENV | |
- name: Cache Conda | |
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 | |
with: | |
enableCrossOsArchive: true | |
path: ${{ env.CONDA_PKGS_DIR }} | |
key: cache-${{ env.HASH }} | |
- name: Setup Miniconda | |
uses: conda-incubator/setup-miniconda@835234971496cad1653abb28a638a281cf32541f # v3.2.0 | |
with: | |
run-post: false # skip post cleanup | |
# conda not preinstalled in arm64 runners | |
miniconda-version: ${{ runner.arch == 'ARM64' && 'latest' || null }} | |
architecture: ${{ runner.arch }} | |
channels: ${{ matrix.channel }} | |
pkgs-dirs: ${{ env.CONDA_PKGS_DIR }} | |
installation-dir: ${{ env.CONDA_INSTALL_DIR }} | |
- name: Install conda-self dependencies | |
run: > | |
conda install | |
--channel ${{ matrix.channel }} | |
--override-channels | |
python=${{ matrix.python-version }} | |
${{ matrix.conda-version != 'latest' && format('conda={0}', matrix.conda-version) || ''}} | |
pip | |
pytest | |
pytest-mock | |
pytest-cov | |
pre-commit | |
- name: Install self | |
run: pip install -e . | |
- name: Conda Info | |
# view test env info (not base) | |
run: python -m conda info --verbose | |
- name: Conda Config | |
run: conda config --show-sources | |
- name: Conda List | |
run: conda list --show-channel-urls | |
- name: Test conda-self plugin registration | |
run: python -m conda self --help | |
- name: Run tests | |
# Windows is sensitive to long paths, using `--basetemp=${{ runner.temp }} to | |
# keep the test directories shorter | |
run: > | |
pytest | |
-xvs | |
--cov=conda_self | |
--cov-report=xml | |
--basetemp=${{ runner.temp }} | |
-n auto | |
tests/ | |
- name: Upload coverage to Codecov | |
uses: codecov/codecov-action@v4 | |
with: | |
file: ./coverage.xml | |
fail_ci_if_error: false | |
lint: | |
name: Lint | |
needs: changes | |
if: github.event_name == 'schedule' || needs.changes.outputs.code == 'true' | |
runs-on: ubuntu-latest | |
steps: | |
- name: Checkout code | |
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
- name: Setup Miniconda | |
uses: conda-incubator/setup-miniconda@835234971496cad1653abb28a638a281cf32541f # v3.2.0 | |
with: | |
# conda not preinstalled in arm64 runners | |
miniconda-version: ${{ runner.arch == 'ARM64' && 'latest' || null }} | |
architecture: ${{ runner.arch }} | |
python-version: "3.10" | |
conda-version: "25.7" | |
channels: conda-forge | |
- name: Install linting dependencies | |
run: > | |
conda install | |
--channel conda-forge | |
--override-channels | |
python=3.10 | |
conda=25.7 | |
pre-commit | |
shell: bash -l {0} | |
- name: Run pip | |
run: pip install -e . | |
shell: bash -l {0} | |
- name: Run pre-commit | |
run: pre-commit run --all-files | |
shell: bash -l {0} | |
# required check | |
analyze: | |
needs: [test, lint] | |
if: '!cancelled()' | |
runs-on: ubuntu-latest | |
steps: | |
- name: Determine Success | |
uses: re-actors/alls-green@05ac9388f0aebcb5727afa17fcccfecd6f8ec5fe # v1.2.2 | |
with: | |
# permit jobs to be skipped if there are no code changes | |
allowed-skips: ${{ toJSON(needs) }} | |
jobs: ${{ toJSON(needs) }} |