Python 3.10 reaches end of life in October 2026, and the newer image that ubuntu-latest moves to may not offer it. The leg would then fail on setup, and the badge on the public README would turn red with nothing broken. Pinning it keeps 3.10 tested for as long as MeshTerm says it supports it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
123 lines
4.5 KiB
YAML
123 lines
4.5 KiB
YAML
# The three commands CONTRIBUTING.md asks a contributor to run, run for them.
|
|
#
|
|
# Split in two on purpose. Style is a property of the source, not of the machine, so
|
|
# `lint` runs once and its failure is unambiguous. Behaviour is a property of the
|
|
# machine, so `test` runs everywhere we claim to work — the description promises
|
|
# Windows, macOS and Linux, and until this file existed that promise had only ever been
|
|
# checked on one of them.
|
|
name: CI
|
|
|
|
on:
|
|
push:
|
|
branches: [main]
|
|
pull_request:
|
|
workflow_dispatch:
|
|
|
|
# Nothing here writes to the repository; say so rather than inherit the default.
|
|
permissions:
|
|
contents: read
|
|
|
|
# A second push while the first is still running makes the first answer obsolete.
|
|
# Cancel it — a run on a stale commit is a queue slot and a wait spent on nothing.
|
|
concurrency:
|
|
group: ci-${{ github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
jobs:
|
|
lint:
|
|
name: lint
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 10
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- uses: actions/setup-python@v5
|
|
with:
|
|
python-version: "3.14"
|
|
cache: pip
|
|
cache-dependency-path: pyproject.toml
|
|
|
|
- run: pip install -e ".[dev]"
|
|
|
|
# Both gates, and the second runs even when the first fails: they report
|
|
# different things and seeing only the earlier one wastes a round trip.
|
|
- run: ruff check .
|
|
- if: ${{ !cancelled() }}
|
|
run: ruff format --check .
|
|
|
|
test:
|
|
name: test ${{ matrix.os }} py${{ matrix.python }}
|
|
runs-on: ${{ matrix.os }}
|
|
timeout-minutes: 15
|
|
strategy:
|
|
# Let every leg finish. The point of a run is the whole picture of what broke,
|
|
# and one red leg cancelling its siblings hides the rest until the next push.
|
|
fail-fast: false
|
|
matrix:
|
|
# Linux carries the full Python range and the slower-to-schedule runners
|
|
# cover the ends of it, which is where a version-dependent break actually
|
|
# shows up. It was shaped this way when the repository was private and
|
|
# minutes were metered; on a public one they are not, so this can widen to
|
|
# every OS times every version whenever the wait for a full run is worth it.
|
|
#
|
|
# 3.10 stays on Ubuntu 24.04. It reaches end of life in October 2026, and a
|
|
# newer image that ubuntu-latest moves to may not offer it at all. That would
|
|
# turn the badge red with nothing broken. Drop this leg when the floor rises.
|
|
include:
|
|
- { os: ubuntu-24.04, python: "3.10" }
|
|
- { os: ubuntu-latest, python: "3.11" }
|
|
- { os: ubuntu-latest, python: "3.12" }
|
|
- { os: ubuntu-latest, python: "3.13" }
|
|
- { os: ubuntu-latest, python: "3.14" }
|
|
- { os: windows-latest, python: "3.10" }
|
|
- { os: windows-latest, python: "3.14" }
|
|
- { os: macos-latest, python: "3.14" }
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- uses: actions/setup-python@v5
|
|
with:
|
|
python-version: ${{ matrix.python }}
|
|
cache: pip
|
|
cache-dependency-path: pyproject.toml
|
|
|
|
- run: pip install -e ".[dev]"
|
|
|
|
# Includes tests/test_gallery.py, the dual-platform readability gate: every
|
|
# screen has to stay readable at 72 columns regular and 53 on the PicoCalc, and
|
|
# every PicoCalc case is a hard failure rather than a warning.
|
|
- run: python -m pytest -q
|
|
|
|
# Builds the distributions and checks them the way PyPI would, publishing nothing.
|
|
# Worth its minute: packaging breaks silently and is otherwise only discovered on
|
|
# the one day you least want to discover it. The wheel is installed into a clean
|
|
# environment and the command run from outside the source tree, because "it built"
|
|
# and "it works when installed" are different claims.
|
|
build:
|
|
name: build
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 10
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- uses: actions/setup-python@v5
|
|
with:
|
|
python-version: "3.14"
|
|
|
|
- run: pip install build twine
|
|
|
|
- run: python -m build
|
|
|
|
- run: twine check dist/*
|
|
|
|
- name: Install the wheel clean and run the command
|
|
run: |
|
|
python -m venv /tmp/fresh
|
|
/tmp/fresh/bin/pip install --quiet dist/*.whl
|
|
cd /tmp
|
|
/tmp/fresh/bin/meshterm --help > /dev/null
|
|
# A tool-provided subcommand, not just --help: the tools are discovered at
|
|
# runtime, so a broken package still answers --help perfectly well.
|
|
/tmp/fresh/bin/meshterm contacts --help > /dev/null
|
|
echo "the wheel installs, the console script runs, and its tools registered"
|