4a19d70af1
CodeQL Advanced / Analyze (actions) (push) Waiting to run
CodeQL Advanced / Analyze (python) (push) Waiting to run
Tests / database-integration-tests (push) Waiting to run
MCP Server Tests / live-mcp-tests (push) Waiting to run
Server Tests / live-server-tests (push) Waiting to run
Pyright Type Check / pyright (push) Waiting to run
Tests / unit-tests (push) Waiting to run
Lint with Ruff / ruff (push) Has been cancelled
69 lines
3.2 KiB
YAML
69 lines
3.2 KiB
YAML
name: Lint with Ruff
|
|
|
|
# SECURITY: this workflow uses `pull_request_target` so that ruff lint/format runs
|
|
# automatically on outside-contributor (fork) PRs WITHOUT the "approve and run"
|
|
# gate that `pull_request` imposes for first-time contributors.
|
|
#
|
|
# `pull_request_target` runs in the BASE-branch context, which can carry write
|
|
# tokens and secrets. That is dangerous in general, but this job is deliberately
|
|
# privilege-stripped so a malicious PR has nothing to steal or abuse:
|
|
# * permissions: contents: read only (no write scopes).
|
|
# * no `environment:`, so no environment secrets are exposed.
|
|
# * no repository/organization secrets are referenced anywhere in the job.
|
|
# * ruff is installed standalone via uv (`uv tool install`); we never run
|
|
# `uv sync` or install the PR's dependencies, so no PR-controlled build
|
|
# hooks or package metadata are executed.
|
|
# * ruff only statically parses the code (check + format --check); it never
|
|
# imports or executes it.
|
|
# * ALL tooling-install steps (setup-uv, uv tool install) run BEFORE the
|
|
# untrusted PR code is checked out, so no cache-writing ("poisonable") step
|
|
# ever runs with attacker-controlled files on disk. This is what prevents
|
|
# cache poisoning of the default branch (CodeQL
|
|
# actions/cache-poisoning/poisonable-step). Only ruff runs after checkout,
|
|
# and ruff writes no GitHub Actions cache.
|
|
#
|
|
# DO NOT add to this job: secrets, write permissions, an `environment:`, a
|
|
# `uv sync`/dependency install, `pytest`, or any step that executes PR code. Do
|
|
# NOT move the tooling-install steps after the checkout, and do NOT add a
|
|
# cache-writing step (e.g. actions/cache, `enable-cache` on setup-uv) after it.
|
|
# Type checking (pyright) and tests install/execute code and must stay on the
|
|
# approval-gated `pull_request` trigger in their own workflows.
|
|
on:
|
|
push:
|
|
branches: ["main"]
|
|
pull_request_target:
|
|
branches: ["main"]
|
|
|
|
# Cancel superseded lint runs on the same PR/branch to save runner time now that
|
|
# every fork push triggers a run automatically.
|
|
concurrency:
|
|
group: lint-${{ github.event.pull_request.number || github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
jobs:
|
|
ruff:
|
|
runs-on: depot-ubuntu-22.04
|
|
steps:
|
|
# Install tooling BEFORE checking out untrusted PR code (see SECURITY note).
|
|
- name: Install uv
|
|
uses: astral-sh/setup-uv@caf0cab7a618c569241d31dcd442f54681755d39 # v3
|
|
- name: Install Ruff
|
|
# Pin to the version locked in uv.lock so this job matches what
|
|
# `make lint` / `make format` produce locally. Bump in lockstep with
|
|
# uv.lock when ruff is upgraded.
|
|
run: uv tool install "ruff==0.14.11"
|
|
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
|
with:
|
|
# pull_request_target checks out the base ref by default; explicitly
|
|
# check out the PR head so we lint the contributor's changes.
|
|
ref: ${{ github.event.pull_request.head.sha || github.sha }}
|
|
fetch-depth: 1
|
|
persist-credentials: false
|
|
- name: Run Ruff linting
|
|
run: uv tool run ruff check --output-format=github
|
|
- name: Run Ruff format check
|
|
run: uv tool run ruff format --check
|