Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 31 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,44 @@ name: CI
on:
push:
branches: [main]
paths-ignore:
- '**.md'
- 'docs/**'
- 'LICENSE*'
- '.gitignore'
- '.editorconfig'
pull_request:
branches: [main]
paths-ignore:
- '**.md'
- 'docs/**'
- 'LICENSE*'
- '.gitignore'
- '.editorconfig'

concurrency:
group: ci-${{ github.ref }}
group: ci-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

# Default to read-only token. Per-job escalation only where required.
permissions:
contents: read

jobs:
lint:
name: Lint & Format
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v6

- uses: actions/setup-python@v6
with:
python-version: '3.13'
# setup-python's pip cache hashes pyproject.toml. Massive
# warm-cache win on lint job since it only needs ruff.
cache: 'pip'
cache-dependency-path: pyproject.toml

- name: Install ruff
run: pip install ruff==0.15.4
Expand All @@ -33,6 +54,7 @@ jobs:
test:
name: Test (Python ${{ matrix.python-version }})
runs-on: ubuntu-latest
timeout-minutes: 10
strategy:
fail-fast: false
matrix:
Expand All @@ -43,6 +65,8 @@ jobs:
- uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
cache: 'pip'
cache-dependency-path: pyproject.toml

- name: Install dependencies
run: pip install -e ".[dev]"
Expand All @@ -53,12 +77,15 @@ jobs:
validate-api-contract:
name: Validate API Contract
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v6

- uses: actions/setup-python@v6
with:
python-version: '3.13'
cache: 'pip'
cache-dependency-path: pyproject.toml

- name: Install dependencies
run: pip install -e ".[dev]"
Expand Down Expand Up @@ -86,13 +113,16 @@ jobs:
build:
name: Build
runs-on: ubuntu-latest
timeout-minutes: 5
needs: [lint, test]
steps:
- uses: actions/checkout@v6

- uses: actions/setup-python@v6
with:
python-version: '3.13'
cache: 'pip'
cache-dependency-path: pyproject.toml

- name: Install build tools
run: pip install build
Expand Down
21 changes: 20 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,31 @@ on:
types: [published]
workflow_dispatch:

# Default to read-only. id-token: write is escalated only on the
# publish job that actually needs PyPI Trusted Publishing OIDC.
permissions:
id-token: write
contents: read

# Only one publish at a time -- never two concurrent publishes of
# the same version. Don't cancel in progress: a half-rolled-back
# publish is worse than two queued.
concurrency:
group: release-pypi
cancel-in-progress: false

jobs:
validate:
name: Validate
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v6

- uses: actions/setup-python@v6
with:
python-version: '3.13'
cache: 'pip'
cache-dependency-path: pyproject.toml

- name: Lint
run: |
Expand All @@ -39,13 +50,21 @@ jobs:
publish:
name: Publish to PyPI
runs-on: ubuntu-latest
timeout-minutes: 10
needs: validate
# PyPI Trusted Publishing needs id-token: write to mint the OIDC
# token. contents: read is for checkout. Nothing else escalates.
permissions:
contents: read
id-token: write
steps:
- uses: actions/checkout@v6

- uses: actions/setup-python@v6
with:
python-version: '3.13'
cache: 'pip'
cache-dependency-path: pyproject.toml

- name: Get version
id: version
Expand Down
16 changes: 14 additions & 2 deletions .github/workflows/sync-from-api.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,32 @@ on:
types: [openapi-spec-updated]
workflow_dispatch:

# Workflow-level: minimal. Job-level escalates to write where needed.
permissions:
contents: write
pull-requests: write
contents: read

# Only one sync at a time -- two parallel runs would race on the
# branch + PR creation.
concurrency:
group: sync-types
cancel-in-progress: false

jobs:
sync-types:
name: Generate Types from OpenAPI
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
contents: write
pull-requests: write
steps:
- uses: actions/checkout@v6

- uses: actions/setup-python@v6
with:
python-version: '3.13'
cache: 'pip'
cache-dependency-path: pyproject.toml

- name: Install dependencies
run: pip install -e ".[dev]"
Expand Down
Loading