Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ If this PR introduces a new feature or changes existing behavior, describe the c

<!-- Please check the box(es) that apply to this PR. -->

- [ ] 🐛 Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] 💥 Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [ ] 📝 Documentation update (changes to `README.md`, `SUPPORT.md`, docstrings, etc.)
- [ ] 🛠️ Maintenance/Refactoring (non-breaking change that improves code structure or quality)
- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [ ] Documentation update (changes to `README.md`, `SUPPORT.md`, docstrings, etc.)
- [ ] Maintenance/Refactoring (non-breaking change that improves code structure or quality)

## Test Plan

Expand Down Expand Up @@ -52,7 +52,7 @@ please add screenshots, terminal output, or recordings to demonstrate the change

- [ ] Includes AI-assisted code completion
- [ ] Includes code generated by an AI application
- [ ] Includes AI-generated tests (NOTE: AI written tests should have a docstring that includes `## WRITTEN BY AI ##`)
- [ ] Includes AI-generated tests

## Checklist

Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/development.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,9 @@ jobs:
# ── Stage 3: Docs (Conditional) ────────────────────────────────────────────
docs:
name: "Build & Deploy Docs"
needs: changes
needs:
- changes
- tests
if: needs.changes.outputs.docs == 'true' && github.event.pull_request.head.repo.fork ==
false
uses: ./.github/workflows/_docs.yml
Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@ jobs:
# ── Stage 3: Documentation ─────────────────────────────────────────────────
docs:
name: "Build & Deploy Docs"
needs: quality
needs:
- quality
- tests
uses: ./.github/workflows/_docs.yml
with:
build_type: "dev"
Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,9 @@ jobs:
# ── Stage 4: Alpha Docs ────────────────────────────────────────────────────
docs:
name: "Nightly Docs"
needs: check-changes
needs:
- check-changes
- test
if: needs.check-changes.outputs.has_changes == 'true'
uses: ./.github/workflows/_docs.yml
with:
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ jobs:
# ── Stage 4: Versioned Docs ────────────────────────────────────────────────
docs:
name: "Versioned Docs"
needs: test
uses: ./.github/workflows/_docs.yml
with:
build_type: "release"
Expand Down
2 changes: 1 addition & 1 deletion CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ representative at an online or offline event.
> [!IMPORTANT]
> Instances of abusive, harassing, or otherwise unacceptable behavior may be
> reported to the community leaders responsible for enforcement by contacting
> **conduct@markurtz.com**.
> one of the project maintainers.
Comment thread
markurtz marked this conversation as resolved.

All complaints will be reviewed and investigated promptly and fairly.

Expand Down
2 changes: 0 additions & 2 deletions docs/community/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,5 +70,3 @@ Where to ask questions, report issues, and find help.
| :-------------------------------------------------------------------------- | :--------------------------------------------- |
| [GitHub Issues](https://github.com/markurtz/git-versioned/issues) | Bug reports and feature requests |
| [GitHub Discussions](https://github.com/markurtz/git-versioned/discussions) | Q&A, ideas, and general community conversation |
| [Slack](https://slack.markurtz.org) | Real-time chat with the team and community |
| [Blog](https://blog.markurtz.org) | Project updates, tutorials, and announcements |
2 changes: 0 additions & 2 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,5 +126,3 @@ For advanced installation options, Setuptools alternatives, and step-by-step onb

- :material-github: [GitHub Repository](https://github.com/markurtz/git-versioned)
- :material-map-marker-path: [Roadmap](https://github.com/markurtz/git-versioned/milestones)
- :material-post-outline: [Blog](https://blog.markurtz.org)
- :material-slack: [Slack Community](https://slack.markurtz.org)
18 changes: 0 additions & 18 deletions docs/reference/api.md

This file was deleted.

8 changes: 5 additions & 3 deletions docs/reference/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ ______________________________________________________________________

Auto-generated documentation for all public classes, methods, and modules.

[:octicons-arrow-right-24: Python API Reference](api.md)
[:octicons-arrow-right-24: Python API Reference](api/gitversioned/index.md)

</div>

Expand All @@ -33,9 +33,11 @@ All supported configuration file options, types, defaults, and examples.

______________________________________________________________________

Coverage reports are generated during CI/CD or locally.
Run `hatch run test:all-cov` to generate HTML reports locally, or view the latest pipeline runs:

Run `hatch run test:all-cov` to generate HTML reports in `docs/coverage/`.
- [:octicons-arrow-right-24: Unit Tests](../coverage/unit/htmlcov/index.html)
- [:octicons-arrow-right-24: Integration Tests](../coverage/integration/htmlcov/index.html)
- [:octicons-arrow-right-24: End-to-End Tests](../coverage/e2e/htmlcov/index.html)

</div>

Expand Down
76 changes: 76 additions & 0 deletions docs/scripts/gen_ref_pages.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# noqa: INP001
"""
Generate the code reference pages and navigation.

This module automates the creation of API reference documentation. It leverages the
``mkdocs-gen-files`` plugin to traverse the ``src/`` directory, generating Markdown
pages for each Python module and constructing a unified navigation structure. This
ensures the project's codebase remains fully documented and accessible.
"""

from pathlib import Path

import mkdocs_gen_files

__all__ = ["generate_api_reference"]


def generate_api_reference() -> None:
"""
Generate the API reference documentation and navigation structure.

Iterates through all Python source files in the ``src/`` directory, converting
their paths into a logical documentation structure. It generates Markdown files
with appropriate directives to render the API, and produces a literate navigation
summary.

Example:
This function is executed directly when the script is run:

.. code-block:: python

generate_api_reference()

:return: None
"""
navigation = mkdocs_gen_files.Nav()
root_directory = Path(__file__).parent.parent.parent
source_directory = root_directory / "src"
api_reference_path = Path("reference/api")

for python_file in sorted(source_directory.rglob("*.py")):
module_path = python_file.relative_to(source_directory).with_suffix("")
document_path = python_file.relative_to(source_directory).with_suffix(".md")
full_document_path = api_reference_path / document_path

path_parts = tuple(module_path.parts)

if path_parts[-1] == "__init__":
path_parts = path_parts[:-1]
document_path = document_path.with_name("index.md")
full_document_path = full_document_path.with_name("index.md")
elif path_parts[-1] == "__main__":
continue

if not path_parts:
continue

navigation[path_parts] = document_path.as_posix()

with mkdocs_gen_files.open(full_document_path, "w") as document_file:
identifier = ".".join(path_parts)
document_file.write(
f"::: {identifier}\n"
" options:\n"
" show_root_heading: true\n"
" show_source: true\n"
)

mkdocs_gen_files.set_edit_path(full_document_path, python_file)

summary_file_path = api_reference_path / "SUMMARY.md"
with mkdocs_gen_files.open(summary_file_path, "w") as navigation_file:
navigation_file.writelines(navigation.build_literate_nav())


generate_api_reference()
12 changes: 8 additions & 4 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,17 @@ edit_uri: edit/main/docs/
# All {{ variable }} references across the docs site are driven from here.
# ---------------------------------------------------------------------------
extra:
gitversioned: "gitversioned"
version:
provider: mike
project_name: "gitversioned"
project_description: "Opinionated PEP 440 Python versioning for Git repos and submodules.\
\ Enforces CI/User authority and generates rich version.py files with deep metadata for\
\ auditability. Native Hatch & Setuptools support. Simple, predictable, and foolproof\
\ automation."
org_name: "markurtz"
org_email: "conduct@markurtz.com"
docs_url: "https://markurtz.github.io/git-versioned"
min_python: "3.10"
current_major_version: "0"
slack_url: "https://slack.markurtz.org"
blog_url: "https://blog.markurtz.org"
roadmap_url: "https://github.com/markurtz/git-versioned/milestones"
theme:
name: material
Expand Down Expand Up @@ -102,6 +101,11 @@ markdown_extensions:
- toc:
permalink: true
plugins:
- gen-files:
scripts:
- docs/scripts/gen_ref_pages.py
- literate-nav:
nav_file: SUMMARY.md
- macros
- mike
- minify:
Expand Down
16 changes: 12 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@ readme = "README.md"
requires-python = ">=3.10"
license = { text = "Apache-2.0" }
authors = [{ name = "Mark Kurtz" }]
classifiers = [
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
]
dependencies = [
"loguru~=0.7",
"packaging>=26.0",
Expand Down Expand Up @@ -56,6 +64,8 @@ docs = [
"mike~=2.2",
"mkdocs~=1.6",
"mkdocstrings[python]~=1.0",
"mkdocs-gen-files~=0.5",
"mkdocs-literate-nav~=0.6",
"mkdocs-macros-plugin~=1.5",
"mkdocs-material~=9.7",
"mkdocs-minify-plugin~=0.8",
Expand All @@ -69,6 +79,7 @@ docs = [
Homepage = "https://github.com/markurtz/git-versioned"
Repository = "https://github.com/markurtz/git-versioned.git"
Issues = "https://github.com/markurtz/git-versioned/issues"
Documentation = "https://markurtz.github.io/git-versioned/"

[project.entry-points.hatch]
gitversioned = "gitversioned.plugins.hatchling_plugin"
Expand Down Expand Up @@ -298,10 +309,7 @@ asyncio_mode = "auto"
markers = [
"smoke: quick tests to check basic functionality",
"sanity: detailed tests to ensure major functions work correctly",
"regression: tests to ensure that new changes do not break existing functionality",
"e2e: end-to-end integration tests",
"unit: unit tests",
"integration: integration tests"
"regression: tests to ensure that new changes do not break existing functionality"
]
Comment thread
markurtz marked this conversation as resolved.
testpaths = ["tests"]

Expand Down
2 changes: 1 addition & 1 deletion src/gitversioned/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,6 @@
__version__: Annotated[
str,
"The current version of the gitversioned package as a PEP 440 compliant string",
] = "0.1.1"
] = "0.1.2"

configure_logger()
84 changes: 84 additions & 0 deletions tests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# Testing Guide

This directory contains the testing suite for `gitversioned`. We use `pytest` as our testing framework and `hatch` to manage test environments and execution.

## Test Tiers

Tests are categorized into three distinct tiers, each located in its respective subdirectory:

| Test Tier | Directory | Description |
| :-------------- | :------------------- | :------------------------------------------------------------------------------------------------------------------------ |
| **Unit** | `tests/unit/` | Fast, isolated tests for individual functions and classes. These tests should not rely on external services or databases. |
| **Integration** | `tests/integration/` | Slower tests that verify interactions between multiple components or modules within the application. |
| **End-to-End** | `tests/e2e/` | Full-stack tests simulating real user workflows, from entry points to expected outcomes. |

## Pytest Markers

We use custom `pytest` markers to categorize test scope and intent. Every test should be decorated with appropriate markers.

| Marker | Purpose | Example Use Case |
| :------------------------ | :-------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------- |
| `@pytest.mark.smoke` | Quick tests to check basic functionality. | A crucial happy-path test that must pass for the system to be considered fundamentally operational. |
| `@pytest.mark.sanity` | Detailed tests to ensure major functions work correctly. | Testing key business logic and typical user flows. |
| `@pytest.mark.regression` | Tests to ensure that new changes do not break existing functionality. | Tests written specifically to prevent known bugs from reoccurring. |

> [!NOTE]
> Every test should be decorated with one of the above markers to indicate its role in the testing pipeline.

## Running Tests

We recommend using `hatch` to run tests, as it automatically manages the required virtual environments and dependencies.

### Standard Test Runs

```bash
# Run all tests
hatch run test:all

# Run only unit tests
hatch run test:unit

# Run tests with a specific marker
hatch run test:all -m "smoke"

# Run tests in a specific file
hatch run test:all tests/unit/test_version.py
```

### Coverage Reports

To generate coverage reports, use the `-cov` suffixed commands. These will output both a terminal report and an HTML report located in `docs/coverage/`.

```bash
# Run all tests with coverage
hatch run test:all-cov

# Run only unit tests with coverage
hatch run test:unit-cov
```

## Adding New Tests

When creating new tests, ensure they are placed in the appropriate tier directory (`unit/`, `integration/`, or `e2e/`) and include the necessary markers.

### Example Unit Test

```python
"""Unit tests for my_module."""

from __future__ import annotations

import pytest

from gitversioned import my_module


@pytest.mark.smoke
def test_my_function() -> None:
"""Verify my_function behaves as expected."""
result = my_module.my_function()
assert result is True
```

> [!TIP]
> **Type Hints:** Ensure all test functions are fully type-hinted (e.g., `-> None:` for test return types) to satisfy our strict `mypy` configuration.
Loading