Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[question] What is the correct way to use hatch with github actions? #669

Closed
EdAyers opened this issue Dec 14, 2022 · 6 comments
Closed

Comments

@EdAyers
Copy link

EdAyers commented Dec 14, 2022

I've moved my builds to hatch. It's really nice.
Currently I have a github actions workflow that looks like

name: Client Python Package

on:
  push:
    branches: ["main"]
  pull_request:
    branches: ["main"]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Install Hatch
        run: pipx install hatch
      - name: Run tests
        run: hatch run test:test
      - name: Build dist
        run: hatch build
      - name: Publish on PyPI
        if: github.ref == 'refs/heads/main'
        run: hatch publish

which works great!

However there are a few issues that I'm having some trouble figuring out.

  • Downloading the dependencies can take a while. Is there a way of enabling dependency caching? I couldn't figure out where hatch was caching dependencies.
  • I have a test matrix for all the different versions of python, but I get Skipped 2 incompatible environments: test.py38 -> cannot locate Python: 38 test.py39 -> cannot locate Python: 39. What steps can I have to make sure these are available?

Any pointers on how to solve these would be much appreciated. Thanks.

@ischaojie
Copy link
Contributor

I have a test matrix for all the different versions of python, but I get Skipped 2 incompatible environments: test.py38 -> cannot locate Python: 38 test.py39 -> cannot locate Python: 39. What steps can I have to make sure these are available?

Maybe should setup python first use https://github.com/actions/setup-python? (not sure)

jobs:
  ci:
    strategy:
      matrix:
        python-version: ["3.8", "3.9", "3.10", "3.11"]
    name: "Python ${{ matrix.python-version }}"
    runs-on: "ubuntu-latest"
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-python@v4
        with:
          python-version: ${{ matrix.python-version }}

@EdAyers
Copy link
Author

EdAyers commented Dec 17, 2022

The suggestion above doesn't quite work, because for each iteration of the matrix it would run the tests on both 3.10 and whatever matrix version was selected. I found that calling setup-python multiple times with different versions worked:

      - uses: actions/setup-python@v4
        with:
          python-version: "3.8"
      - uses: actions/setup-python@v4
        with:
          python-version: "3.9"
      - uses: actions/setup-python@v4
        with:
          python-version: "3.10"

Then on the test phase with hatch test it runs hatch's environment matrix of different versions. I still haven't figured out the caching issue. Adding cache: pip to setup-python doesn't seem to improve loading times, maybe I'm missing something.

For reference, I have this env matrix in my pyproject.toml

[[tool.hatch.envs.test.matrix]]
python = ["38", "39", "310"]

@ofek
Copy link
Collaborator

ofek commented Dec 27, 2022

@br3ndonland
Copy link

Caching

actions/setup-python@v4 has some caching capabilities built in, but they aren't optimized for pyproject.toml yet (actions/setup-python#529). I'd recommend sticking with actions/cache to set up caching before installing dependencies. Hatch uses pip, and the actions/cache docs have some examples that will work for pip. Cache paths will vary by OS, so you may want to include some if: conditions to set the path appropriate for each OS.

- name: Set up pip cache
  if: runner.os == 'Linux'
  uses: actions/cache@v3
  with:
    path: ~/.cache/pip
    key: ${{ runner.os }}-pip-${{ hashFiles('pyproject.toml') }}
    restore-keys: ${{ runner.os }}-pip-

Matrices

The primary decision point with matrices is whether you want to implement them with GitHub Actions or Hatch.

GitHub Actions matrices are defined through the strategy key in each job.

name: ...

on: ...

jobs:
  job-name:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: ["3.9", "3.10", "3.11"]
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-python@v4
        with:
          python-version: ${{ matrix.python-version }}

Hatch matrices are defined in pyproject.toml. Note that Hatch doesn't automatically install Python executables (#645), so each version of Python needs to be installed on the machine ahead of time. actions/setup-python@v4.4.0 made it easier to install multiple versions of Python to use with Hatch matrices:

name: ...

on: ...

jobs:
  job-name:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-python@v4
        with:
          python-version: |
            3.9
            3.10
            3.11

One potential drawback of Hatch matrices is that, AFAIK, Hatch matrices can only run sequentially, whereas GitHub Actions matrices can run in parallel. If you have a small test suite that only takes a few seconds to run, sequential execution isn't much of a problem. For larger test suites, running sequentially can substantially slow down CI jobs.

Examples

Based on the original post, an example with caching and GitHub Actions matrices could look like this:

name: Client Python Package

on:
  push:
    branches: ["main"]
  pull_request:
    branches: ["main"]

jobs:
  build:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: ["3.9", "3.10", "3.11"]
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-python@v4
        with:
          python-version: ${{ matrix.python-version }}
      - name: Set up pip cache
        if: runner.os == 'Linux'
        uses: actions/cache@v3
        with:
          path: ~/.cache/pip
          key: ${{ runner.os }}-pip-${{ hashFiles('pyproject.toml') }}
          restore-keys: ${{ runner.os }}-pip-
      - name: Install Hatch
        run: pipx install hatch
      - name: Run tests
        run: hatch run test:test
      - name: Build dist
        run: hatch build
      - name: Publish on PyPI
        if: github.ref == 'refs/heads/main'
        run: hatch publish

An example with caching and Hatch matrices (assuming matrices are defined in the pyproject.toml as described in the Hatch docs) could look like this:

name: Client Python Package

on:
  push:
    branches: ["main"]
  pull_request:
    branches: ["main"]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-python@v4
        with:
          python-version: |
            3.9
            3.10
            3.11
      - name: Set up pip cache
        if: runner.os == 'Linux'
        uses: actions/cache@v3
        with:
          path: ~/.cache/pip
          key: ${{ runner.os }}-pip-${{ hashFiles('pyproject.toml') }}
          restore-keys: ${{ runner.os }}-pip-
      - name: Install Hatch
        run: pipx install hatch
      - name: Run tests
        run: hatch run test:test
      - name: Build dist
        run: hatch build
      - name: Publish on PyPI
        if: github.ref == 'refs/heads/main'
        run: hatch publish

EdAyers added a commit to hitsave-io/xyz that referenced this issue Jan 4, 2023
@EdAyers
Copy link
Author

EdAyers commented Jan 4, 2023

Hi great this is all working! I've gone the hatch-matrix route. The caching is also working.

@EdAyers EdAyers closed this as completed Jan 4, 2023
@ischaojie
Copy link
Contributor

If you using matrix in hatch envs, you can using +py flag to point special python version, for example:

name: "CI"

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  run:
    name: "tests & coverage"
    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"]

    steps:
    - uses: actions/checkout@v3
    - name: Set up Python ${{ matrix.python-version }}
      uses: actions/setup-python@v4
      with:
        python-version: ${{ matrix.python-version }}

    - name: Install hatch
      run: |
        python -m pip install hatch

    - name: Lint
      run: hatch run check

    - name: Tests
      run: hatch run +py=${{ matrix.python-version }} test:test

Hatch config:

[[tool.hatch.envs.test.matrix]]
python = ["3.7", "3.8", "3.9", "3.10", "3.11"]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants