Strict typing #98
Workflow file for this run
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
name: CI | |
on: | |
push: | |
branches: | |
- master | |
- '[0-9].[0-9]+' # matches to backport branches, e.g. 3.6 | |
tags: [v*] | |
pull_request: | |
concurrency: | |
group: >- | |
${{ | |
github.workflow | |
}}-${{ | |
github.ref_type | |
}}-${{ | |
github.event.pull_request.number || github.sha | |
}} | |
cancel-in-progress: true | |
env: | |
COLOR: >- # Supposedly, pytest or coveragepy use this | |
yes | |
FORCE_COLOR: 1 # Request colored output from CLI tools supporting it | |
MYPY_FORCE_COLOR: 1 # MyPy's color enforcement | |
PIP_DISABLE_PIP_VERSION_CHECK: 1 # Hide "there's a newer pip" message | |
PIP_NO_PYTHON_VERSION_WARNING: 1 # Hide "this Python is deprecated" message | |
PIP_NO_WARN_SCRIPT_LOCATION: 1 # Hide "script dir is not in $PATH" message | |
PRE_COMMIT_COLOR: always | |
PROJECT_NAME: aiosignal | |
PY_COLORS: 1 # Recognized by the `py` package, dependency of `pytest` | |
PYTHONIOENCODING: utf-8 | |
PYTHONUTF8: 1 | |
TOX_PARALLEL_NO_SPINNER: 1 # Disable tox's parallel run spinner animation | |
TOX_TESTENV_PASSENV: >- # Make tox-wrapped tools see color requests | |
FORCE_COLOR | |
MYPY_FORCE_COLOR | |
NO_COLOR | |
PIP_DISABLE_PIP_VERSION_CHECK | |
PIP_NO_PYTHON_VERSION_WARNING | |
PIP_NO_WARN_SCRIPT_LOCATION | |
PRE_COMMIT_COLOR | |
PY_COLORS | |
PYTEST_THEME | |
PYTEST_THEME_MODE | |
PYTHONIOENCODING | |
PYTHONLEGACYWINDOWSSTDIO | |
PYTHONUTF8 | |
UPSTREAM_REPOSITORY_ID: >- | |
205007356 | |
jobs: | |
pre-setup: | |
name: ⚙️ Pre-set global build settings | |
runs-on: ubuntu-latest | |
timeout-minutes: 2 # network is slow sometimes when fetching from Git | |
defaults: | |
run: | |
shell: python | |
outputs: | |
# NOTE: These aren't env vars because the `${{ env }}` context is | |
# NOTE: inaccessible when passing inputs to reusable workflows. | |
dists-artifact-name: python-package-distributions | |
release-requested: >- | |
${{ | |
( | |
github.event_name == 'push' | |
&& github.ref_type == 'tag' | |
) | |
&& true | |
|| false | |
}} | |
cache-key-for-dep-files: >- | |
${{ steps.calc-cache-key-files.outputs.cache-key-for-dep-files }} | |
sdist-artifact-name: ${{ steps.artifact-name.outputs.sdist }} | |
wheel-artifact-name: ${{ steps.artifact-name.outputs.wheel }} | |
upstream-repository-id: ${{ env.UPSTREAM_REPOSITORY_ID }} | |
is-debug-mode: ${{ toJSON(runner.debug == '1') }} | |
steps: | |
- name: Switch to using Python 3.11 by default | |
uses: actions/setup-python@v5 | |
with: | |
python-version: 3.11 | |
- name: Check out src from Git | |
uses: actions/checkout@v4 | |
- name: >- | |
Calculate dependency files' combined hash value | |
for use in the cache key | |
id: calc-cache-key-files | |
uses: ./.github/actions/cache-keys | |
- name: Set the expected dist artifact names | |
id: artifact-name | |
run: | | |
from os import environ | |
from pathlib import Path | |
FILE_APPEND_MODE = 'a' | |
whl_file_prj_base_name = '${{ env.PROJECT_NAME }}'.replace('-', '_') | |
sdist_file_prj_base_name = whl_file_prj_base_name.replace('.', '_') | |
with Path(environ['GITHUB_OUTPUT']).open( | |
mode=FILE_APPEND_MODE, | |
) as outputs_file: | |
print( | |
f"sdist={sdist_file_prj_base_name !s}-*.tar.gz", | |
file=outputs_file, | |
) | |
print( | |
f"wheel={whl_file_prj_base_name !s}-*-py3-none-any.whl", | |
file=outputs_file, | |
) | |
build: | |
name: >- | |
📦 ${{ github.ref_name }} | |
needs: | |
- pre-setup | |
uses: tox-dev/workflow/.github/workflows/reusable-tox.yml@208490c75f7f6b81e2698cc959f24d264c462d57 # yamllint disable-line rule:line-length | |
with: | |
cache-key-for-dependency-files: >- | |
${{ needs.pre-setup.outputs.cache-key-for-dep-files }} | |
check-name: Build dists under 🐍3.13 | |
job-dependencies-context: >- # context for hooks | |
${{ toJSON(needs) }} | |
python-version: 3.13 | |
runner-vm-os: ubuntu-latest | |
timeout-minutes: 2 | |
toxenv: build-dists | |
xfail: false | |
lint: | |
name: 🧹 Linters${{ '' }} # nest jobs under the same sidebar category | |
needs: | |
- build | |
- pre-setup # transitive, for accessing settings | |
strategy: | |
matrix: | |
runner-vm-os: | |
- ubuntu-latest | |
python-version: | |
- 3.13 | |
toxenv: | |
- pre-commit | |
- metadata-validation | |
- build-docs | |
# - codelinter-docs | |
# - coverage-docs | |
# - doctest-docs | |
# - linkcheck-docs | |
- spellcheck-docs | |
xfail: | |
- false | |
fail-fast: false | |
uses: tox-dev/workflow/.github/workflows/reusable-tox.yml@208490c75f7f6b81e2698cc959f24d264c462d57 # yamllint disable-line rule:line-length | |
with: | |
built-wheel-names: >- | |
${{ | |
matrix.toxenv == 'metadata-validation' | |
&& needs.pre-setup.outputs.wheel-artifact-name | |
|| '' | |
}} | |
cache-key-for-dependency-files: >- | |
${{ needs.pre-setup.outputs.cache-key-for-dep-files }} | |
checkout-src-git-fetch-depth: >- | |
${{ | |
fromJSON(needs.pre-setup.outputs.release-requested) | |
&& 1 | |
|| 0 | |
}} | |
dists-artifact-name: >- | |
${{ needs.pre-setup.outputs.dists-artifact-name }} | |
post-toxenv-preparation-command: >- | |
${{ | |
matrix.toxenv == 'pre-commit' | |
&& 'python -Im pre_commit install-hooks' | |
|| '' | |
}} | |
python-version: >- | |
${{ matrix.python-version }} | |
require-successful-codecov-uploads: >- | |
${{ | |
toJSON( | |
needs.pre-setup.outputs.upstream-repository-id | |
== github.repository_id | |
) | |
}} | |
runner-vm-os: >- | |
${{ matrix.runner-vm-os }} | |
# NOTE: `pre-commit --show-diff-on-failure` and | |
# NOTE: `sphinxcontrib-spellcheck` with Git authors allowlist enabled | |
# NOTE: both depend on the presence of a Git repository. | |
source-tarball-name: >- | |
${{ | |
!contains( | |
fromJSON('["pre-commit", "spellcheck-docs"]'), | |
matrix.toxenv | |
) | |
&& needs.pre-setup.outputs.sdist-artifact-name | |
|| '' | |
}} | |
# NOTE: `pre-commit` and `sphinxcontrib-spellcheck` both depend on Git. | |
# NOTE: They may get slower due to network I/O, hence bigger timeout. | |
timeout-minutes: >- | |
${{ | |
!contains( | |
fromJSON('["pre-commit", "spellcheck-docs"]'), | |
matrix.toxenv | |
) | |
&& 4 | |
|| 2 | |
}} | |
toxenv: >- | |
${{ matrix.toxenv }} | |
xfail: >- | |
${{ matrix.xfail }} | |
secrets: | |
codecov-token: ${{ secrets.CODECOV_TOKEN }} | |
tests: | |
name: 🧪 Tests${{ '' }} # nest jobs under the same sidebar category | |
needs: | |
- build | |
- pre-setup # transitive, for accessing settings | |
strategy: | |
fail-fast: >- # ${{ runner.debug }} is unavailable in this context | |
${{ | |
fromJSON(needs.pre-setup.outputs.is-debug-mode) | |
&& false | |
|| true | |
}} | |
matrix: | |
python-version: | |
# NOTE: The latest and the lowest supported Pythons are prioritized | |
# NOTE: to improve the responsiveness. It's nice to see the most | |
# NOTE: important results first. | |
- 3.13 | |
- 3.9 | |
- 3.12 | |
- 3.11 | |
- >- | |
3.10 | |
runner-vm-os: | |
- ubuntu-24.04 | |
toxenv: | |
- py | |
xfail: | |
- false | |
uses: tox-dev/workflow/.github/workflows/reusable-tox.yml@208490c75f7f6b81e2698cc959f24d264c462d57 # yamllint disable-line rule:line-length | |
with: | |
built-wheel-names: >- | |
${{ needs.pre-setup.outputs.wheel-artifact-name }} | |
cache-key-for-dependency-files: >- | |
${{ needs.pre-setup.outputs.cache-key-for-dep-files }} | |
check-name: >- | |
🧪 🐍${{ | |
matrix.python-version | |
}} @ ${{ | |
matrix.runner-vm-os | |
}} | |
dists-artifact-name: >- | |
${{ needs.pre-setup.outputs.dists-artifact-name }} | |
job-dependencies-context: >- # context for hooks | |
${{ toJSON(needs) }} | |
python-version: >- | |
${{ matrix.python-version }} | |
require-successful-codecov-uploads: >- | |
${{ | |
toJSON( | |
needs.pre-setup.outputs.upstream-repository-id | |
== github.repository_id | |
) | |
}} | |
runner-vm-os: >- | |
${{ matrix.runner-vm-os }} | |
source-tarball-name: >- | |
${{ needs.pre-setup.outputs.sdist-artifact-name }} | |
timeout-minutes: 2 | |
toxenv: >- | |
${{ matrix.toxenv }} | |
# tox-provision-args: >- | |
# --force-dep '...' | |
tox-run-posargs: >- | |
--cov-report=xml:.tox/.tmp/.test-results/pytest-${{ | |
matrix.python-version | |
}}/cobertura.xml | |
--junitxml=.tox/.tmp/.test-results/pytest-${{ | |
matrix.python-version | |
}}/test.xml | |
tox-rerun-posargs: >- | |
--no-cov | |
-vvvvv | |
--lf | |
xfail: >- | |
${{ matrix.xfail }} | |
secrets: | |
codecov-token: ${{ secrets.CODECOV_TOKEN }} | |
test-summary: | |
name: Test matrix status | |
runs-on: ubuntu-latest | |
needs: | |
- lint | |
- tests | |
if: always() | |
steps: | |
- name: Decide whether the needed jobs succeeded or failed | |
uses: re-actors/alls-green@release/v1 | |
with: | |
jobs: ${{ toJSON(needs) }} | |
deploy: | |
name: Deploy | |
runs-on: ubuntu-latest | |
needs: | |
- pre-setup # transitive, for accessing settings | |
- test-summary | |
# Run only on pushing a tag | |
if: >- | |
always() | |
&& needs.test-summary.result == 'success' | |
&& fromJSON(needs.pre-setup.outputs.release-requested) | |
&& needs.pre-setup.outputs.upstream-repository-id == github.repository_id | |
permissions: | |
contents: write # IMPORTANT: mandatory for making GitHub Releases | |
id-token: write # IMPORTANT: mandatory for trusted publishing & sigstore | |
environment: | |
name: pypi | |
url: https://pypi.org/p/${{ env.PROJECT_NAME }} | |
steps: | |
- name: Download all the dists | |
uses: actions/download-artifact@v4 | |
with: | |
name: >- | |
${{ needs.pre-setup.outputs.dists-artifact-name }} | |
path: dist/ | |
- name: Login | |
run: | | |
echo "${{ secrets.GITHUB_TOKEN }}" | gh auth login --with-token | |
- name: Release | |
uses: aio-libs/[email protected] | |
with: | |
changes_file: CHANGES.rst | |
name: ${{ env.PROJECT_NAME }} | |
github_token: ${{ secrets.GITHUB_TOKEN }} | |
pypi_token: ${{ secrets.PYPI_TOKEN }} | |
artifact: '' | |
version_file: ${{ env.PROJECT_NAME }}/__init__.py | |
fix_issue_regex: "\n?\\s*`#(\\d+) <https://github.com/aio-libs/${{ env.PROJECT_NAME }}/issues/\\1>`_" | |
fix_issue_repl: ' (#\1)' | |
- name: >- | |
Publish 🐍📦 to PyPI | |
uses: pypa/gh-action-pypi-publish@release/v1 | |
- name: Sign the dists with Sigstore | |
uses: sigstore/[email protected] | |
with: | |
inputs: >- | |
dist/${{ needs.pre-setup.outputs.sdist-artifact-name }} | |
dist/${{ needs.pre-setup.outputs.wheel-artifact-name }} | |
- name: Upload artifact signatures to GitHub Release | |
# Confusingly, this action also supports updating releases, not | |
# just creating them. This is what we want here, since we've manually | |
# created the release above. | |
uses: softprops/action-gh-release@v2 | |
with: | |
# dist/ contains the built packages, which smoketest-artifacts/ | |
# contains the signatures and certificates. | |
files: dist/** |