diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 37491ad..eacff08 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,10 +17,10 @@ jobs: - name: Checkout code uses: actions/checkout@v6 - - name: Set up Python 3.12 + - name: Set up Python uses: actions/setup-python@v6 with: - python-version: "3.14" + python-version: "3.13" cache: 'pip' - name: Install dependencies @@ -44,10 +44,10 @@ jobs: - name: Checkout code uses: actions/checkout@v6 - - name: Set up Python 3.12 + - name: Set up Python uses: actions/setup-python@v6 with: - python-version: "3.14" + python-version: "3.13" cache: 'pip' - name: Install dependencies @@ -67,10 +67,10 @@ jobs: - name: Checkout code uses: actions/checkout@v6 - - name: Set up Python 3.12 + - name: Set up Python uses: actions/setup-python@v6 with: - python-version: "3.14" + python-version: "3.13" cache: 'pip' - name: Install dependencies @@ -94,10 +94,10 @@ jobs: - name: Checkout code uses: actions/checkout@v6 - - name: Set up Python 3.12 + - name: Set up Python uses: actions/setup-python@v6 with: - python-version: "3.14" + python-version: "3.13" cache: 'pip' - name: Install dependencies diff --git a/TEMPLATE.md b/TEMPLATE.md new file mode 100644 index 0000000..cf8cff7 --- /dev/null +++ b/TEMPLATE.md @@ -0,0 +1,59 @@ +# Template Instantiation Checklist + +This repo is a **fork-and-edit** Python project template. After forking, walk +through each item below before opening your first real PR. + +## 1. Project identity (`pyproject.toml`) + +Replace every `REPLACE_ME` token: + +- `name = "REPLACE_ME-project-name"` → kebab-case PyPI distribution name +- `authors = [{name = "REPLACE_ME Author", email = "replace-me@example.com"}]` +- `description = "REPLACE_ME — short project description"` +- `[tool.ruff.lint.isort] known-first-party = ["hello_world"]` → + match your actual package directory under `src/` + +## 2. Rename the package + +```bash +git mv src/hello_world src/ +``` + +- Update any imports in `tests/` and elsewhere from `hello_world` to your + package name. +- Update package-level metadata in `src//__init__.py`: + `__author__`, `__email__`, and `__version__` are currently hardcoded + with the template author's information and must be replaced. + +## 3. Update README + +- Replace `python-template` references with your project name +- Replace the example `hello_world` import/run snippets +- Update the badge URLs (replace `JacobPEvans/python-template` with + `/`) +- Fix the Codecov token in the coverage badge (or remove it until you wire + up Codecov for the new repo) + +## 4. CI workflows (`.github/workflows/`) + +- `ci.yml` and `tests.yml` reference `JacobPEvans/python-template` in the + Codecov `slug:` — replace with `/` +- Confirm the Python `matrix` in `tests.yml` matches the versions you want + to support; the single-version jobs in `ci.yml` use the latest released + stable (`3.13`) — bump when you upgrade + +## 5. Strip template scaffolding + +Once everything is renamed and CI is green on your fork, delete this file: + +```bash +git rm TEMPLATE.md +git commit -m "chore: remove template instantiation checklist" +``` + +## Why fork-and-edit instead of Cookiecutter? + +The template doubles as a working repo for its own CI (linting, type checks, +security scans, coverage gating). Cookiecutter-style placeholders would +break that — the repo itself wouldn't be installable or testable. Fork +copies the working state; you edit it in place. diff --git a/pyproject.toml b/pyproject.toml index 93ecea8..2deebd8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,14 +2,16 @@ requires = ["setuptools>=61.0"] build-backend = "setuptools.build_meta" +# TEMPLATE: After forking, replace the placeholders below. +# See TEMPLATE.md for the full instantiation checklist. [project] -name = "hello-world" +name = "REPLACE_ME-project-name" version = "0.1.0" license = {text = "Apache-2.0"} authors = [ - {name = "Your Name", email = "your.email@example.com"}, + {name = "REPLACE_ME Author", email = "replace-me@example.com"}, ] -description = "A simple Python project template" +description = "REPLACE_ME — short project description" readme = "README.md" requires-python = ">=3.11" classifiers = [ @@ -26,7 +28,6 @@ dev = [ "mypy>=1.16.1", # Security "bandit[toml]>=1.8.0", - "safety>=3.0.0", # Testing "pytest>=8.4.1", "pytest-cov>=6.2.0", @@ -203,6 +204,7 @@ convention = "google" max-complexity = 10 [tool.ruff.lint.isort] +# TEMPLATE: replace "hello_world" with the actual package name (matches src//). known-first-party = ["hello_world"] force-single-line = false lines-after-imports = 2 diff --git a/requirements-dev.txt b/requirements-dev.txt index a6b0a7c..5686d34 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -10,7 +10,6 @@ mypy>=1.16.1 # Security bandit[toml]>=1.8.0 -safety>=3.0.0 pip-audit>=2.7.0 # Testing