diff --git a/.github/workflows/ci_tests_run_notebooks.yml b/.github/workflows/ci_tests_run_notebooks.yml new file mode 100644 index 0000000..5f106c6 --- /dev/null +++ b/.github/workflows/ci_tests_run_notebooks.yml @@ -0,0 +1,77 @@ +name: Test notebooks + +on: + push: + branches: + - main + pull_request: + branches: + - main + schedule: + - cron: '0 5 * * 1' + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + tests: + # Do not run the test matrix on PRs affecting the rendering + if: ${{ !(github.event_name == 'pull_request') || !contains(github.event.pull_request.labels.*.name, 'html rendering / skip testing') }} + + name: ${{ matrix.os }} ${{ matrix.name }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + # Run all supported OS for one Python version, then add a few extra scenarios + os: [ubuntu-latest, macos-latest, windows-latest] + python-version: ['3.12'] + toxenv: [py312-test] + name: ['with Python 3.12',] + + include: + - python-version: '3.10' + toxenv: py310-test-oldestdeps + name: with Python 3.10 and oldest versioned dependencies + os: ubuntu-latest + + - python-version: '3.13' + toxenv: py313-test-devdeps + name: with Python 3.13 and developer versioned dependencies + os: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + + - name: Install dependencies + run: python -m pip install --upgrade tox + + - name: Test with tox + run: tox ${{ matrix.toxargs }} -e ${{ matrix.toxenv }} -- ${{ matrix.toxposargs }} + + + gha_buildhtml: + # When label is used, we do run buildhtml on GHA to check if the publishing job will run or not. + # Use in case when new content has run into troubles on CircleCI. + if: ${{ (github.event_name == 'pull_request') && contains(github.event.pull_request.labels.*.name, 'GHA buildhtml') }} + name: Buildhtml testing + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: '3.11' + + - name: Install dependencies + run: python -m pip install --upgrade tox + + - name: Execute notebooks as testing + run: tox -e py311-buildhtml diff --git a/.gitignore b/.gitignore index 9d64d4f..6154ca0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,10 @@ _build/* .ipynb_checkpoints /.pixi/* +# Notebooks are stored in the text-based Markdown format. +# No .ipynb files should be stored in this repository. +*.ipynb + # We treat this repository as a library, not an application, and thus we do not # include the lockfile in source control. For a specific event, like a # workshop, we suggest committing the lockfile on a branch dedicated to the diff --git a/requirements.txt b/requirements.txt index df354a5..a1e6cc1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,3 +6,8 @@ ipympl sphinx-copybutton # For tutorials matplotlib +# for testing +pytest +nbval +pytest-custom_exit_code +jupytext diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000..81ee08a --- /dev/null +++ b/tox.ini @@ -0,0 +1,53 @@ +[tox] +envlist = + py{311, 312, 313}-test{,-oldestdeps,-devdeps,-predeps}{,-buildhtml} +requires = + pip >= 19.3.1 + +[testenv] + +description = run tests + +setenv = + devdeps: PIP_EXTRA_INDEX_URL = https://pypi.anaconda.org/scientific-python-nightly-wheels/simple + +passenv = CI, CIRCLECI, GITHUB_EVENT_NAME, GITHUB_EVENT_PATH + +deps = + # We use these files to specify all the dependencies, and below we override + # versions for specific testing schenarios + -rrequirements.txt + #-rsite_requirements.txt + #-r.binder/requirements.txt + + # Notebooks may set minimums for some dependencies, the others are set for a supported minimum + # following e.g. SPEC0 or some other considerations. + oldestdeps: numpy==1.24.0 + oldestdeps: matplotlib==3.7.0 + + # TODO: add pure python dependency, so we can add an example for the github install + devdeps: git+https://github.com/astropy/pyvo.git#egg=pyvo + +allowlist_externals = bash, sed + +commands = + pip freeze + + ## Some of the these could be factored out to a separate shell script, + ## but so far it's simple enought to keep it here. + + # We only want to run CI in PRs for the notebooks we touched + !buildhtml: bash -c 'if [[ $GITHUB_EVENT_NAME == pull_request && -z "$(grep force_run:all_tests ${GITHUB_EVENT_PATH})" ]]; then git fetch origin main --depth=1; git diff origin/main --name-only tutorials | grep .md; else find tutorials -name "*.md"; fi | grep -vf ignore_testing | xargs jupytext --to notebook ' + + !buildhtml: pytest --nbval-lax -vv --suppress-no-test-exit-code --durations=10 tutorials + + buildhtml: sphinx-build -b html . _build/html -nWT --keep-going + # SED magic to remove the toctree captions from the rendered index page while keeping them in the sidebar TOC + buildhtml: sed -E -i.bak '/caption-text/{N; s/.+caption-text.+\n