Skip to content

Commit 5d1b188

Browse files
committed
ci/tests: modernize based on poetry
1 parent cc9df18 commit 5d1b188

5 files changed

Lines changed: 186 additions & 150 deletions

File tree

.github/actions/bootstrap-poetry/action.yaml

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,7 @@ runs:
3535
allow-prereleases: ${{ inputs.python-prereleases == 'true' }}
3636
update-environment: false
3737

38-
- run: >
39-
pipx install \
40-
${{ inputs.python-version != 'default' && format('--python "{0}"', steps.setup-python.outputs.python-path) || '' }} \
41-
'${{ inputs.poetry-spec }}'
38+
- run: pipx install ${{ inputs.python-version != 'default' && format('--python "{0}"', steps.setup-python.outputs.python-path) || '' }} '${{ inputs.poetry-spec }}'
4239
shell: bash
4340

4441
# Enable handling long path names (+260 char) on the Windows platform

.github/actions/poetry-install/action.yaml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,6 @@ outputs:
1616
description: Whether an exact cache hit occured
1717
value: ${{ steps.cache.outputs.cache-hit }}
1818

19-
defaults:
20-
run:
21-
working-directory: ${{ inputs.path }}
22-
2319
runs:
2420
using: composite
2521
steps:
@@ -48,10 +44,13 @@ runs:
4844
enableCrossOsArchive: true
4945

5046
- run: poetry install ${{ inputs.args }}
47+
working-directory: ${{ inputs.path }}
5148
shell: bash
5249

5350
- run: poetry env info
51+
working-directory: ${{ inputs.path }}
5452
shell: bash
5553

5654
- run: poetry show
55+
working-directory: ${{ inputs.path }}
5756
shell: bash
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# Reusable workflow consumed by tests.yaml; used to share a single matrix across jobs.
2+
on:
3+
workflow_call:
4+
inputs:
5+
runner:
6+
required: true
7+
type: string
8+
python-version:
9+
required: true
10+
type: string
11+
run-mypy:
12+
required: true
13+
type: boolean
14+
run-pytest:
15+
required: true
16+
type: boolean
17+
run-pytest-poetry:
18+
required: true
19+
type: boolean
20+
21+
defaults:
22+
run:
23+
shell: bash
24+
25+
jobs:
26+
mypy:
27+
name: mypy
28+
runs-on: ${{ inputs.runner }}
29+
if: inputs.run-mypy
30+
steps:
31+
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
32+
33+
- uses: ./.github/actions/bootstrap-poetry
34+
id: bootstrap-poetry
35+
with:
36+
python-version: ${{ inputs.python-version }}
37+
38+
- uses: ./.github/actions/poetry-install
39+
40+
- uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4
41+
with:
42+
path: .mypy_cache
43+
key: mypy-${{ runner.os }}-py${{ steps.bootstrap-poetry.outputs.python-version }}-${{ hashFiles('pyproject.toml', 'poetry.lock') }}
44+
restore-keys: |
45+
mypy-${{ runner.os }}-py${{ steps.bootstrap-poetry.outputs.python-version }}-
46+
mypy-${{ runner.os }}-
47+
48+
- run: poetry run mypy
49+
50+
pytest:
51+
name: pytest
52+
runs-on: ${{ inputs.runner }}
53+
if: inputs.run-pytest
54+
steps:
55+
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
56+
57+
- uses: ./.github/actions/bootstrap-poetry
58+
with:
59+
python-version: ${{ inputs.python-version }}
60+
61+
- uses: ./.github/actions/poetry-install
62+
with:
63+
args: --with github-actions
64+
65+
- run: poetry run pytest --integration -v
66+
67+
- run: git diff --exit-code --stat HEAD
68+
69+
pytest-poetry:
70+
name: pytest (Poetry)
71+
runs-on: ${{ inputs.runner }}
72+
if: inputs.run-pytest-poetry
73+
steps:
74+
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
75+
with:
76+
path: poetry-core
77+
78+
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
79+
with:
80+
path: poetry
81+
repository: python-poetry/poetry
82+
83+
- uses: ./poetry-core/.github/actions/bootstrap-poetry
84+
with:
85+
python-version: ${{ inputs.python-version }}
86+
87+
- uses: ./poetry-core/.github/actions/poetry-install
88+
with:
89+
path: ./poetry
90+
91+
- run: poetry add ../poetry-core
92+
working-directory: ./poetry
93+
94+
- run: poetry run pytest -v
95+
working-directory: ./poetry

.github/workflows/downstream.yaml

Lines changed: 0 additions & 76 deletions
This file was deleted.

.github/workflows/tests.yaml

Lines changed: 87 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,81 +1,102 @@
11
name: Tests
22

33
on:
4-
pull_request: {}
4+
merge_group:
5+
pull_request:
56
push:
6-
branches: [main]
7+
8+
concurrency:
9+
group: ${{ github.workflow }}-${{ github.ref }}
10+
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
11+
12+
defaults:
13+
run:
14+
shell: bash
715

816
env:
917
PYTHONWARNDEFAULTENCODING: 'true'
1018

1119
jobs:
12-
tests:
13-
name: ${{ matrix.os }} / ${{ matrix.python-version }}
14-
runs-on: "${{ matrix.os }}-latest"
20+
changes:
21+
name: Detect changed files
22+
runs-on: ubuntu-latest
23+
outputs:
24+
project: ${{ steps.changes.outputs.project }}
25+
src: ${{ steps.changes.outputs.src }}
26+
tests: ${{ steps.changes.outputs.tests }}
27+
steps:
28+
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
29+
30+
- uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3
31+
id: changes
32+
with:
33+
filters: |
34+
workflow: &workflow
35+
- '.github/actions/**'
36+
- '.github/workflows/tests.yaml'
37+
- '.github/workflows/.tests-matrix.yaml'
38+
project: &project
39+
- *workflow
40+
- 'poetry.lock'
41+
- 'pyproject.toml'
42+
src:
43+
- *project
44+
- 'src/**/*.py'
45+
tests:
46+
- *project
47+
- 'src/**/*.py'
48+
- 'tests/**'
49+
50+
lockfile:
51+
name: Check poetry.lock
52+
runs-on: ubuntu-latest
53+
if: needs.changes.outputs.project == 'true'
54+
needs: changes
55+
steps:
56+
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
57+
58+
- uses: ./.github/actions/bootstrap-poetry
59+
60+
- run: poetry check --lock
61+
62+
tests-matrix:
63+
# Use this matrix with multiple jobs defined in a reusable workflow:
64+
uses: ./.github/workflows/.tests-matrix.yaml
65+
name: ${{ matrix.os.name }} (Python ${{ matrix.python-version }})
66+
if: '!failure() && !cancelled()'
67+
needs:
68+
- lockfile
69+
- changes
70+
with:
71+
runner: ${{ matrix.os.image }}
72+
python-version: ${{ matrix.python-version }}
73+
run-mypy: ${{ needs.changes.outputs.src == 'true' }}
74+
run-pytest: ${{ needs.changes.outputs.tests == 'true' }}
75+
run-pytest-poetry: ${{ needs.changes.outputs.src == 'true' }}
76+
secrets: inherit
1577
strategy:
1678
matrix:
17-
os: [Ubuntu, MacOS, Windows]
79+
os:
80+
- name: Ubuntu
81+
image: ubuntu-22.04
82+
- name: macOS
83+
image: macos-13
84+
- name: Windows
85+
image: windows-2022
1886
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
1987
include:
20-
- os: Ubuntu
21-
python-version: pypy-3.8
88+
- os: {name: Ubuntu, image: ubuntu-22.04}
89+
python-version: pypy3.9
90+
- os: {name: Ubuntu, image: ubuntu-22.04}
91+
python-version: pypy3.10
2292
fail-fast: false
23-
defaults:
24-
run:
25-
shell: bash
26-
steps:
27-
- uses: actions/checkout@v4
28-
29-
- name: Set up Python ${{ matrix.python-version }}
30-
uses: actions/setup-python@v5
31-
with:
32-
python-version: ${{ matrix.python-version }}
33-
34-
- name: Get full Python version
35-
id: full-python-version
36-
run: echo version=$(python -c "import sys; print('-'.join(str(v) for v in sys.version_info))") >> $GITHUB_OUTPUT
37-
38-
- name: Bootstrap poetry
39-
run: |
40-
curl -sSL https://install.python-poetry.org | python - -y
4193

42-
- name: Update PATH
43-
if: ${{ matrix.os != 'Windows' }}
44-
run: echo "$HOME/.local/bin" >> $GITHUB_PATH
45-
46-
- name: Update Path for Windows
47-
if: ${{ matrix.os == 'Windows' }}
48-
run: echo "$APPDATA\Python\Scripts" >> $GITHUB_PATH
49-
50-
- name: Configure poetry
51-
run: poetry config virtualenvs.in-project true
52-
53-
- name: Set up cache
54-
uses: actions/cache@v4
55-
id: cache
56-
with:
57-
path: .venv
58-
key: venv-${{ runner.os }}-${{ steps.full-python-version.outputs.version }}-${{ hashFiles('**/poetry.lock') }}
59-
60-
- name: Ensure cache is healthy
61-
if: steps.cache.outputs.cache-hit == 'true'
62-
run: |
63-
# `timeout` is not available on macOS, so we define a custom function.
64-
[ "$(command -v timeout)" ] || function timeout() { perl -e 'alarm shift; exec @ARGV' "$@"; }
65-
# Using `timeout` is a safeguard against the Poetry command hanging for some reason.
66-
timeout 10s poetry run pip --version || rm -rf .venv
67-
68-
- name: Check lock file
69-
run: poetry lock --check
70-
71-
- name: Install dependencies
72-
run: poetry install
73-
74-
- name: Run tests
75-
run: poetry run python -m pytest -p no:sugar -q tests/
76-
77-
- name: Run integration tests
78-
run: poetry run python -m pytest -p no:sugar --integration -q tests/integration
79-
80-
- name: Run mypy
81-
run: poetry run mypy
94+
status:
95+
name: Status
96+
runs-on: ubuntu-latest
97+
if: '!cancelled()'
98+
needs:
99+
- lockfile
100+
- tests-matrix
101+
steps:
102+
- run: ${{ (contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')) && 'false' || 'true' }}

0 commit comments

Comments
 (0)