Files
MeshTerm/.github/workflows/ci.yml
T
Jean-Pierre MartineauandClaude Opus 5.5 b7a1ad47c2 The Oxford comma, always, the one-line description included
Every list of three or more takes the serial comma: the one-liner in
pyproject.toml, meshterm/__init__.py, and --help ("USB, Bluetooth, or TCP",
"Windows, macOS, and Linux"), the README, the changelog, the manuals, the
issue and PR templates, and six strings the app shows (the region-name
rule, a repeater setting's help, the diagnostics tool's description, and
the archive confirms). The Windows-console notice is rewrapped so its
comma keeps it inside 72 columns.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-25 21:28:00 -04:00

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"