Skip to content

Commit

Permalink
ci: run Nox sessions in GitHub Actions
Browse files Browse the repository at this point in the history
  • Loading branch information
paduszyk committed May 22, 2024
1 parent 53b97f3 commit 5c7f021
Show file tree
Hide file tree
Showing 5 changed files with 214 additions and 0 deletions.
112 changes: 112 additions & 0 deletions .github/workflows/python-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
name: "Python: CI"

on:
push:
branches:
- main
pull_request:
branches:
- main

jobs:
get-python-versions:
name: Get Python versions
runs-on: ubuntu-latest
outputs:
python-versions: ${{ steps.python-versions.outputs.python-versions }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
- id: python-versions
run: |
echo "python-versions<<EOF" >> $GITHUB_OUTPUT
echo "$(python ./scripts/get_python_versions.py)" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
format-nox-sessions:
name: Format Nox sessions
runs-on: ubuntu-latest
outputs:
install-sessions: ${{ steps.nox-sessions.outputs.install-sessions }}
lint-sessions: ${{ steps.nox-sessions.outputs.lint-sessions }}
test-sessions: ${{ steps.nox-sessions.outputs.test-sessions }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
cache: pip
- run: python -m pip install --upgrade pip
- run: python -m pip install nox
- id: nox-sessions
run: |
echo "install-sessions=$(python ./scripts/format_nox_sessions.py install)" >> $GITHUB_OUTPUT
echo "lint-sessions=$(python ./scripts/format_nox_sessions.py lint)" >> $GITHUB_OUTPUT
echo "test-sessions=$(python ./scripts/format_nox_sessions.py test)" >> $GITHUB_OUTPUT
install:
name: ${{ matrix.session.job }}
needs:
- get-python-versions
- format-nox-sessions
runs-on: ubuntu-latest
strategy:
matrix:
session: ${{ fromJson(needs.format-nox-sessions.outputs.install-sessions) }}
fail-fast: false
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: ${{ needs.get-python-versions.outputs.python-versions }}
cache: pip
- run: python -m pip install --upgrade pip
- run: python -m pip install nox
- run: nox --session "${{ matrix.session.name }}"
lint:
name: ${{ matrix.session.job }}
needs:
- format-nox-sessions
- install
runs-on: ubuntu-latest
strategy:
matrix:
session: ${{ fromJson(needs.format-nox-sessions.outputs.lint-sessions) }}
fail-fast: false
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
cache: pip
- run: python -m pip install --upgrade pip
- run: python -m pip install nox
- run: nox --session "${{ matrix.session.name }}"
test:
name: ${{ matrix.session.job }}
needs:
- get-python-versions
- format-nox-sessions
- install
runs-on: ubuntu-latest
strategy:
matrix:
session: ${{ fromJson(needs.format-nox-sessions.outputs.test-sessions) }}
fail-fast: false
services:
postgresql:
image: ${{ contains(matrix.session.name, 'postgresql') && 'postgres:latest' || '' }}
env:
POSTGRES_PASSWORD: postgres
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: ${{ needs.get-python-versions.outputs.python-versions }}
cache: pip
- run: python -m pip install --upgrade pip
- run: python -m pip install nox
- run: nox --session "${{ matrix.session.name }}"
2 changes: 2 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# django-xlsx-serializer

[![Pre-commit](https://img.shields.io/github/actions/workflow/status/paduszyk/django-xlsx-serializer/pre-commit-run.yml?style=flat-square&label=pre-commit&logo=pre-commit)][pre-commit]
[![Python: CI](https://img.shields.io/github/actions/workflow/status/paduszyk/django-xlsx-serializer/python-ci.yml?style=flat-square&logo=github&label=CI)][python-ci]

[![Nox](https://img.shields.io/badge/%F0%9F%A6%8A-Nox-D85E00.svg?style=flat-square)][nox]
[![Ruff](https://img.shields.io/endpoint?style=flat-square&url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)][ruff]
Expand All @@ -23,4 +24,5 @@ Released under the [MIT license][license].
[paduszyk]: https://github.com/paduszyk
[pre-commit]: https://github.com/paduszyk/django-xlsx-serializer/actions/workflows/pre-commit-run.yml
[prettier]: https://prettier.io
[python-ci]: https://github.com/paduszyk/django-xlsx-serializer/actions/workflows/python-ci.yml
[ruff]: https://docs.astral.sh/ruff/
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ select = ["ALL"]
ignore = ["ANN", "D"]

[tool.ruff.lint.per-file-ignores]
"scripts/**/*.py" = ["INP"]
"tests/**/*.py" = ["ARG", "DJ", "E501", "FBT", "PLR2004", "S101"]

[tool.ruff.lint.isort]
Expand Down
63 changes: 63 additions & 0 deletions scripts/format_nox_sessions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
from __future__ import annotations

import argparse
import json
import subprocess
import sys
from typing import Any, Callable

SESSION_NAME_FORMATS = {
"install": "Install package (Python {python})",
"ruff_lint": "Lint package (Ruff)",
"ruff_format": "Format package (Ruff)",
"mypy": "Type-check package (Mypy)",
"pytest": "Test package (Python {python}, Django {django}, {database_engine})",
}


CALL_SPEC_VALUE_FORMATTERS = {
"database_engine": lambda value: {
"postgresql": "PostgreSQL",
"sqlite3": "SQLite",
}[value],
}


def format_nox_session(session: dict[str, Any]) -> dict[str, str]:
def get_session_call_spec_value_formatter(name: str) -> Callable[[str], str]:
return CALL_SPEC_VALUE_FORMATTERS.get(name, lambda value: value)

name = session["name"]
python = session.get("python") or ""
call_specs = {
name: get_session_call_spec_value_formatter(name)(value)
for name, value in session["call_spec"].items()
}

return {
"name": session["session"],
"job": SESSION_NAME_FORMATS[name].format(python=python, **call_specs),
}


def format_nox_sessions(tag: str) -> str:
sessions = json.loads(
subprocess.check_output(
f"{sys.executable} -m nox --tag {tag} --list-sessions --json".split(), # noqa: S603
),
)

return json.dumps(list(map(format_nox_session, sessions)))


def main() -> None:
parser = argparse.ArgumentParser()
parser.add_argument("tag", type=str)

args = parser.parse_args()

sys.stdout.write(format_nox_sessions(args.tag))


if __name__ == "__main__":
main()
36 changes: 36 additions & 0 deletions scripts/get_python_versions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
from __future__ import annotations

import re
import sys
from pathlib import Path

if sys.version_info >= (3, 11):
import tomllib
else:
import tomli as tomllib

PYPROJECT_TOML_PATH = Path(__file__).resolve().parents[1] / "pyproject.toml"


def get_python_versions() -> list[str]:
with PYPROJECT_TOML_PATH.open(mode="rb") as f:
classifiers = tomllib.load(f)["project"]["classifiers"]

return [
version_match.group(1)
for classifier in classifiers
if (
version_match := re.match(
r"Programming Language :: Python :: (\d+\.\d+)",
classifier,
)
)
]


def main() -> None:
sys.stdout.write("\n".join(get_python_versions()))


if __name__ == "__main__":
main()

0 comments on commit 5c7f021

Please sign in to comment.