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
16 changes: 8 additions & 8 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down
59 changes: 59 additions & 0 deletions TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -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/<your_package_name>
```

- Update any imports in `tests/` and elsewhere from `hello_world` to your
package name.
- Update package-level metadata in `src/<your_package_name>/__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
`<your-org>/<your-repo>`)
- 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 `<your-org>/<your-repo>`
- 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.
10 changes: 6 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 = [
Expand All @@ -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",
Expand Down Expand Up @@ -203,6 +204,7 @@ convention = "google"
max-complexity = 10

[tool.ruff.lint.isort]
# TEMPLATE: replace "hello_world" with the actual package name (matches src/<package>/).
known-first-party = ["hello_world"]
force-single-line = false
lines-after-imports = 2
Expand Down
1 change: 0 additions & 1 deletion requirements-dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ mypy>=1.16.1

# Security
bandit[toml]>=1.8.0
safety>=3.0.0
pip-audit>=2.7.0

# Testing
Expand Down