diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml index 3280138f3b..2cb4843405 100644 --- a/.github/workflows/deploy-docs.yml +++ b/.github/workflows/deploy-docs.yml @@ -36,13 +36,8 @@ jobs: - name: Install uv uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 - run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV - - name: Install dependencies - run: uv pip install -e ".[dask,ibis]" --group docs - - name: Run hooks manually - run: | - python utils/generate_backend_completeness.py - python utils/generate_zen_content.py - - run: zensical build --clean + - name: Build docs + run: make docs-build - uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0 with: path: site diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index 4ebb0ae7f8..3d4424056e 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -82,11 +82,11 @@ jobs: cache-suffix: pytest-full-coverage-${{ matrix.python-version }} cache-dependency-glob: "pyproject.toml" - name: Run pytest - run: make run-ci DEPS="--extra pandas --extra dask --group core-tests --group sklearn --group plugins" CMD="pytest tests --cov=src --cov=tests --cov-fail-under=100 --runslow --durations=30 --constructors=pandas,pandas[nullable],pandas[pyarrow],pyarrow,polars[eager],polars[lazy],dask,duckdb,sqlframe" + run: make test-full-coverage - name: Run doctests # reprs differ between versions, so we only run doctests on the latest Python if: matrix.python-version == '3.13' - run: make run-ci DEPS="--extra pandas --extra dask --group core-tests --group sklearn" CMD="pytest src --doctest-modules" + run: make doctest # Test against smaller dependency set, used e.g. on Gentoo. pytest-narrower-dependencies: diff --git a/AGENTS.md b/AGENTS.md index 0066890f53..0f816534bc 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -134,14 +134,14 @@ make typing-coverage that catches missing `# pragma: no cover`): ```bash -PYTEST_ADDOPTS="--numprocesses=logical" make run-ci DEPS="--extra pandas --extra dask --group core-tests --group sklearn --group plugins" CMD="pytest tests --cov=src --cov=tests --cov-fail-under=100 --runslow --durations=30 --constructors=pandas,pandas[nullable],pandas[pyarrow],pyarrow,polars[eager],polars[lazy],dask,duckdb,sqlframe" +make test-full-coverage ``` **4. Doctests** (docstring examples are executed; reprs differ across versions, so CI only runs these on the latest Python): ```bash -make run-ci DEPS="--extra pandas --extra dask --group core-tests --group sklearn" CMD="pytest src --doctest-modules" +make doctest ``` **5. Docs build**, if you touched anything under `docs/` or any docstring. The build *executes* the @@ -151,8 +151,9 @@ make run-ci DEPS="--extra pandas --extra dask --group core-tests --group sklearn make docs-build ``` -To preview instead of just building: `make docs-serve` (or `make docs-clean-serve` if it does not -refresh). Docs are built with `zensical` (configured in [zensical.toml](zensical.toml)), not mkdocs +To preview instead of just building: `make docs-clean-serve` (or plain `make docs-serve` for a +quicker preview without the clean rebuild). +Docs are built with `zensical` (configured in [zensical.toml](zensical.toml)), not mkdocs — the nav lives there, so a new page must be added to it. ### Faster inner loop diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a3557dd894..8371f3eba2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -14,7 +14,8 @@ If you've got experience with open source contributions, the following instructi - `uv sync --group local-dev` (creates `.venv` and installs project + dev deps) - Install prek as a git hook: `uv run prek install` - To run tests: `uv run pytest` -- To run all linting checks: `make lint` +- To run ruff formatting and linting: `make lint` +- To run all pre-commit checks (which include ruff): `uv run prek run --all-files` - To run static typing checks: `make typing` For more detailed and beginner-friendly instructions, see below! @@ -332,6 +333,8 @@ The docs should refresh when you make changes. If they don't, press `ctrl+C`, an make docs-clean-serve ``` +which rebuilds everything from a clean state (via `make docs-build`) before serving. + ### 10. Pull requests When you have resolved your issue, [open a pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork) in the Narwhals repository. diff --git a/Makefile b/Makefile index cc26ab7200..2eb3c8201a 100644 --- a/Makefile +++ b/Makefile @@ -23,25 +23,39 @@ typing: ## Run type checkers typing-coverage: ## Run type checkers uv run --group typing pyrefly coverage check src/narwhals --public-only -.PHONY: docs-build -docs-build: ## Build the docs locally - uv run --group docs zensical build --clean +.PHONY: docs-dynamic-content +docs-dynamic-content: ## Regenerate the dynamic docs pages (API completeness tables, docs/this.md, ...) uv run --group docs --extra dask --extra ibis utils/generate_backend_completeness.py uv run --group docs utils/generate_zen_content.py - uv run --group docs zensical build --strict + +.PHONY: docs-build +docs-build: ## Build the docs from a clean state, failing on warnings + $(MAKE) docs-dynamic-content + uv run --group docs zensical build --clean --strict .PHONY: docs-serve -docs-serve: ## Build and serve the docs locally - uv run --group docs --extra dask --extra ibis utils/generate_backend_completeness.py - uv run --group docs utils/generate_zen_content.py +docs-serve: ## Serve the docs locally + $(MAKE) docs-dynamic-content uv run --group docs zensical serve .PHONY: docs-clean-serve docs-clean-serve: ## Rebuild docs from a clean state and serve them locally - uv run --group docs zensical build --clean - $(MAKE) docs-serve + $(MAKE) docs-build + uv run --group docs zensical serve .PHONY: run-ci run-ci: ## Print resolved deps, then run a command via uv. Usage: make run-ci DEPS="" CMD="" [RUN_ONLY=""] uv export --no-annotate --no-hashes $(DEPS) uv run $(DEPS) $(RUN_ONLY) $(CMD) + +.PHONY: doctest +doctest: ## Run doctests + make run-ci \ + DEPS="--extra pandas --extra dask --group core-tests --group sklearn" \ + CMD="pytest src --doctest-modules" + +.PHONY: test-full-coverage +test-full-coverage: ## Run the full test suite with 100% coverage across all constructors as in CI + PYTEST_ADDOPTS="--numprocesses=logical" make run-ci \ + DEPS="--extra pandas --extra dask --group core-tests --group sklearn --group plugins" \ + CMD="pytest tests --cov=src --cov=tests --cov-fail-under=100 --runslow --durations=30 --constructors=pandas,pandas[nullable],pandas[pyarrow],pyarrow,polars[eager],polars[lazy],dask,duckdb,sqlframe"