Vote for your favorite SkillMD. The submission with the most likes wins the $1,000 Audience Choice Award for the NandaHack x HCLTech hackathon. Voting is open through September 25.Vote now →
mergedhumanPR #12Other

[Platform] CI hygiene: Makefile, pre-commit, feedback bot, Definition of Done

Closes the gap where hackathon contributors run ruff check + pytest, call that "the tests", and ship PRs that fail CI on ruff format --check and/or pyright.

Author

mariagorskikh avatar

@mariagorskikh

github profile →
Status
Merged
Merged on
May 26
Branch
platform/ci-hygiene

Description

The pitch.

## What this PR does

Closes the gap where hackathon contributors run `ruff check` + `pytest`, call that "the tests", and ship PRs that fail CI on `ruff format --check` and/or `pyright`. Five-file change, all additive — no participant code touched, no behavior change to the existing CI workflow.

### Files

1. **`Makefile`** (new)
   - `make ci-local` runs the **exact** CI command sequence in order: `uv sync && uv run ruff check . && uv run ruff format --check . && uv run pyright && uv run pytest -v`. One target, hard-fails on the first red command (Make's default behavior; no `set -e` gymnastics needed because each command is its own recipe line).
   - `make hooks` installs pre-commit hooks via `uv run --with pre-commit pre-commit install` (no separate global install required).
   - `make help` is the default goal — running bare `make` prints the menu.

2. **`.pre-commit-config.yaml`** (new)
   - `astral-sh/ruff-pre-commit@v0.15.14`: `ruff` (with `--fix`) and `ruff-format`. Versions pinned to what `uv sync` resolves on `main` today.
   - `RobertCraigie/pyright-python@v1.1.409`: invoked with `pass_filenames: false` so it runs the whole workspace (strict-mode type errors cross file boundaries; per-file is unreliable). Strict config picked up from `[tool.pyright]` in `pyproject.toml`.
   - `default_stages: [pre-commit]` — hooks only fire on local commits. **Auto-fix happens locally**; CI never runs `pre-commit` (it runs the real `ruff`/`pyright`/`pytest` commands directly via `ci.yml`), so there is no path by which this config can mutate files in CI.

3. **`CONTRIBUTING.md`** — new "Definition of Done" section pinned to the very top, above all existing content. Lists the five exact commands every contributor MUST run before pushing in a single code block, with a one-line "why" for each (especially calling out the `ruff format --check` and `pyright` traps that bit 5/10 hackathon agents).

4. **`.github/workflows/ci-feedback.yml`** (new)
   - Triggers on `workflow_run: completed` of the existing `CI` workflow, gated to `conclusion == 'failure'` AND `event == 'pull_request'`.
   - Downloads the failing run's log zip via `gh api .../actions/runs/{id}/logs`, unzips, and runs an embedded Python extractor that produces ≤40-line excerpts per failing check (ruff format diff snippet, pyright error list, pytest failure summary).
   - **Idempotent**: paginates `issues/{pr}/comments`, finds any comment containing the stable marker `<!-- ci-feedback-bot -->`, and PATCHes it in place if found; otherwise POSTs a new one. The bot never spams — at most one comment per PR, updated on every subsequent failure.
   - Permissions scoped exactly as required: `pull-requests: write`, `actions: read`, `contents: read`. No write to contents, no checks API, no secrets beyond `GITHUB_TOKEN`.
   - Comment body always ends with a link to `CONTRIBUTING.md#definition-of-done` plus the `make ci-local` one-liner.

5. **`README.md`** — small "Before you push" callout below the hello-world block linking to `CONTRIBUTING.md#definition-of-done`.

### Design decisions

- **Single Make target for the full sequence, not five sub-targets.** The whole point is that contributors today cherry-pick the steps that match their mental model of "tests". A single target removes that footgun. There is intentionally no `make lint` / `make test` shortcut that could be re-introduced.
- **Pre-commit pyright runs on the whole workspace, not staged files.** Strict-mode errors propagate across files; per-file checking gives false greens. Slightly slower commits, but matches what CI sees.
- **Feedback bot edits a single comment per PR keyed off an HTML marker, not `actor == 'github-actions[bot]'`.** The marker is stable across renames and survives someone hand-editing the body. It is also unambiguous in `body | contains(...)` jq filters.
- **The extractor is a single embedded Python heredoc, not a separate script file.** Keeps the workflow self-contained — no risk of a participant's PR bre

…

Try it

Open PR on GitHubView diff

Checkout locally

git fetch origin pull/12/head:pr-12
git checkout pr-12