firecrown-ci #3550
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
| # CI Workflow Optimization Summary | |
| # ===================================== | |
| # This workflow is designed as a 3-stage pipeline to balance fast feedback | |
| # with comprehensive cross-platform validation. | |
| # | |
| # STAGE 1: QUICK VALIDATION (Parallel with Stage 2) | |
| # - Goal: 2-3 minute feedback on common PR issues. | |
| # - Actions: Linting, formatting, and Jupyter Notebook cleanliness checks. | |
| # - Optimization: Uses environment caching to minimize setup time. | |
| # | |
| # STAGE 2: FULL COMPATIBILITY MATRIX | |
| # - Goal: Verify Firecrown across all supported environments. | |
| # - Actions: Comprehensive unit and integration testing. | |
| # - Matrix: Covers OS (Linux/macOS) and Python versions defined in the job below. | |
| # - Optimization: Ubuntu + Python 3.12 performs coverage analysis. | |
| # | |
| # STAGE 3: DOWNSTREAM & DOCUMENTATION (Sequential - depends on Stage 2) | |
| # - Goal: Verify ecosystem integration and build stability. | |
| # - Actions: Tests with Smokescreen and Augur; full documentation verification. | |
| # - Optimization: Only runs if the main matrix succeeds to save resources. | |
| # | |
| # MAINTENANCE NOTE: | |
| # When updating supported Python versions, only the matrix configuration | |
| # in Stage 2 needs to be changed. This header is intentionally abstract. | |
| # | |
| # MacOS Note: | |
| # Stage 2 include a workaround for RPATH issues in 'isitgr' on macOS to | |
| # ensure libraries are correctly loaded during integration tests. | |
| name: firecrown-ci | |
| on: | |
| push: | |
| branches: | |
| - "master" | |
| paths-ignore: | |
| - "docs/**/*.md" | |
| - "*.md" | |
| pull_request: | |
| branches: | |
| - "*" | |
| paths-ignore: | |
| - "docs/**/*.md" | |
| - "*.md" | |
| schedule: | |
| - cron: "47 1 * * *" | |
| env: | |
| CONDA_ENV: firecrown_developer | |
| CACHE_VERSION: 15 | |
| jobs: | |
| quick-validation: | |
| name: Quick validation | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Setting up Miniforge | |
| uses: conda-incubator/setup-miniconda@v3 | |
| with: | |
| miniforge-version: latest | |
| python-version: "3.12" | |
| activate-environment: ${{ env.CONDA_ENV }} | |
| - name: Cache date | |
| id: get-date | |
| run: echo "today=$(/bin/date -u '+%Y%m%d')" >> $GITHUB_OUTPUT | |
| shell: bash | |
| - name: Compute environment.yml hash | |
| id: env-hash | |
| run: | | |
| if command -v sha256sum &>/dev/null 2>&1; then | |
| h=$(sha256sum environment.yml | cut -d' ' -f1) | |
| else | |
| h=$(shasum -a 256 environment.yml | cut -d' ' -f1) | |
| fi | |
| echo "env_hash=${h}" >> $GITHUB_OUTPUT | |
| shell: bash | |
| - name: Cache Conda env | |
| uses: actions/cache/restore@v4 | |
| id: cache | |
| with: | |
| path: ${{ env.CONDA }}/envs | |
| key: conda-Linux-X64-py3.12-${{ steps.get-date.outputs.today }}-${{ steps.env-hash.outputs.env_hash }}-v${{ env.CACHE_VERSION }} | |
| - name: Update environment | |
| if: steps.cache.outputs.cache-hit != 'true' | |
| run: | | |
| python .github/update_ci.py 3.12 | |
| conda env update -n ${{ env.CONDA_ENV }} -f env_tmp.yml --prune | |
| - name: Save conda environment | |
| if: steps.cache.outputs.cache-hit != 'true' | |
| uses: actions/cache/save@v4 | |
| with: | |
| path: ${{ env.CONDA }}/envs | |
| key: ${{ steps.cache.outputs.cache-primary-key }} | |
| - name: Quick setup and linting | |
| shell: bash -l {0} | |
| run: | | |
| pip install --no-deps -e . | |
| make lint | |
| - name: Ensure clear Jupyter Notebooks | |
| uses: ResearchSoftwareActions/EnsureCleanNotebooksAction@1.1 | |
| firecrown-miniforge: | |
| name: (${{ matrix.os }}, py${{ matrix.python-version }})${{ matrix.coverage && ' + coverage' || '' }} | |
| runs-on: ${{ matrix.os }}-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: ["ubuntu", "macos"] | |
| python-version: ["3.11", "3.12", "3.13", "3.14"] | |
| include: | |
| - os: ubuntu | |
| python-version: "3.12" | |
| coverage: true | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Setting up Miniforge | |
| uses: conda-incubator/setup-miniconda@v3 | |
| with: | |
| miniforge-version: latest | |
| python-version: ${{ matrix.python-version }} | |
| activate-environment: ${{ env.CONDA_ENV }} | |
| - name: Cache date | |
| id: get-date | |
| run: echo "today=$(/bin/date -u '+%Y%m%d')" >> $GITHUB_OUTPUT | |
| shell: bash | |
| - name: Compute environment.yml hash | |
| id: env-hash | |
| run: | | |
| if command -v sha256sum &>/dev/null 2>&1; then | |
| h=$(sha256sum environment.yml | cut -d' ' -f1) | |
| else | |
| h=$(shasum -a 256 environment.yml | cut -d' ' -f1) | |
| fi | |
| echo "env_hash=${h}" >> $GITHUB_OUTPUT | |
| shell: bash | |
| - name: Cache Conda env | |
| uses: actions/cache/restore@v4 | |
| id: cache | |
| with: | |
| path: ${{ env.CONDA }}/envs | |
| key: conda-${{ runner.os }}-${{ runner.arch }}-py${{ matrix.python-version }}-${{ steps.get-date.outputs.today }}-${{ steps.env-hash.outputs.env_hash }}-v${{ env.CACHE_VERSION }} | |
| - name: Update environment | |
| if: steps.cache.outputs.cache-hit != 'true' | |
| run: | | |
| python .github/update_ci.py ${{ matrix.python-version }} | |
| conda env update -n ${{ env.CONDA_ENV }} -f env_tmp.yml --prune | |
| - name: Setting up CosmoSIS and Cobaya | |
| if: steps.cache.outputs.cache-hit != 'true' | |
| shell: bash -l {0} | |
| run: | | |
| # Sequential setup of dependencies to avoid environment corruption | |
| source ${CONDA_PREFIX}/bin/cosmosis-configure | |
| pushd ${CONDA_PREFIX} | |
| cosmosis-build-standard-library | |
| export CSL_DIR=${PWD}/cosmosis-standard-library | |
| conda env config vars set CSL_DIR=${CSL_DIR} | |
| popd | |
| python -m pip install cobaya --no-deps | |
| - name: Remove redundant rpath and import isitgr | |
| if: ${{ (matrix.os == 'macos') && (steps.cache.outputs.cache-hit != 'true') }} | |
| shell: bash -l {0} | |
| run: | | |
| install_name_tool -delete_rpath /Users/runner/miniconda3/envs/firecrown_developer/lib /Users/runner/miniconda3/envs/firecrown_developer/lib/python3.1?/site-packages/isitgr/isitgrlib.so || true | |
| python -c "import isitgr" | |
| - name: Save conda-forge, CosmoSIS and Cobaya environment | |
| id: cache-primes-save | |
| uses: actions/cache/save@v4 | |
| with: | |
| path: ${{ env.CONDA }}/envs | |
| key: ${{ steps.cache.outputs.cache-primary-key }} | |
| - name: Setting up Firecrown | |
| shell: bash -l {0} | |
| run: | | |
| export FIRECROWN_DIR=${PWD} | |
| conda env config vars set FIRECROWN_DIR=${FIRECROWN_DIR} | |
| pip install --no-deps -e . | |
| conda list | |
| - name: Code quality checks | |
| shell: bash -l {0} | |
| run: make lint | |
| - name: Run CI tests | |
| shell: bash -l {0} | |
| run: | | |
| if [[ "${{ matrix.coverage || false }}" == "true" ]]; then | |
| make test-ci | |
| else | |
| make test-all | |
| fi | |
| - name: Upload coverage reports to Codecov | |
| if: ${{ matrix.coverage == true }} | |
| uses: codecov/codecov-action@v5 | |
| with: | |
| files: ./coverage.xml | |
| fail_ci_if_error: true | |
| verbose: true | |
| use_oidc: false | |
| # TODO: Remove the following two lines when GPG verification is fixed | |
| disable_search: true | |
| disable_file_fixes: true | |
| env: | |
| CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} | |
| # TODO: Remove when GPG key verification issue is resolved upstream | |
| CODECOV_SKIP_GPG_VERIFY: true | |
| external-dependencies: | |
| name: External dependencies and documentation | |
| needs: [firecrown-miniforge] | |
| runs-on: macos-latest | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Setting up Miniforge | |
| uses: conda-incubator/setup-miniconda@v3 | |
| with: | |
| miniforge-version: latest | |
| python-version: "3.13" | |
| activate-environment: ${{ env.CONDA_ENV }} | |
| - name: Cache date | |
| id: get-date | |
| run: echo "today=$(/bin/date -u '+%Y%m%d')" >> $GITHUB_OUTPUT | |
| shell: bash | |
| - name: Compute environment.yml hash | |
| id: env-hash | |
| run: | | |
| if command -v sha256sum &>/dev/null 2>&1; then | |
| h=$(sha256sum environment.yml | cut -d' ' -f1) | |
| else | |
| h=$(shasum -a 256 environment.yml | cut -d' ' -f1) | |
| fi | |
| echo "env_hash=${h}" >> $GITHUB_OUTPUT | |
| shell: bash | |
| - name: Cache Conda env | |
| uses: actions/cache/restore@v4 | |
| id: cache | |
| with: | |
| path: ${{ env.CONDA }}/envs | |
| key: conda-${{ runner.os }}-${{ runner.arch }}-py3.13-${{ steps.get-date.outputs.today }}-${{ steps.env-hash.outputs.env_hash }}-v${{ env.CACHE_VERSION }} | |
| - name: Update environment | |
| if: steps.cache.outputs.cache-hit != 'true' | |
| run: | | |
| python .github/update_ci.py 3.13 | |
| conda env update -n ${{ env.CONDA_ENV }} -f env_tmp.yml --prune | |
| - name: Remove redundant rpath and import isitgr | |
| shell: bash -l {0} | |
| run: | | |
| install_name_tool -delete_rpath /Users/runner/miniconda3/envs/firecrown_developer/lib /Users/runner/miniconda3/envs/firecrown_developer/lib/python3.1?/site-packages/isitgr/isitgrlib.so || true | |
| python -c "import isitgr" | |
| - name: Setting up CosmoSIS and Cobaya | |
| if: steps.cache.outputs.cache-hit != 'true' | |
| shell: bash -l {0} | |
| run: | | |
| # Sequential setup of dependencies to avoid environment corruption | |
| source ${CONDA_PREFIX}/bin/cosmosis-configure | |
| pushd ${CONDA_PREFIX} | |
| cosmosis-build-standard-library | |
| export CSL_DIR=${PWD}/cosmosis-standard-library | |
| conda env config vars set CSL_DIR=${CSL_DIR} | |
| popd | |
| python -m pip install cobaya --no-deps | |
| - name: Save conda-forge, CosmoSIS and Cobaya environment | |
| id: cache-primes-save | |
| uses: actions/cache/save@v4 | |
| with: | |
| path: ${{ env.CONDA }}/envs | |
| key: ${{ steps.cache.outputs.cache-primary-key }} | |
| - name: Create firecrown_developer environment | |
| shell: bash -l {0} | |
| run: | | |
| export FIRECROWN_DIR=${PWD} | |
| conda env config vars set FIRECROWN_DIR=${FIRECROWN_DIR} | |
| pip install --no-deps -e . | |
| conda list | |
| - name: Cloning Smokescreen | |
| uses: actions/checkout@v5 | |
| with: | |
| repository: "marcpaterno/smokescreen" | |
| path: "smokescreen" | |
| ref: "adjust-to-firecrown-pr-586" | |
| - name: Cloning Augur | |
| uses: actions/checkout@v5 | |
| with: | |
| repository: "lsstdesc/augur" | |
| path: "augur" | |
| ref: "b59cfaf3dec90aa606a4add453a5a77e0c8ea942" | |
| - name: Build and verify tutorials and documentation | |
| shell: bash -l {0} | |
| run: make docs-verify | |
| - name: Pip-install Augur and test it | |
| shell: bash -l {0} | |
| run: | | |
| conda install jinja2 tjpcov | |
| cd augur | |
| pip install -e . | |
| python -m pytest . | |
| - name: Pip-install Smokescreen and test it | |
| shell: bash -l {0} | |
| run: | | |
| cd smokescreen | |
| pip install -e . | |
| python -m pytest tests |