Python Checks
python-checks@1.0.0 Template Install with uv, Poetry or pip and run lint, type-check and test commands in order.
Start from it
flightstack template use python-checks What it does
Detects the installer your repo already uses (uv, Poetry or pip) from what it commits, installs into an isolated environment, then runs each command in order and stops at the first failure.
Inputs
-
commandsarray required - Commands to run inside the project environment, in order, e.g. "ruff check .", "mypy src", "pytest -q".
-
workingDirstring default. - Directory holding pyproject.toml or requirements.txt.
-
installerauto | uv | poetry | pip defaultauto autouses uv when uv.lock is committed, Poetry when poetry.lock is, and pip otherwise.-
extrasstring - Extras or dependency groups to install, comma-separated, e.g. "dev".
-
requirementsFilestring defaultrequirements.txt - pip only - requirements file to install when there is no pyproject.toml.
-
pythonVersionstring - Fail early unless
python3 --versionreports this prefix, e.g. "3.12". -
envobject - Extra environment variables for the commands.
Definition
name: Python Checks
description: >-
Install a Python project with the tool it already uses (uv, Poetry or pip)
and run lint, type-check and test commands in order.
triggers:
- type: push
branches: [main]
- type: pullRequest
jobs:
checks:
name: Lint and test
type: plugin/python-checks
with:
commands:
- ruff check .
- pytest
plugin:
name: python-checks
displayName: Python Checks
description: >-
Detect uv, Poetry or pip from the files the repo commits, install into an
isolated environment, then run each command in order and stop at the
first failure.
category: quality
supportedPlatforms:
- linux
- macos
- windows
parameters:
type: object
properties:
commands:
type: array
description: >-
Commands to run inside the project environment, in order, e.g.
"ruff check .", "mypy src", "pytest -q".
workingDir:
type: string
default: "."
description: Directory holding pyproject.toml or requirements.txt.
installer:
type: string
enum: [auto, uv, poetry, pip]
default: auto
description: >-
`auto` uses uv when uv.lock is committed, Poetry when poetry.lock is,
and pip otherwise.
extras:
type: string
default: ""
description: >-
Extras or dependency groups to install, comma-separated, e.g. "dev".
requirementsFile:
type: string
default: requirements.txt
description: pip only - requirements file to install when there is no pyproject.toml.
pythonVersion:
type: string
default: ""
description: >-
Fail early unless `python3 --version` reports this prefix, e.g. "3.12".
env:
type: object
description: Extra environment variables for the commands.
required: [commands]
script: |
set -euo pipefail
cd "{{workingDir}}"
py="$(command -v python3 || command -v python || true)"
if [ -z "$py" ]; then
echo "Python is not installed on this agent." >&2
exit 1
fi
version="$("$py" --version 2>&1 | awk '{print $2}')"
echo "python $version"
wanted="{{pythonVersion}}"
if [ -n "$wanted" ] && [ "${version#"$wanted"}" = "$version" ]; then
echo "This job wants Python $wanted but the agent has $version." >&2
exit 1
fi
installer="{{installer}}"
if [ "$installer" = "auto" ]; then
if [ -f uv.lock ]; then installer=uv
elif [ -f poetry.lock ]; then installer=poetry
else installer=pip
fi
fi
echo "installer: $installer"
extras="{{extras}}"
{{#each env}}
export {{@key}}="{{this}}"
{{/each}}
case "$installer" in
uv)
command -v uv >/dev/null 2>&1 || "$py" -m pip install --quiet uv
groups=()
for g in $(echo "$extras" | tr ',' ' '); do
groups+=(--group "$g")
done
uv sync --frozen ${groups[@]+"${groups[@]}"}
run() { uv run --frozen -- bash -c "$1"; }
;;
poetry)
command -v poetry >/dev/null 2>&1 || "$py" -m pip install --quiet poetry
if [ -n "$extras" ]; then
poetry install --no-interaction --with "$extras"
else
poetry install --no-interaction
fi
run() { poetry run bash -c "$1"; }
;;
pip)
"$py" -m venv .fs-venv
. .fs-venv/bin/activate 2>/dev/null || . .fs-venv/Scripts/activate
python -m pip install --quiet --upgrade pip
if [ -f pyproject.toml ]; then
if [ -n "$extras" ]; then pip install -e ".[$extras]"; else pip install -e .; fi
elif [ -f "{{requirementsFile}}" ]; then
pip install -r "{{requirementsFile}}"
fi
run() { bash -c "$1"; }
;;
esac
{{#each commands}}
echo "--- {{this}}"
run "{{this}}"
{{/each}}