Skip to content

ENG-39: Add pull_request CI workflow to Red: Ruff gate, then pytest on 3.11 - #2

Merged
asinglesprinkle merged 1 commit into
masterfrom
eng-39/add-pull-request-ci-workflow-to-red-ruff-gate
Aug 3, 2026
Merged

asinglesprinkle merged 1 commit into
masterfrom
eng-39/add-pull-request-ci-workflow-to-red-ruff-gate

Conversation

@asinglesprinkle

Copy link
Copy Markdown
Owner

Closes ENG-39: Add pull_request CI workflow to Red: Ruff gate, then pytest on 3.11

Problem

cmichaelsd/Red has no .github/ directory at all, so pull requests get no automatic check. Maintainers only find out whether a branch lints and passes tests by pulling it locally. Forman is getting a Ruff + pytest pull-request workflow in a prior slice; Red needs the same one so both repos behave identically.

Acceptance criteria

  • A workflow file exists under .github/workflows/ in Red, mirroring the structure, step order and naming of the workflow that landed in cmichaelsd/Forman.
  • The workflow triggers on pull_request only — no push, no schedule, no workflow_dispatch.
  • Opening a pull request against Red starts a workflow run, and pushing a further commit to that open PR starts a fresh run.
  • The workflow sets up Python 3.11 exactly — a single version, a single runner, no matrix.
  • Dependencies are installed with pip install -e ".[dev]".
  • ruff check and ruff format --check run before the test step, and when either exits non-zero the pytest step does not execute at all (the job stops at the failing lint step).
  • When both Ruff steps pass, pytest runs from the repo root and its pass/fail is visible as a check on the PR.
  • The workflow references no secrets.* value and needs no API key or SSH key; installing the forman @ git+https://… pinned dependency works over unauthenticated https on a stock GitHub-hosted runner.
  • A no-op pull request against master is green end to end.

Context / pointers

Repo: cmichaelsd/Red, default branch master, working copy at /home/cole/Projects/Red; there is currently no .github/ directory. Read Forman's .github/workflows/ file first and copy its shape — the author wants one CI style across both repos, not two. Red's pyproject.toml already sets [tool.pytest.ini_options] with testpaths=["tests"] and pythonpath=["src"], so a bare pytest from the repo root is enough. Ruff must already be in the dev extra and the tree already clean — that is ticket 1, which must land first so this check starts green. The test run needs no secrets: tests/conftest.py has an autouse fixture that replaces claude_agent_sdk with a module raising on any attribute access, so no test can start a real agent session. The install step does need outbound network and git, because dependencies includes forman @ git+https://github.com/cmichaelsd/Forman@980b450008e145609808eee6587d6a49e39b62a3 (unauthenticated https, pinned commit); a GitHub-hosted runner provides both. README 'Development' documents pip install -e ".[dev]" then pytest.

Out of scope

Do not configure branch protection or mark this check as required to merge — deferred by the author. No multi-version or multi-OS matrix, no coverage measurement or reporting, no type checking (pyright stays out of CI even though pyrightconfig.json exists), no release/publish/build-artifact workflows, no Dependabot, auto-merge, PR labelling or other repo automation, no pre-commit hooks. Do not bump or alter the pinned Forman SHA in pyproject.toml. Do not change source, tests, or the Ruff configuration here — if the tree is not clean, that belongs to ticket 1. Do not touch cmichaelsd/Forman in this ticket.

Sub-tasks completed

ENG-39.01 Add Red's pull_request CI workflow under .github/workflows/, mirroring Forman's workflow file

Added /home/cole/Projects/Red/.github/workflows/ci.yml (name: CI): bare on: pull_request, single ubuntu-latest job, no matrix, steps checkout@v4 -> setup-python@v5 with python-version '3.11' -> pip install -e ".[dev]" -> ruff check -> ruff format --check -> pytest, with pytest last and unguarded so a Ruff failure ends the job. No secrets./env:/permissions wiring. Forman's workflow was genuinely unreachable — verified via contents API (404), recursive git tree, code search (0 hits), branch/PR list, Actions API (only the synthetic Dependabot dependency-graph entry) and a local Forman clone whose full history never contained .github — so per the brief I fell back to the ticket's step list and logged that. Note: a local Forman working copy does exist at /home/cole/Projects/Forman, contrary to the brief's note. Action version pins are my choice and should be reconciled if Forman's workflow lands later. Verified: secrets grep empty, YAML parses (top-level keys name/true/jobs, the expected on: boolean quirk), only that one file added under .github, and ruff check + ruff format --check + pytest all pass locally (87 tests).

ENG-39.02 Verify the gate is green locally and the workflow needs no secrets

Verified Red's CI gate locally in a throwaway Python 3.11.15 venv: pip install -e ".[dev]" (exit 0, resolved forman @ git+https at pinned SHA 980b450 over unauthenticated https with no credential helper/netrc/token), ruff check (exit 0), ruff format --check (exit 0, 19 files), and bare pytest (exit 0, 87 passed) run under unshare -rn with no network and all Linear/Anthropic env vars unset. pytest picked up configfile pyproject.toml + testpaths=tests, confirming the bare invocation works from the repo root. The four commands match the workflow's run: values byte for byte; the workflow greps clean for secrets./env:/token/ssh. Venv and helper scripts deleted, working tree unchanged apart from ENG-39.01's .github/. Caveats logged: local 3.11.15 is not necessarily the exact patch setup-python picks, and this does not exercise a real GitHub-hosted runner.


Opened by Forman. Not auto-merged: this PR and the ticket's in-review state are the human gate.

…ds nothing

Mirrors Forman's workflow: checkout, setup-python 3.11, `pip install -e
".[dev]"`, then `ruff check`, `ruff format --check` and `pytest` as three
separate steps so a failure names itself.

The four `run:` values are byte-for-byte the commands ENG-39.02 verified in
a throwaway Python 3.11.15 venv: all four exit 0, with `ruff check` clean,
19 files already formatted and 87 tests passing.

No secrets and no `permissions:` block. The pinned Forman dependency
resolves over unauthenticated https - verified with every Anthropic, Linear
and GitHub token unset, no credential helper and `GIT_TERMINAL_PROMPT=0` -
and the suite passes inside a fresh network namespace, so nothing in it
reaches the network.

Sub-tasks .01 and .02 land in one commit: .02 changed no files, it only
verified what .01 wrote.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@asinglesprinkle
asinglesprinkle merged commit 9c0c135 into master Aug 3, 2026
1 check passed
@asinglesprinkle
asinglesprinkle deleted the eng-39/add-pull-request-ci-workflow-to-red-ruff-gate branch August 3, 2026 02:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant