Skip to content

Commit

Permalink
ci: 🎨🧪 Modularize GHA workflow through reuse (#618)
Browse files Browse the repository at this point in the history
This change slightly refactors parts of the GitHub Actions CI/CD
workflow definitions to make it possible to rely on the main check
gate in branch protection and declutter the generic workflow.

It reproduces the original efforts of skipping the unnecessary checks
depending on the files changed via dynamically determined variables.
  • Loading branch information
webknjaz authored May 15, 2023
1 parent f5d5f15 commit 04df94c
Show file tree
Hide file tree
Showing 6 changed files with 216 additions and 130 deletions.
58 changes: 58 additions & 0 deletions .github/workflows/reusable-change-detection.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
name: change detection
on:
workflow_call:
outputs:
run-docs:
description: Whether or not build the docs
value: ${{ jobs.change-detection.outputs.run-docs || false }}
run-tests:
description: Whether or not run the tests
value: ${{ jobs.change-detection.outputs.run-tests || false }}

jobs:
change-detection:
name: Identify source changes
runs-on: ubuntu-latest
timeout-minutes: 1
outputs:
run-docs: ${{ steps.docs-changes.outputs.run-docs || false }}
run-tests: ${{ steps.tests-changes.outputs.run-tests || false }}
steps:
- uses: actions/checkout@v3
- name: Get a list of the changed runtime-related files
if: github.event_name == 'pull_request'
id: changed-testable-files
uses: Ana06/get-changed-files@v2.2.0
with:
filter: |
src/**
tests/**
tox.ini
.github/workflows/test.yml
.github/workflows/reusable-type.yml
.github/workflows/reusable-pytest.yml
- name: Set a flag for running the tests
if: >-
github.event_name != 'pull_request'
|| steps.changed-testable-files.outputs.added_modified_renamed != ''
id: tests-changes
run: >-
echo "run-tests=true" >> "${GITHUB_OUTPUT}"
- name: Get a list of the changed documentation-related files
if: github.event_name == 'pull_request'
id: changed-docs-files
uses: Ana06/get-changed-files@v2.2.0
with:
filter: |
docs/**
CHANGELOG.rst
README.md
.github/workflows/test.yml
.github/workflows/reusable-check.yml
- name: Set a flag for building the docs
if: >-
github.event_name != 'pull_request'
|| steps.changed-docs-files.outputs.added_modified_renamed != ''
id: docs-changes
run: >-
echo "run-docs=true" >> "${GITHUB_OUTPUT}"
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
name: check
on:
push:
branches:
- main
pull_request:
branches:
- main
schedule:
- cron: "0 8 * * *"
workflow_call:

jobs:
docs:
Expand Down
100 changes: 100 additions & 0 deletions .github/workflows/reusable-pytest.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
name: pytest
on:
workflow_call:

jobs:
pytest:
runs-on: ${{ matrix.os }}-latest
env:
PYTEST_ADDOPTS: "--run-integration --showlocals -vv --durations=10 --reruns 5 --only-rerun subprocess.CalledProcessError"
strategy:
fail-fast: false
matrix:
os:
- ubuntu
- macos
- windows
py:
- "pypy-3.7"
- "pypy-3.8"
- "pypy-3.9"
- "3.11"
- "3.10"
- "3.9"
- "3.8"
- "3.7"
tox-target:
- "tox"
- "min"

continue-on-error: >- # jobs not required in branch protection
${{
(
startsWith(matrix.py, 'pypy-')
&& (!endsWith(matrix.py, '-3.7') || matrix.os == 'windows')
)
&& true
|| false
}}
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0

- name: Setup python for test ${{ matrix.py }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.py }}

- name: Pick environment to run
run: |
import platform
import os
import sys
if platform.python_implementation() == "PyPy":
base = f"pypy{sys.version_info.major}{sys.version_info.minor}"
else:
base = f"py{sys.version_info.major}{sys.version_info.minor}"
env = f"BASE={base}\n"
print(f"Picked:\n{env}for {sys.version}")
with open(os.environ["GITHUB_ENV"], "a", encoding="utf-8") as file:
file.write(env)
shell: python

- name: Setup python for tox
uses: actions/setup-python@v4
with:
python-version: 3.9

- name: Install tox
run: python -m pip install tox

- name: Run test suite via tox
if: matrix.tox-target == 'tox'
run: |
tox -vv --notest -e ${{env.BASE}}
tox -e ${{env.BASE}} --skip-pkg-install
- name: Run minimum version test
if: matrix.tox-target == 'min'
run: tox -e ${{env.BASE}}-${{ matrix.tox-target }}

- name: Run path test
if: matrix.tox-target == 'tox' && matrix.py == '3.10'
run: tox -e path

- name: Combine coverage files
if: always()
run: tox -e coverage

- uses: codecov/codecov-action@v3
if: always()
env:
PYTHON: ${{ matrix.python }}
with:
file: ./.tox/coverage.xml
flags: tests
env_vars: PYTHON
name: ${{ matrix.py }} - ${{ matrix.os }}
26 changes: 26 additions & 0 deletions .github/workflows/reusable-type.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: type
on:
workflow_call:

jobs:
type:
runs-on: ubuntu-latest
env:
PY_COLORS: 1
TOX_PARALLEL_NO_SPINNER: 1
steps:
- uses: actions/checkout@v3

- name: Setup Python 3.9
uses: actions/setup-python@v4
with:
python-version: 3.9

- name: Install tox
run: python -m pip install tox

- name: Setup run environment
run: tox -vv --notest -e type

- name: Run check for type
run: tox -e type --skip-pkg-install
152 changes: 31 additions & 121 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,9 @@ on:
push:
branches:
- main
paths-ignore:
- "docs/**"
- "*.md"
- "*.rst"
pull_request:
branches:
- main
paths-ignore:
- "docs/**"
- "*.md"
- "*.rst"
schedule:
- cron: "0 8 * * *"
workflow_dispatch:
Expand All @@ -23,129 +15,31 @@ concurrency:
cancel-in-progress: true

jobs:
pytest:
runs-on: ${{ matrix.os }}-latest
env:
PYTEST_ADDOPTS: "--run-integration --showlocals -vv --durations=10 --reruns 5 --only-rerun subprocess.CalledProcessError"
strategy:
fail-fast: false
matrix:
os:
- ubuntu
- macos
- windows
py:
- "pypy-3.7"
- "pypy-3.8"
- "pypy-3.9"
- "3.11"
- "3.10"
- "3.9"
- "3.8"
- "3.7"
tox-target:
- "tox"
- "min"

continue-on-error: >- # jobs not required in branch protection
${{
(
startsWith(matrix.py, 'pypy-')
&& (!endsWith(matrix.py, '-3.7') || matrix.os == 'windows')
)
&& true
|| false
}}
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0

- name: Setup python for test ${{ matrix.py }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.py }}

- name: Pick environment to run
run: |
import platform
import os
import sys
if platform.python_implementation() == "PyPy":
base = f"pypy{sys.version_info.major}{sys.version_info.minor}"
else:
base = f"py{sys.version_info.major}{sys.version_info.minor}"
env = f"BASE={base}\n"
print(f"Picked:\n{env}for {sys.version}")
with open(os.environ["GITHUB_ENV"], "a", encoding="utf-8") as file:
file.write(env)
shell: python

- name: Setup python for tox
uses: actions/setup-python@v4
with:
python-version: 3.9

- name: Install tox
run: python -m pip install tox
change-detection:
uses: ./.github/workflows/reusable-change-detection.yml

- name: Run test suite via tox
if: matrix.tox-target == 'tox'
run: |
tox -vv --notest -e ${{env.BASE}}
tox -e ${{env.BASE}} --skip-pkg-install
check-docs:
needs: change-detection
if: fromJSON(needs.change-detection.outputs.run-docs)
uses: ./.github/workflows/reusable-docs.yml

- name: Run minimum version test
if: matrix.tox-target == 'min'
run: tox -e ${{env.BASE}}-${{ matrix.tox-target }}

- name: Run path test
if: matrix.tox-target == 'tox' && matrix.py == '3.10'
run: tox -e path

- name: Combine coverage files
if: always()
run: tox -e coverage

- uses: codecov/codecov-action@v3
if: always()
env:
PYTHON: ${{ matrix.python }}
with:
file: ./.tox/coverage.xml
flags: tests
env_vars: PYTHON
name: ${{ matrix.py }} - ${{ matrix.os }}
pytest:
needs: change-detection
if: fromJSON(needs.change-detection.outputs.run-tests)
uses: ./.github/workflows/reusable-pytest.yml

type:
runs-on: ubuntu-latest
env:
PY_COLORS: 1
TOX_PARALLEL_NO_SPINNER: 1
steps:
- uses: actions/checkout@v3

- name: Setup Python 3.9
uses: actions/setup-python@v4
with:
python-version: 3.9

- name: Install tox
run: python -m pip install tox

- name: Setup run environment
run: tox -vv --notest -e type

- name: Run check for type
run: tox -e type --skip-pkg-install
needs: change-detection
if: fromJSON(needs.change-detection.outputs.run-tests)
uses: ./.github/workflows/reusable-type.yml

# https://github.com/marketplace/actions/alls-green#why
required-checks-pass: # This job does nothing and is only used for the branch protection
if: always()

needs:
- change-detection # transitive
- check-docs
- pytest
- type

Expand All @@ -155,4 +49,20 @@ jobs:
- name: Decide whether the needed jobs succeeded or failed
uses: re-actors/alls-green@release/v1
with:
allowed-skips: >-
${{
fromJSON(needs.change-detection.outputs.run-docs)
&& ''
|| '
check-docs,
'
}}
${{
fromJSON(needs.change-detection.outputs.run-tests)
&& ''
|| '
pytest,
type,
'
}}
jobs: ${{ toJSON(needs) }}
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# build

[![pre-commit.ci status](https://results.pre-commit.ci/badge/github/pypa/build/main.svg)](https://results.pre-commit.ci/latest/github/pypa/build/main)
[![CI check](https://github.com/pypa/build/workflows/check/badge.svg)](https://github.com/pypa/build/actions)
[![CI test](https://github.com/pypa/build/actions/workflows/test.yml/badge.svg)](https://github.com/pypa/build/actions/workflows/test.yml)
[![codecov](https://codecov.io/gh/pypa/build/branch/main/graph/badge.svg)](https://codecov.io/gh/pypa/build)

Expand Down

0 comments on commit 04df94c

Please sign in to comment.