ci: drop pytest lanes from ci-python-app (#146)

Collect-only and subproject-tests were unused on most callers. Pytest stays a caller-owned job. The reusable now emits lint plus the ci / ci aggregator.
This commit is contained in:
Adam Moussa 2026-09-22 15:52:03 -04:00 • committed by GitHub
parent 216604ad67
commit c34891cb5d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 12 additions and 82 deletions

View file

@ -1,19 +1,14 @@
name: CI — Python (app)
# Reusable CI for plain Python apps / locally-run tooling that do NOT deploy via
# SAM or CDK (use ci-python-sam.yaml / ci-typescript-cdk.yaml for those). Beyond
# lint + format it adds two things such repos commonly need:
# * a collect-only import check for a root suite whose live run needs secrets
# (verifies every test module imports cleanly without running them), and
# * an isolated full pytest run for a self-contained subproject dir whose tests
# package collides with the root tests/ package (e.g. a `tests/` under a
# subdir) and so must run in its own working directory.
# SAM or CDK (use ci-python-sam.yaml / ci-typescript-cdk.yaml for those).
# Runs ruff check + format, plus an optional conventions audit.
#
# Naming is load-bearing (see this repo's ci.yaml): the org ruleset matches the
# required `ci / ci` check against the JOB check-run name. A caller job keyed `ci`
# invoking this workflow reports each job here as `ci / <job>`, so the aggregator
# job below is keyed `ci` to emit exactly `ci / ci`. The aggregator gates on every
# other job, so the single required check fails if any sub-job fails.
# job below is keyed `ci` to emit exactly `ci / ci`. The aggregator gates on lint,
# so the single required check fails if lint fails.
on:
workflow_call:
@ -26,18 +21,6 @@ on:
description: "Space-separated directories for ruff (default: repo root)"
type: string
default: "."
requirements:
description: "Requirements file used for the pip cache key + install"
type: string
default: "requirements.txt"
collect-only:
description: "Run 'pytest --collect-only' at the repo root (imports resolve without secrets)"
type: boolean
default: true
subproject-dir:
description: "Optional self-contained subproject dir whose pytest suite runs in full"
type: string
default: ""
run-conventions-check:
description: "Run the lightweight conventions audit (README + .gitignore covers .env)"
type: boolean
@ -52,10 +35,8 @@ jobs:
timeout-minutes: 10
# The trailing segment of every group in this file is the job id written
# out literally, NOT `${{ github.job }}`. In a called workflow that
# expression evaluates to the CALLER's job id, so all four jobs here would
# expression evaluates to the CALLER's job id, so sibling jobs would
# resolve to one group and, with cancel-in-progress on, cancel each other.
# Observed live in pr-reviewer: `lint` was cancelled one second in by a
# sibling and the aggregator failed on the cancelled dependency.
concurrency:
group: ci-python-app-${{ github.workflow }}-${{ github.ref }}-${{ inputs.source-dirs }}-lint
cancel-in-progress: true
@ -101,68 +82,19 @@ jobs:
fi
echo "Conventions check passed."
test-collect:
if: ${{ inputs.collect-only }}
runs-on: ubuntu-latest
timeout-minutes: 10
concurrency:
group: ci-python-app-${{ github.workflow }}-${{ github.ref }}-${{ inputs.source-dirs }}-test-collect
cancel-in-progress: true
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: ${{ inputs.python-version }}
cache: pip
cache-dependency-path: ${{ inputs.requirements }}
- name: Install dependencies
run: |
pip install -r "${{ inputs.requirements }}"
pip install pytest python-dotenv
- name: Pytest collect-only
run: pytest --collect-only -q
subproject-tests:
if: ${{ inputs.subproject-dir != '' }}
runs-on: ubuntu-latest
timeout-minutes: 10
concurrency:
group: ci-python-app-${{ github.workflow }}-${{ github.ref }}-${{ inputs.source-dirs }}-subproject-tests
cancel-in-progress: true
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: ${{ inputs.python-version }}
cache: pip
cache-dependency-path: ${{ inputs.requirements }}
- name: Install dependencies
run: |
pip install -r "${{ inputs.requirements }}"
pip install pytest
- name: Run subproject suite
working-directory: ${{ inputs.subproject-dir }}
run: python -m pytest -q
ci:
# Aggregator — keyed `ci` so a caller job keyed `ci` reports `ci / ci`.
needs: [lint, test-collect, subproject-tests]
needs: [lint]
if: always()
runs-on: ubuntu-latest
concurrency:
group: ci-python-app-${{ github.workflow }}-${{ github.ref }}-${{ inputs.source-dirs }}-ci
cancel-in-progress: true
steps:
- name: Require all jobs to have succeeded
- name: Require lint to have succeeded
run: |
if [ "${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') }}" = "true" ]; then
echo "A required CI job failed or was cancelled."
if [ "${{ needs.lint.result }}" != "success" ]; then
echo "lint failed or was cancelled."
exit 1
fi
echo "All CI jobs passed."

View file

@ -61,7 +61,7 @@ The formatter GitHub App is not on the main-branch bypass list.
**`.github/workflows/cd-cdk.yaml`** — Reusable CD workflow for CDK repos (TypeScript and Python). Runs `cdk deploy --all` with OIDC credentials. Supports optional Python setup for Python CDK repos and QEMU emulation for cross-platform Docker builds.
**`.github/workflows/ci-python-app.yaml`** — Reusable CI for non-SAM Python apps (ruff check + format, optional pytest; no SAM validate).
**`.github/workflows/ci-python-app.yaml`** — Reusable CI for non-SAM Python apps (ruff check + format and conventions; no pytest, no SAM validate). Pytest stays a caller-owned job.
**`.github/workflows/ci-dotnet.yaml`** — Reusable CI for .NET solutions (`dotnet build`, optional `dotnet test`; SDK version and solution path as inputs).

View file

@ -1,6 +1,6 @@
{
"name": "Sea Haven — CI (Python / app)",
"description": "Runs ruff check, ruff format --check, a pytest collect-only import check, and an optional subproject suite via the org reusable workflow. For Python repos that do not deploy via SAM or CDK.",
"description": "Runs ruff check, ruff format --check, and a conventions audit via the org reusable workflow. For Python repos that do not deploy via SAM or CDK.",
"iconName": "octicon-checklist",
"categories": ["Python", "Continuous integration"],
"filePatterns": ["requirements.*\\.txt$", "pyproject\\.toml$"]

View file

@ -9,7 +9,5 @@ jobs:
# Job id MUST stay `ci`: the reusable's aggregator job is also `ci`, so the
# check context resolves to the required `ci / ci`.
#
# Every input is optional. Common overrides: `source-dirs` (ruff targets),
# `requirements` (non-default requirements file), `subproject-dir` (a
# self-contained suite that must run in its own working directory).
# Every input is optional. Common override: `source-dirs` (ruff targets).
uses: Sea-Haven-Industries/.github/.github/workflows/ci-python-app.yaml@9781774f04b824b1182ff41638687f1c01c04361 # v1.0.11