diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..82509b8 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,47 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + +permissions: + contents: read + +jobs: + validate: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6.0.2 + + - uses: actions/setup-python@v6.2.0 + with: + python-version: "3.12" + cache: pip + cache-dependency-path: apps/api/pyproject.toml + + - uses: pnpm/action-setup@v5.0.0 + + - uses: actions/setup-node@v6.3.0 + with: + node-version-file: ".nvmrc" + cache: pnpm + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Install API dev dependencies + working-directory: apps/api + run: .venv/bin/python -m pip install -e ".[dev]" + + - name: Lint + run: pnpm lint + + - name: Test + run: pnpm test + + - name: Generate OpenAPI code + run: pnpm openapi:generate + + - name: Validate generated OpenAPI code matches the repo + run: pnpm openapi:validate diff --git a/.github/workflows/validate-openapi.yml b/.github/workflows/validate-openapi.yml deleted file mode 100644 index 8c78159..0000000 --- a/.github/workflows/validate-openapi.yml +++ /dev/null @@ -1,27 +0,0 @@ -name: Validate OpenAPI - -on: - push: - branches: [main] - pull_request: - -jobs: - openapi: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6.0.2 - - - uses: pnpm/action-setup@v5.0.0 - with: - version: 10.18.1 - - - uses: actions/setup-node@v6.3.0 - with: - node-version-file: ".nvmrc" - cache: pnpm - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Lint OpenAPI spec - run: pnpm --filter @solid-pact/openapi run lint diff --git a/PLAN.md b/PLAN.md index 97d8471..85c6da8 100644 --- a/PLAN.md +++ b/PLAN.md @@ -19,7 +19,7 @@ Tasks and subtasks for building the bread-recipes app (SolidJS + Python REST + O - [x] **3.2** Implement a data-access abstraction and a static implementation (files under repo) so swapping to DB/CMS later does not reshape route handlers. - [x] **3.3** Wire FastAPI/OpenAPI **`info`** (title, version, description) from **`packages/openapi/openapi.yaml`** so the running app matches the committed spec and those values are not duplicated in code (e.g. `main.py`). - [x] **3.4** Implement REST handlers to match the OpenAPI spec (response shapes and status codes); keep behaviour aligned with the spec. -- [ ] **3.5** Generate Pydantic models from **`packages/openapi/openapi.yaml`** (e.g. **datamodel-code-generator**), commit generated output, and add CI that fails when the spec changes without regenerating (drift check). +- [x] **3.5** Generate Pydantic models from **`packages/openapi/openapi.yaml`** (e.g. **datamodel-code-generator**), commit generated output, and add CI that fails when the spec changes without regenerating (drift check). - [ ] **3.6** Tests with 100% coverage and a coverage gate in CI for the API package; add `README.md` for install, run, and test commands. - [ ] **3.7** Select and configure a Python import-ordering tool (PEP 8–aligned; e.g. **Ruff**’s isort rules or **isort**), apply it across **`apps/api`**, and document how to run it (CI enforcement can align with §3.6 / §6.1). diff --git a/README.md b/README.md index 019ea0f..d3a4f65 100644 --- a/README.md +++ b/README.md @@ -10,13 +10,9 @@ You can work in other editors, but Cursor is the intended environment. ## OpenAPI contract -The REST API is defined in **`packages/openapi/openapi.yaml`** (shared by the Python API and the front end). Lint it with **[Redocly](https://redocly.com/docs/cli/)** from the repo root: +The REST API is defined in **`packages/openapi/openapi.yaml`** (shared by the Python API and the front end). From the repository root, **`pnpm lint`** runs **[Redocly](https://redocly.com/docs/cli/)** on that spec (via **`@solid-pact/openapi`**) together with the other workspace lint tasks. -```bash -pnpm --filter @solid-pact/openapi run lint -``` - -The **Validate OpenAPI** workflow (`.github/workflows/validate-openapi.yml`) runs that command on pushes to `main` and on every pull request. +The **CI** workflow (`.github/workflows/ci.yml`) runs **`pnpm lint`**, **`pnpm test`**, **`pnpm openapi:generate`**, and **`pnpm openapi:validate`** (among the other setup steps) on pushes to `main` and on every pull request. When you add or upgrade Node dependencies, run **`pnpm install`** with the **pnpm** version pinned in **`packageManager`** (via Corepack). Using a different pnpm release can rewrite **`pnpm-lock.yaml`** in an incompatible way (for example changing the lockfile format). @@ -65,10 +61,10 @@ pnpm build pnpm dev pnpm lint pnpm test +pnpm openapi:generate +pnpm openapi:validate ``` -(`pnpm run