From aed6bb433358dcd706b65bf9254325e6896a4700 Mon Sep 17 00:00:00 2001 From: Alexis Date: Wed, 2 Apr 2025 10:31:23 +0200 Subject: [PATCH 01/20] Use groups --- {{cookiecutter.project_slug}}/Makefile | 2 +- {{cookiecutter.project_slug}}/pyproject.toml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/{{cookiecutter.project_slug}}/Makefile b/{{cookiecutter.project_slug}}/Makefile index 4f99666..49b2e49 100644 --- a/{{cookiecutter.project_slug}}/Makefile +++ b/{{cookiecutter.project_slug}}/Makefile @@ -53,7 +53,7 @@ run: $(VENV)/pyvenv.cfg $(VENV)/pyvenv.cfg: pyproject.toml uv venv $(VENV) - uv pip install -e '.[$(INSTALL_EXTRA)]' + uv sync --group '$(INSTALL_EXTRA)' .PHONY: lint lint: $(VENV)/pyvenv.cfg diff --git a/{{cookiecutter.project_slug}}/pyproject.toml b/{{cookiecutter.project_slug}}/pyproject.toml index 8231f0f..27e66e4 100644 --- a/{{cookiecutter.project_slug}}/pyproject.toml +++ b/{{cookiecutter.project_slug}}/pyproject.toml @@ -23,7 +23,7 @@ requires-python = ">=3.9" [tool.setuptools.dynamic] version = { attr = "{{ cookiecutter.__project_import }}.__version__" } -[project.optional-dependencies] +[dependency-groups] doc = [ {%- if cookiecutter.documentation == "pdoc" -%} "pdoc" @@ -42,7 +42,7 @@ lint = [ "interrogate", {%- endif %} ] -dev = ["{{ cookiecutter.project_slug }}[doc,test,lint]", "twine", "build"] +dev = [{include-group = "doc"}, {include-group = "test"}, {include-group = "lint"}, "twine", "build"] {% if cookiecutter.entry_point -%} [project.scripts] From 0c002341760fe262c9f06016a929b9bca9d973d1 Mon Sep 17 00:00:00 2001 From: Alexis Date: Wed, 2 Apr 2025 17:55:52 +0200 Subject: [PATCH 02/20] Fix selftest --- {{cookiecutter.project_slug}}/pyproject.toml | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/pyproject.toml b/{{cookiecutter.project_slug}}/pyproject.toml index 27e66e4..0e3b4a5 100644 --- a/{{cookiecutter.project_slug}}/pyproject.toml +++ b/{{cookiecutter.project_slug}}/pyproject.toml @@ -20,6 +20,13 @@ classifiers = [ dependencies = [] requires-python = ">=3.9" +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[tool.hatch.version] +path = "{{ cookiecutter.__project_src_path }}/__init__.py" + [tool.setuptools.dynamic] version = { attr = "{{ cookiecutter.__project_import }}.__version__" } @@ -42,7 +49,14 @@ lint = [ "interrogate", {%- endif %} ] -dev = [{include-group = "doc"}, {include-group = "test"}, {include-group = "lint"}, "twine", "build"] +dev = [ + {include-group = "doc"}, + {include-group = "test"}, + {include-group = "lint"}, + "twine", + "build", + "{{ cookiecutter.project_slug }}", +] {% if cookiecutter.entry_point -%} [project.scripts] @@ -108,3 +122,6 @@ exclude = ["env", "test", "{{ cookiecutter.__project_src_path }}/_cli.py"] ignore-semiprivate = true fail-under = 100 {%- endif %} + +[tool.uv.sources] +{{ cookiecutter.project_slug }} = { workspace = true } \ No newline at end of file From f4ded9cb112bd73cd25afc8e9e517ac87631e23d Mon Sep 17 00:00:00 2001 From: Alexis Date: Wed, 2 Apr 2025 18:16:56 +0200 Subject: [PATCH 03/20] Add hatch build targets --- {{cookiecutter.project_slug}}/pyproject.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/{{cookiecutter.project_slug}}/pyproject.toml b/{{cookiecutter.project_slug}}/pyproject.toml index 0e3b4a5..5595f00 100644 --- a/{{cookiecutter.project_slug}}/pyproject.toml +++ b/{{cookiecutter.project_slug}}/pyproject.toml @@ -27,6 +27,9 @@ build-backend = "hatchling.build" [tool.hatch.version] path = "{{ cookiecutter.__project_src_path }}/__init__.py" +[tool.hatch.build.targets.wheel] +packages = ["{{ cookiecutter.__project_src_path }}"] + [tool.setuptools.dynamic] version = { attr = "{{ cookiecutter.__project_import }}.__version__" } From d5439a9dbd50f97b251b3ddd08997e8bfdbdcdc5 Mon Sep 17 00:00:00 2001 From: Alexis Date: Wed, 2 Apr 2025 18:36:12 +0200 Subject: [PATCH 04/20] Fix selftest? --- cookiecutter.json | 1 + {{cookiecutter.project_slug}}/pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/cookiecutter.json b/cookiecutter.json index 8d61f41..3f0da15 100644 --- a/cookiecutter.json +++ b/cookiecutter.json @@ -7,6 +7,7 @@ "project_slug": "{{ (cookiecutter.__project_namespace_slug + '-' if cookiecutter.project_namespace_import else '') + cookiecutter.__module_slug }}", "__project_import": "{{ (cookiecutter.project_namespace_import + '.' if cookiecutter.project_namespace_import else '') + cookiecutter.__module_import }}", "__project_src_path": "src/{{ cookiecutter.__project_import.replace('.', '/') }}", + "__project_src_first": "{{ ('src/' + cookiecutter.project_namespace_import.split('.')[0] if cookiecutter.project_namespace_import else 'src/' + cookiecutter.__module_import) }}", "project_description": "", "repo_type": [ "CLI", diff --git a/{{cookiecutter.project_slug}}/pyproject.toml b/{{cookiecutter.project_slug}}/pyproject.toml index 5595f00..e11fa0e 100644 --- a/{{cookiecutter.project_slug}}/pyproject.toml +++ b/{{cookiecutter.project_slug}}/pyproject.toml @@ -28,7 +28,7 @@ build-backend = "hatchling.build" path = "{{ cookiecutter.__project_src_path }}/__init__.py" [tool.hatch.build.targets.wheel] -packages = ["{{ cookiecutter.__project_src_path }}"] +packages = ["{{ cookiecutter.__project_src_first }}"] [tool.setuptools.dynamic] version = { attr = "{{ cookiecutter.__project_import }}.__version__" } From fbe292eac5fe73c245eb68dca29f364285db6e48 Mon Sep 17 00:00:00 2001 From: William Tan <1284324+Ninja3047@users.noreply.github.com> Date: Sat, 30 Aug 2025 19:07:40 -0400 Subject: [PATCH 05/20] bump ruff version --- {{cookiecutter.project_slug}}/pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/pyproject.toml b/{{cookiecutter.project_slug}}/pyproject.toml index 684c5c5..21d5c62 100644 --- a/{{cookiecutter.project_slug}}/pyproject.toml +++ b/{{cookiecutter.project_slug}}/pyproject.toml @@ -45,7 +45,7 @@ test = ["pytest", "pytest-cov", "pretend", "coverage[toml]"] lint = [ # NOTE: ruff is under active development, so we pin conservatively here # and let Dependabot periodically perform this update. - "ruff ~= 0.6.2", + "ruff ~= 0.12", "mypy >= 1.0", "types-html5lib", "types-requests", From dca8e19b8270a733eef1e88960f35c7b1504ff48 Mon Sep 17 00:00:00 2001 From: William Tan <1284324+Ninja3047@users.noreply.github.com> Date: Sat, 30 Aug 2025 19:07:40 -0400 Subject: [PATCH 06/20] exclude /.github in source dist --- {{cookiecutter.project_slug}}/pyproject.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/{{cookiecutter.project_slug}}/pyproject.toml b/{{cookiecutter.project_slug}}/pyproject.toml index 21d5c62..603460b 100644 --- a/{{cookiecutter.project_slug}}/pyproject.toml +++ b/{{cookiecutter.project_slug}}/pyproject.toml @@ -32,6 +32,9 @@ path = "{{ cookiecutter.__project_src_path }}/__init__.py" [tool.hatch.build.targets.wheel] packages = ["{{ cookiecutter.__project_src_first }}"] +[tool.hatch.build.targets.sdist] +exclude = ["/.github"] + [tool.setuptools.dynamic] version = { attr = "{{ cookiecutter.__project_import }}.__version__" } From 9e1fbc579a0a3e7efb8041831a022e6dfc63154f Mon Sep 17 00:00:00 2001 From: William Tan <1284324+Ninja3047@users.noreply.github.com> Date: Sat, 30 Aug 2025 19:07:40 -0400 Subject: [PATCH 07/20] posix newline --- {{cookiecutter.project_slug}}/pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/pyproject.toml b/{{cookiecutter.project_slug}}/pyproject.toml index 603460b..3a6d75c 100644 --- a/{{cookiecutter.project_slug}}/pyproject.toml +++ b/{{cookiecutter.project_slug}}/pyproject.toml @@ -132,4 +132,4 @@ fail-under = 100 {%- endif %} [tool.uv.sources] -{{ cookiecutter.project_slug }} = { workspace = true } \ No newline at end of file +{{ cookiecutter.project_slug }} = { workspace = true } From adc4a0b417a4d033b748e2a4fad3e172d03d69a4 Mon Sep 17 00:00:00 2001 From: William Tan <1284324+Ninja3047@users.noreply.github.com> Date: Sat, 30 Aug 2025 19:07:40 -0400 Subject: [PATCH 08/20] update zizmor workflow to use the github actions --- .../.github/workflows/zizmor.yml | 22 +++++-------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/{{cookiecutter.project_slug}}/.github/workflows/zizmor.yml b/{{cookiecutter.project_slug}}/.github/workflows/zizmor.yml index 117672b..0352cb2 100644 --- a/{{cookiecutter.project_slug}}/.github/workflows/zizmor.yml +++ b/{{cookiecutter.project_slug}}/.github/workflows/zizmor.yml @@ -10,28 +10,16 @@ permissions: {} jobs: zizmor: - name: zizmor latest via PyPI runs-on: ubuntu-latest permissions: - security-events: write # needed by upload-sarif for all repositories - contents: read # needed by upload-sarif for private repositories - actions: read # needed by upload-sarif for private repositories + security-events: write + contents: read # only needed for private repos + actions: read # only needed for private repos steps: - name: Checkout repository - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: persist-credentials: false - - name: Install the latest version of uv - uses: astral-sh/setup-uv@445689ea25e0de0a23313031f5fe577c74ae45a1 # v6.3.0 - - name: Run zizmor 🌈 - run: uvx zizmor --format sarif . > results.sarif - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Upload SARIF file - uses: github/codeql-action/upload-sarif@ce28f5bb42b7a9f2c824e633a3f6ee835bab6858 # v3.29.0 - with: - sarif_file: results.sarif - category: zizmor + uses: zizmorcore/zizmor-action@5ca5fc7a4779c5263a3ffa0e1f693009994446d1 # v0.1.2 From 26121f7ada996a9703a881a207b34adc36c0642b Mon Sep 17 00:00:00 2001 From: William Tan <1284324+Ninja3047@users.noreply.github.com> Date: Sat, 30 Aug 2025 19:07:40 -0400 Subject: [PATCH 09/20] drop python 3.9, add 3.13 --- {{cookiecutter.project_slug}}/.github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/.github/workflows/tests.yml b/{{cookiecutter.project_slug}}/.github/workflows/tests.yml index 890b651..82467d1 100644 --- a/{{cookiecutter.project_slug}}/.github/workflows/tests.yml +++ b/{{cookiecutter.project_slug}}/.github/workflows/tests.yml @@ -13,10 +13,10 @@ jobs: strategy: matrix: python: - - "3.9" - "3.10" - "3.11" - "3.12" + - "3.13" runs-on: ubuntu-latest steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 From 97f5813c22da1f2ce5405b4450be2f434cf794b6 Mon Sep 17 00:00:00 2001 From: William Tan <1284324+Ninja3047@users.noreply.github.com> Date: Sat, 30 Aug 2025 19:07:40 -0400 Subject: [PATCH 10/20] use uv github action to setup python version --- {{cookiecutter.project_slug}}/.github/workflows/tests.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/{{cookiecutter.project_slug}}/.github/workflows/tests.yml b/{{cookiecutter.project_slug}}/.github/workflows/tests.yml index 82467d1..00d68e2 100644 --- a/{{cookiecutter.project_slug}}/.github/workflows/tests.yml +++ b/{{cookiecutter.project_slug}}/.github/workflows/tests.yml @@ -25,9 +25,8 @@ jobs: - name: Install uv uses: astral-sh/setup-uv@445689ea25e0de0a23313031f5fe577c74ae45a1 # v6.3.0 - - - name: Install Python ${{ matrix.python }} - run: uv python install ${{ matrix.python }} + with: + python-version: ${{ matrix.python }} - name: test run: make test INSTALL_EXTRA=test From f839f8a71db37b9f0c70e260ce042e7e5ee0184e Mon Sep 17 00:00:00 2001 From: William Tan <1284324+Ninja3047@users.noreply.github.com> Date: Sat, 30 Aug 2025 19:07:40 -0400 Subject: [PATCH 11/20] switch dependabot to track uv instead of pip --- {{cookiecutter.project_slug}}/.github/dependabot.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/.github/dependabot.yml b/{{cookiecutter.project_slug}}/.github/dependabot.yml index 99d80f9..f3d7b30 100644 --- a/{{cookiecutter.project_slug}}/.github/dependabot.yml +++ b/{{cookiecutter.project_slug}}/.github/dependabot.yml @@ -1,7 +1,7 @@ version: 2 updates: - - package-ecosystem: pip + - package-ecosystem: uv directory: / groups: python: From d65138518910076b8ef4ea43a1981aafe4026c34 Mon Sep 17 00:00:00 2001 From: William Tan <1284324+Ninja3047@users.noreply.github.com> Date: Sat, 30 Aug 2025 19:07:40 -0400 Subject: [PATCH 12/20] remove edit target --- {{cookiecutter.project_slug}}/Makefile | 7 ------- 1 file changed, 7 deletions(-) diff --git a/{{cookiecutter.project_slug}}/Makefile b/{{cookiecutter.project_slug}}/Makefile index 49b2e49..470526a 100644 --- a/{{cookiecutter.project_slug}}/Makefile +++ b/{{cookiecutter.project_slug}}/Makefile @@ -2,9 +2,6 @@ SHELL := /bin/bash PY_IMPORT = {{ cookiecutter.__project_import }} -ALL_PY_SRCS := $(shell find src -name '*.py') \ - $(shell find test -name '*.py') - # Optionally overriden by the user, if they're using a virtual environment manager. # Warning: changing this name to something else than '.venv' will make working with # uv harder. @@ -87,7 +84,3 @@ doc: .PHONY: package package: $(VENV)/pyvenv.cfg uv build - -.PHONY: edit -edit: - $(EDITOR) $(ALL_PY_SRCS) From d0cc120679e5b0105f0ba5869586935f39371584 Mon Sep 17 00:00:00 2001 From: William Tan <1284324+Ninja3047@users.noreply.github.com> Date: Sat, 30 Aug 2025 19:07:40 -0400 Subject: [PATCH 13/20] remove complicated venv management from Makefile uv does all this stuff automatically already uv run also installs the dev group by default so there's no need to make it configurable --- .github/workflows/tests.yml | 5 --- .../.github/workflows/docs.yml | 4 -- .../.github/workflows/lint.yml | 2 +- .../.github/workflows/tests.yml | 2 +- {{cookiecutter.project_slug}}/Makefile | 37 +++---------------- 5 files changed, 8 insertions(+), 42 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 94657e8..2f3aa52 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -35,7 +35,6 @@ jobs: cd /tmp/python-project git init . && git add . && git commit -m "Initial commit" - make dev make reformat git diff --exit-code || { >&2 echo "please reformat"; exit 1; } @@ -54,7 +53,6 @@ jobs: cd /tmp/python-project git init . && git add . && git commit -m "Initial commit" - make dev make reformat git diff --exit-code || { >&2 echo "please reformat"; exit 1; } @@ -73,7 +71,6 @@ jobs: cd /tmp/tob-r-and-e-python-project git init . && git add . && git commit -m "Initial commit" - make dev make reformat git diff --exit-code || { >&2 echo "please reformat"; exit 1; } @@ -92,7 +89,6 @@ jobs: cd /tmp/bit-trails git init . && git add . && git commit -m "Initial commit" - make dev make reformat git diff --exit-code || { >&2 echo "please reformat"; exit 1; } @@ -112,7 +108,6 @@ jobs: cd /tmp/python-project git init . && git add . && git commit -m "Initial commit" - make dev make reformat git diff --exit-code || { >&2 echo "please reformat"; exit 1; } diff --git a/{{cookiecutter.project_slug}}/.github/workflows/docs.yml b/{{cookiecutter.project_slug}}/.github/workflows/docs.yml index b230de0..5a6af9d 100644 --- a/{{cookiecutter.project_slug}}/.github/workflows/docs.yml +++ b/{{cookiecutter.project_slug}}/.github/workflows/docs.yml @@ -18,10 +18,6 @@ jobs: - name: Install uv uses: astral-sh/setup-uv@445689ea25e0de0a23313031f5fe577c74ae45a1 # v6.3.0 - - name: setup - run: | - make dev INSTALL_EXTRA=doc - - name: build docs run: | make doc diff --git a/{{cookiecutter.project_slug}}/.github/workflows/lint.yml b/{{cookiecutter.project_slug}}/.github/workflows/lint.yml index 6bddd64..a3eeaa0 100644 --- a/{{cookiecutter.project_slug}}/.github/workflows/lint.yml +++ b/{{cookiecutter.project_slug}}/.github/workflows/lint.yml @@ -20,4 +20,4 @@ jobs: uses: astral-sh/setup-uv@445689ea25e0de0a23313031f5fe577c74ae45a1 # v6.3.0 - name: lint - run: make lint INSTALL_EXTRA=lint + run: make lint diff --git a/{{cookiecutter.project_slug}}/.github/workflows/tests.yml b/{{cookiecutter.project_slug}}/.github/workflows/tests.yml index 00d68e2..bfa4161 100644 --- a/{{cookiecutter.project_slug}}/.github/workflows/tests.yml +++ b/{{cookiecutter.project_slug}}/.github/workflows/tests.yml @@ -29,4 +29,4 @@ jobs: python-version: ${{ matrix.python }} - name: test - run: make test INSTALL_EXTRA=test + run: make test diff --git a/{{cookiecutter.project_slug}}/Makefile b/{{cookiecutter.project_slug}}/Makefile index 470526a..b824cf0 100644 --- a/{{cookiecutter.project_slug}}/Makefile +++ b/{{cookiecutter.project_slug}}/Makefile @@ -2,27 +2,9 @@ SHELL := /bin/bash PY_IMPORT = {{ cookiecutter.__project_import }} -# Optionally overriden by the user, if they're using a virtual environment manager. -# Warning: changing this name to something else than '.venv' will make working with -# uv harder. -VENV ?= .venv - -# On Windows, venv scripts/shims are under `Scripts` instead of `bin`. -VENV_BIN := $(VENV)/bin -ifeq ($(OS),Windows_NT) - VENV_BIN := $(VENV)/Scripts -endif - -# Optionally overridden by the user in the `release` target. -BUMP_ARGS := - # Optionally overridden by the user in the `test` target. TESTS := -# Optionally overridden by the user/CI, to limit the installation to a specific -# subset of development dependencies. -INSTALL_EXTRA := dev - # If the user selects a specific test pattern to run, set `pytest` to fail fast # and only run tests that match the pattern. # Otherwise, run all tests and enable coverage assertions, since we expect @@ -39,21 +21,14 @@ endif all: @echo "Run my targets individually!" -.PHONY: dev -dev: $(VENV)/pyvenv.cfg - {%- if cookiecutter.entry_point %} .PHONY: run -run: $(VENV)/pyvenv.cfg +run: uv run {{ cookiecutter.entry_point }} $(ARGS) {%- endif %} -$(VENV)/pyvenv.cfg: pyproject.toml - uv venv $(VENV) - uv sync --group '$(INSTALL_EXTRA)' - .PHONY: lint -lint: $(VENV)/pyvenv.cfg +lint: uv run ruff format --check && \ uv run ruff check && \ uv run mypy @@ -67,14 +42,14 @@ reformat: uv run ruff format && \ uv run ruff check --fix -.PHONY: test tests -test tests: $(VENV)/pyvenv.cfg +.PHONY: test +test: uv run pytest --cov=$(PY_IMPORT) $(T) $(TEST_ARGS) uv run coverage report -m $(COV_ARGS) .PHONY: doc {%- if cookiecutter.documentation == 'pdoc' %} -doc: $(VENV)/pyvenv.cfg +doc: uv run pdoc -o html $(PY_IMPORT) {%- elif cookiecutter.documentation == 'none' %} doc: @@ -82,5 +57,5 @@ doc: {%- endif %} .PHONY: package -package: $(VENV)/pyvenv.cfg +package: uv build From 6de1e812b800ac82799d26b0d20d980453d11ebf Mon Sep 17 00:00:00 2001 From: William Tan <1284324+Ninja3047@users.noreply.github.com> Date: Sat, 30 Aug 2025 19:07:40 -0400 Subject: [PATCH 14/20] rename reformat target to format this makes it more consistant with uv and other build tools --- .github/workflows/tests.yml | 20 +++++++++---------- .../.github/workflows/release.yml | 2 +- {{cookiecutter.project_slug}}/Makefile | 4 ++-- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 2f3aa52..f4c58d9 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -35,9 +35,9 @@ jobs: cd /tmp/python-project git init . && git add . && git commit -m "Initial commit" - make reformat + make format - git diff --exit-code || { >&2 echo "please reformat"; exit 1; } + git diff --exit-code || { >&2 echo "please format"; exit 1; } make lint make test @@ -53,9 +53,9 @@ jobs: cd /tmp/python-project git init . && git add . && git commit -m "Initial commit" - make reformat + make format - git diff --exit-code || { >&2 echo "please reformat"; exit 1; } + git diff --exit-code || { >&2 echo "please format"; exit 1; } make lint make test @@ -71,9 +71,9 @@ jobs: cd /tmp/tob-r-and-e-python-project git init . && git add . && git commit -m "Initial commit" - make reformat + make format - git diff --exit-code || { >&2 echo "please reformat"; exit 1; } + git diff --exit-code || { >&2 echo "please format"; exit 1; } make lint make test @@ -89,9 +89,9 @@ jobs: cd /tmp/bit-trails git init . && git add . && git commit -m "Initial commit" - make reformat + make format - git diff --exit-code || { >&2 echo "please reformat"; exit 1; } + git diff --exit-code || { >&2 echo "please format"; exit 1; } make lint make test @@ -108,9 +108,9 @@ jobs: cd /tmp/python-project git init . && git add . && git commit -m "Initial commit" - make reformat + make format - git diff --exit-code || { >&2 echo "please reformat"; exit 1; } + git diff --exit-code || { >&2 echo "please format"; exit 1; } make lint make test diff --git a/{{cookiecutter.project_slug}}/.github/workflows/release.yml b/{{cookiecutter.project_slug}}/.github/workflows/release.yml index 65b94a3..174dc0c 100644 --- a/{{cookiecutter.project_slug}}/.github/workflows/release.yml +++ b/{{cookiecutter.project_slug}}/.github/workflows/release.yml @@ -20,7 +20,7 @@ jobs: uses: astral-sh/setup-uv@445689ea25e0de0a23313031f5fe577c74ae45a1 # v6.3.0 - name: Build distributions - run: uv build + run: make build - name: Upload distributions uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 diff --git a/{{cookiecutter.project_slug}}/Makefile b/{{cookiecutter.project_slug}}/Makefile index b824cf0..d1b42be 100644 --- a/{{cookiecutter.project_slug}}/Makefile +++ b/{{cookiecutter.project_slug}}/Makefile @@ -37,8 +37,8 @@ lint: uv run interrogate -c pyproject.toml . {%- endif %} -.PHONY: reformat -reformat: +.PHONY: format +format: uv run ruff format && \ uv run ruff check --fix From cc00bcd07e813841af856938ec932cbd4cbc28c7 Mon Sep 17 00:00:00 2001 From: William Tan <1284324+Ninja3047@users.noreply.github.com> Date: Sat, 30 Aug 2025 19:07:40 -0400 Subject: [PATCH 15/20] rename package target to build this makes it more consistent with uv and other build tools --- .github/workflows/tests.yml | 10 +++++----- {{cookiecutter.project_slug}}/Makefile | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index f4c58d9..9df8084 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -41,7 +41,7 @@ jobs: make lint make test - make package + make build make doc cd .. && rm -rf /tmp/python-project @@ -59,7 +59,7 @@ jobs: make lint make test - make package + make build make doc cd .. && rm -rf /tmp/python-project @@ -77,7 +77,7 @@ jobs: make lint make test - make package + make build make doc cd .. && rm -rf /tmp/tob-r-and-e-python-project @@ -95,7 +95,7 @@ jobs: make lint make test - make package + make build make doc cd .. && rm -rf /tmp/bit-trails @@ -114,6 +114,6 @@ jobs: make lint make test - make package + make build make doc cd .. && rm -rf /tmp/python-project diff --git a/{{cookiecutter.project_slug}}/Makefile b/{{cookiecutter.project_slug}}/Makefile index d1b42be..fae43d4 100644 --- a/{{cookiecutter.project_slug}}/Makefile +++ b/{{cookiecutter.project_slug}}/Makefile @@ -56,6 +56,6 @@ doc: @echo "No documentation set up" {%- endif %} -.PHONY: package -package: +.PHONY: build +build: uv build From a09128c58d3c9cfa71b95120c1e89da0db88470f Mon Sep 17 00:00:00 2001 From: William Tan <1284324+Ninja3047@users.noreply.github.com> Date: Mon, 1 Sep 2025 13:50:59 -0400 Subject: [PATCH 16/20] switch to uv_build build backend also use pyproject.toml as single source of truth for version since uv does not support dynamic attribute --- {{cookiecutter.project_slug}}/pyproject.toml | 23 +++++++------------ .../__init__.py | 4 +++- 2 files changed, 11 insertions(+), 16 deletions(-) diff --git a/{{cookiecutter.project_slug}}/pyproject.toml b/{{cookiecutter.project_slug}}/pyproject.toml index 3a6d75c..e4af0da 100644 --- a/{{cookiecutter.project_slug}}/pyproject.toml +++ b/{{cookiecutter.project_slug}}/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "{{ cookiecutter.project_slug }}" -dynamic = ["version"] +version = "{{ cookiecutter.version }}" description = "{{ cookiecutter.project_description }}" readme = "README.md" license-files = ["LICENSE"] @@ -23,20 +23,8 @@ dependencies = [] requires-python = ">=3.9" [build-system] -requires = ["hatchling"] -build-backend = "hatchling.build" - -[tool.hatch.version] -path = "{{ cookiecutter.__project_src_path }}/__init__.py" - -[tool.hatch.build.targets.wheel] -packages = ["{{ cookiecutter.__project_src_first }}"] - -[tool.hatch.build.targets.sdist] -exclude = ["/.github"] - -[tool.setuptools.dynamic] -version = { attr = "{{ cookiecutter.__project_import }}.__version__" } +requires = ["uv_build>=0.8.14,<0.9.0"] +build-backend = "uv_build" [dependency-groups] doc = [ @@ -133,3 +121,8 @@ fail-under = 100 [tool.uv.sources] {{ cookiecutter.project_slug }} = { workspace = true } + +{%- if cookiecutter.project_namespace_import %} +[tool.uv.build-backend] +module-name = "{{ cookiecutter.__project_import }}" +{%- endif %} diff --git a/{{cookiecutter.project_slug}}/src/{{cookiecutter.__module_import}}/__init__.py b/{{cookiecutter.project_slug}}/src/{{cookiecutter.__module_import}}/__init__.py index 5ae53f4..7c4677d 100644 --- a/{{cookiecutter.project_slug}}/src/{{cookiecutter.__module_import}}/__init__.py +++ b/{{cookiecutter.project_slug}}/src/{{cookiecutter.__module_import}}/__init__.py @@ -1,3 +1,5 @@ """The `{{ cookiecutter.project_slug }}` APIs.""" -__version__ = "{{ cookiecutter.version }}" +import importlib.metadata + +__version__ = importlib.metadata.version("{{ cookiecutter.project_slug }}") From 4a9d8f18db2e92e2c291267ced1b1e37862f5621 Mon Sep 17 00:00:00 2001 From: William Tan <1284324+Ninja3047@users.noreply.github.com> Date: Mon, 1 Sep 2025 13:50:59 -0400 Subject: [PATCH 17/20] bump minimum python version to 3.10 in pyproject.toml --- {{cookiecutter.project_slug}}/pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/pyproject.toml b/{{cookiecutter.project_slug}}/pyproject.toml index e4af0da..3ffc569 100644 --- a/{{cookiecutter.project_slug}}/pyproject.toml +++ b/{{cookiecutter.project_slug}}/pyproject.toml @@ -20,7 +20,7 @@ classifiers = [ "Programming Language :: Python :: 3", ] dependencies = [] -requires-python = ">=3.9" +requires-python = ">=3.10" [build-system] requires = ["uv_build>=0.8.14,<0.9.0"] From 25092141c4d787a078933ce328a6d7761434fd55 Mon Sep 17 00:00:00 2001 From: William Tan <1284324+Ninja3047@users.noreply.github.com> Date: Mon, 1 Sep 2025 13:50:59 -0400 Subject: [PATCH 18/20] remove unecessary/unused dev dependencies. --- {{cookiecutter.project_slug}}/pyproject.toml | 3 --- 1 file changed, 3 deletions(-) diff --git a/{{cookiecutter.project_slug}}/pyproject.toml b/{{cookiecutter.project_slug}}/pyproject.toml index 3ffc569..868dacd 100644 --- a/{{cookiecutter.project_slug}}/pyproject.toml +++ b/{{cookiecutter.project_slug}}/pyproject.toml @@ -49,9 +49,6 @@ dev = [ {include-group = "doc"}, {include-group = "test"}, {include-group = "lint"}, - "twine", - "build", - "{{ cookiecutter.project_slug }}", ] {% if cookiecutter.entry_point -%} From 41e47ea541e91eeacf4f9b10388a8b3c9a9ec29c Mon Sep 17 00:00:00 2001 From: William Tan <1284324+Ninja3047@users.noreply.github.com> Date: Tue, 9 Sep 2025 14:11:04 -0400 Subject: [PATCH 19/20] remove extra unused variable --- cookiecutter.json | 1 - 1 file changed, 1 deletion(-) diff --git a/cookiecutter.json b/cookiecutter.json index 3f0da15..8d61f41 100644 --- a/cookiecutter.json +++ b/cookiecutter.json @@ -7,7 +7,6 @@ "project_slug": "{{ (cookiecutter.__project_namespace_slug + '-' if cookiecutter.project_namespace_import else '') + cookiecutter.__module_slug }}", "__project_import": "{{ (cookiecutter.project_namespace_import + '.' if cookiecutter.project_namespace_import else '') + cookiecutter.__module_import }}", "__project_src_path": "src/{{ cookiecutter.__project_import.replace('.', '/') }}", - "__project_src_first": "{{ ('src/' + cookiecutter.project_namespace_import.split('.')[0] if cookiecutter.project_namespace_import else 'src/' + cookiecutter.__module_import) }}", "project_description": "", "repo_type": [ "CLI", From 856c54c4b6cc86fba809a432f57f639daa7dda20 Mon Sep 17 00:00:00 2001 From: William Tan <1284324+Ninja3047@users.noreply.github.com> Date: Wed, 10 Sep 2025 10:36:49 -0400 Subject: [PATCH 20/20] update zizmor workflow for repo --- .github/workflows/zizmor.yml | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml index b93239a..0352cb2 100644 --- a/.github/workflows/zizmor.yml +++ b/.github/workflows/zizmor.yml @@ -10,27 +10,16 @@ permissions: {} jobs: zizmor: - name: zizmor latest via PyPI runs-on: ubuntu-latest permissions: - security-events: write # needed by upload-sarif for all repositories + security-events: write + contents: read # only needed for private repos + actions: read # only needed for private repos steps: - name: Checkout repository uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: persist-credentials: false - - name: Install the latest version of uv - uses: astral-sh/setup-uv@557e51de59eb14aaaba2ed9621916900a91d50c6 # v6.6.1 - - name: Run zizmor 🌈 - # Run it for both this repo and the templated cookiecutter repo. - run: uvx zizmor --format sarif . {{cookiecutter.project_slug}}/.github/workflows > results.sarif - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Upload SARIF file - uses: github/codeql-action/upload-sarif@f1f6e5f6af878fb37288ce1c627459e94dbf7d01 # v3.29.5 - with: - sarif_file: results.sarif - category: zizmor + uses: zizmorcore/zizmor-action@5ca5fc7a4779c5263a3ffa0e1f693009994446d1 # v0.1.2