From 26d0c4f2eda466dee198736bbc3761df062ed393 Mon Sep 17 00:00:00 2001 From: michplunkett <5885605+michplunkett@users.noreply.github.com> Date: Fri, 23 Jan 2026 15:49:35 -0600 Subject: [PATCH 01/10] Update Makefile --- Makefile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index bbbb0a3..67879b9 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ # Here is some general information on Makefile's so that you can grow this out: # https://www.gnu.org/software/make/manual/html_node/Introduction.html -.DEFAULT_GOAL := lint +.DEFAULT_GOAL := format .PHONY: env env: @@ -8,14 +8,14 @@ env: .PHONY: install install: - uv pip install -r pyproject.toml + uv sync .PHONY: create-requirements create-requirements: uv pip compile --generate-hashes pyproject.toml > requirements.txt -.PHONY: lint -lint: create-requirements +.PHONY: format +format: create-requirements pre-commit run --all-files .PHONY: test From d0fda162463868da46643ae977a26843dce0b1ab Mon Sep 17 00:00:00 2001 From: michplunkett <5885605+michplunkett@users.noreply.github.com> Date: Fri, 23 Jan 2026 15:50:09 -0600 Subject: [PATCH 02/10] Update .pre-commit-config.yaml --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 9f16c96..ea87ea5 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -45,7 +45,7 @@ repos: - id: python-no-log-warn - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.14.11 + rev: v0.14.14 hooks: - id: ruff-check types_or: [python,pyi] From 1d2d342a18525c6ae2f560fd6c84b0dd5f6df227 Mon Sep 17 00:00:00 2001 From: michplunkett <5885605+michplunkett@users.noreply.github.com> Date: Fri, 23 Jan 2026 15:50:11 -0600 Subject: [PATCH 03/10] Update README.md --- README.md | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 4840805..2c5b522 100644 --- a/README.md +++ b/README.md @@ -2,26 +2,41 @@ This repository is a template for a python 🐍 project using the `uv` container. The intent is to do all the basic lifting for a python project so that people can hit the ground running with their ideas. -### To make this project your own +## Required Post-templating Changes 1. Create a new repository, [using this one as a template](https://docs.github.com/en/repositories/creating-and-managing-repositories/creating-a-repository-from-a-template). 2. Change the `project` folder name to the kebab-case name of your project. 3. Update the information in the `pyproject.toml` file with your project's and your personal information. 4. Update the information in the `CODEOWNERS` file so that it uses your GitHub ID and the kebab-case name of your project folder. -### 🐍 by Default (Feel free to delete this after creating your project) +## Default 🐍 Packages - [pre-commit](https://pre-commit.com/): This serves as the codebase formatter and linter. - [requests](https://requests.readthedocs.io/en/latest/): This is the project's means of communicating with external APIs. - [responses](https://github.com/getsentry/responses): This is used in conjunction with Pytest and Requests to mock API calls in the test module. -### Project Requirements -- `uv` version: `0.5.7` +## Pull Request Requirements + +If any of the following conditions are not met the respective GitHub Action will +fail, and you will not be able to merge. Please do not mark your PR as `Open` for +review until all GitHub Actions are passing. + +- All PR titles must be in the present imperative tense. + - **Examples:** "Fix issue in the dispatcher where…", "Improve our handling of…", + - For more information on Pull Requests, you can reference here: [PRs to Contribute](https://success.vanillaforums.com/kb/articles/228-using-pull-requests-to-contribute). +- Code in PRs must be properly formatted. + +If your PR is not ready for review for whatever reason, please mark it as a +draft: [PR Draft](https://github.blog/news-insights/product-news/introducing-draft-pull-requests/). + +## Project Requirements +- `uv` version: `0.9.26` - Download at: [link](https://docs.astral.sh/uv/). -### Instructions to Run the Project -1. Go into the base directory of the repository and type `make env` or `uv env` into the terminal. -2. Use the `make run` command. +## Instructions to Run the Project +1. Go into the base directory of the repository and type `make env` into the terminal. +2. Enter `source .venv/bin/activate` to access the environment. +3. Use the `make run` command. -### Technical Notes +## Technical Notes - Any modules should be added via the `uv add [module]` command. - Example: `uv add pre-commit` From 4b673335298b3b070021e2bbca63bcf1f8a0accc Mon Sep 17 00:00:00 2001 From: michplunkett <5885605+michplunkett@users.noreply.github.com> Date: Fri, 23 Jan 2026 15:50:59 -0600 Subject: [PATCH 04/10] Create check-pr-title.yml --- .github/workflows/check-pr-title.yml | 100 +++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 .github/workflows/check-pr-title.yml diff --git a/.github/workflows/check-pr-title.yml b/.github/workflows/check-pr-title.yml new file mode 100644 index 0000000..b25ce1f --- /dev/null +++ b/.github/workflows/check-pr-title.yml @@ -0,0 +1,100 @@ +name: Check-PR-Title + +on: + pull_request: + types: + - opened + - edited + - synchronize + - reopened + +jobs: + title-check: + runs-on: ubuntu-latest + steps: + - name: Enforce imperative subject (heuristic) + uses: actions/github-script@v7 + with: + script: | + const title = context.payload.pull_request.title; + + // ----------------------------- + // 1) Imperative heuristic + // ----------------------------- + const bannedStarts = new Set([ + "Added", "Adding", "Adds", + "Fixed", "Fixes", "Fixing", + "Updated", "Updating", "Updates", + "Changed", "Changing", "Changes", + "Removed", "Removing", "Removes", + "Refactored", "Refactoring", + "Improved", "Improving", + "Implemented", "Implementing", "Implements", + "Created", "Creating", "Creates", + "Renamed", "Renaming", "Renames", + "Moved", "Moving", "Moves", + "Deleted", "Deleting", "Deletes", + "Reverted", "Reverting", "Reverts", + "Bumped", "Bumping", "Bumps", + "Upgraded", "Upgrading", "Upgrades", + "Downgraded", "Downgrading", "Downgrades", + "Pinned", "Pinning", "Pins", + "Resolved", "Resolving", "Resolves", + "Corrected", "Correcting", "Corrects", + "Addressed", "Addressing", "Addresses", + "Patched", "Patching", "Patches", + "Cleaned", "Cleaning", "Cleans", + "Formatted", "Formatting", "Formats", + "Linted", "Linting", "Lints", + "Sorted", "Sorting", "Sorts", + "Documented", "Documenting", "Documents", + "Tested", "Testing", "Tests", + "Optimized", "Optimizing", "Optimizes", + "Enhanced", "Enhancing", "Enhances", + "Simplified", "Simplifying", "Simplifies", + "Adjusted", "Adjusting", "Adjusts", + "Modified", "Modifying", "Modifies", + ]); + + const firstWord = title.split(/\s+/)[0]; + if (bannedStarts.has(firstWord)) { + core.setFailed( + `PR title subject should be present imperative. ` + + `Avoid "${firstWord} …". Example: "Add …", "Fix …", "Update …".` + ); + } + + // ----------------------------- + // 2) Allow leading emojis, but: + // - Reject WIP prefixes + // - Require first "real" word to start uppercase + // ----------------------------- + const trimmed = title.trim(); + + // Reject WIP at the start (optionally wrapped in [] or () and optionally followed by ":" or "-") + if (/^\s*[\[(]?\s*wip\s*[\])]?(\s*[:\-–—])?/i.test(trimmed)) { + core.setFailed(`PR title must not be WIP.`); + } + + // Find the first letter-starting word, allowing leading non-letters (e.g., emojis, punctuation) + const match = trimmed.match(/[A-Za-z][A-Za-z0-9'’]*/); + + if (!match) { + core.setFailed(`PR title must contain a word.`); + } else { + const firstRealWord = match[0]; + const firstChar = firstRealWord[0]; + + if (firstChar !== firstChar.toUpperCase()) { + const suggested = + trimmed.replace( + firstRealWord, + firstChar.toUpperCase() + firstRealWord.slice(1) + ); + + core.setFailed( + `PR title must start with a capitalized word (emojis are fine). ` + + `Example: "${suggested}"` + ); + } + } From 9adc8af44919699e8412f2368a509682906a5c73 Mon Sep 17 00:00:00 2001 From: michplunkett <5885605+michplunkett@users.noreply.github.com> Date: Fri, 23 Jan 2026 15:51:37 -0600 Subject: [PATCH 05/10] Update CODEOWNERS --- CODEOWNERS => .github/CODEOWNERS | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename CODEOWNERS => .github/CODEOWNERS (100%) diff --git a/CODEOWNERS b/.github/CODEOWNERS similarity index 100% rename from CODEOWNERS rename to .github/CODEOWNERS From a5cf58c9a5b427459d3681a3b233cbf6eef01711 Mon Sep 17 00:00:00 2001 From: michplunkett <5885605+michplunkett@users.noreply.github.com> Date: Fri, 23 Jan 2026 15:51:44 -0600 Subject: [PATCH 06/10] Update pull_request_template.md --- .github/pull_request_template.md | 7 ------- 1 file changed, 7 deletions(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 9d1ba93..e53128b 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,10 +1,3 @@ - ## Describe your changes From 9909254383b46834ccb2e37e8dcba09c037dedfa Mon Sep 17 00:00:00 2001 From: michplunkett <5885605+michplunkett@users.noreply.github.com> Date: Fri, 23 Jan 2026 15:56:15 -0600 Subject: [PATCH 07/10] Update requirements.txt --- requirements.txt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/requirements.txt b/requirements.txt index e75e75a..7f5fa1a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -131,9 +131,9 @@ filelock==3.20.3 \ --hash=sha256:18c57ee915c7ec61cff0ecf7f0f869936c7c30191bb0cf406f1341778d0834e1 \ --hash=sha256:4b0dda527ee31078689fc205ec4f1c1bf7d56cf88b6dc9426c4f230e46c2dce1 # via virtualenv -identify==2.6.15 \ - --hash=sha256:1181ef7608e00704db228516541eb83a88a9f94433a8c80bb9b5bd54b1d81757 \ - --hash=sha256:e4f4864b96c6557ef2a1e1c951771838f4edc9df3a72ec7118b338801b11c7bf +identify==2.6.16 \ + --hash=sha256:391ee4d77741d994189522896270b787aed8670389bfd60f326d677d64a6dfb0 \ + --hash=sha256:846857203b5511bbe94d5a352a48ef2359532bc8f6727b5544077a0dcfb24980 # via pre-commit idna==3.11 \ --hash=sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea \ @@ -147,9 +147,9 @@ nodeenv==1.10.0 \ --hash=sha256:5bb13e3eed2923615535339b3c620e76779af4cb4c6a90deccc9e36b274d3827 \ --hash=sha256:996c191ad80897d076bdfba80a41994c2b47c68e224c542b48feba42ba00f8bb # via pre-commit -packaging==25.0 \ - --hash=sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484 \ - --hash=sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f +packaging==26.0 \ + --hash=sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4 \ + --hash=sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529 # via pytest platformdirs==4.5.1 \ --hash=sha256:61d5cdcc6065745cdd94f0f878977f8de9437be93de97c1c12f853c9c0cdcbda \ From c7358ebee4b823a52aac5e0c3ab5505720e8cd1c Mon Sep 17 00:00:00 2001 From: michplunkett <5885605+michplunkett@users.noreply.github.com> Date: Fri, 23 Jan 2026 15:56:19 -0600 Subject: [PATCH 08/10] Update .pre-commit-config.yaml --- .pre-commit-config.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ea87ea5..a736ccc 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -51,12 +51,12 @@ repos: types_or: [python,pyi] args: - --fix - - --target-version=py311 - - --select=B,C,E,F,W,B9,I + - --target-version=py312 + - --select=B,C,E,F,W,I,ERA,N,RUF - --line-length=80 - - --ignore=E203,E402,E501,E261 + - --ignore=E261,E501 - id: ruff-format types_or: [ python,pyi] args: - - --target-version=py311 + - --target-version=py312 - --line-length=80 From 6e061f31a66f82a221d40e3199b9f628a8598c77 Mon Sep 17 00:00:00 2001 From: michplunkett <5885605+michplunkett@users.noreply.github.com> Date: Fri, 23 Jan 2026 15:56:26 -0600 Subject: [PATCH 09/10] Update python version --- .github/workflows/format-and-fail.yml | 2 +- .github/workflows/run-tests.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/format-and-fail.yml b/.github/workflows/format-and-fail.yml index 843da13..559591d 100644 --- a/.github/workflows/format-and-fail.yml +++ b/.github/workflows/format-and-fail.yml @@ -12,5 +12,5 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-python@v4 with: - python-version: "3.11" + python-version: "3.12" - uses: pre-commit/action@v3.0.0 diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index ba73c53..d862336 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -10,14 +10,14 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [ '3.11', '3.12', '3.13' ] + python-version: [ '3.12', '3.13' ] steps: - uses: actions/checkout@v4 - name: Install uv uses: astral-sh/setup-uv@v4 with: - version: 0.5.7 + version: 0.9.26 - name: Set up Python run: uv python install ${{ matrix.python-version }} From 90da4a16ecb236ab52446a80213eb73b33905a9f Mon Sep 17 00:00:00 2001 From: michplunkett <5885605+michplunkett@users.noreply.github.com> Date: Fri, 23 Jan 2026 15:58:45 -0600 Subject: [PATCH 10/10] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2c5b522..520052c 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,6 @@ draft: [PR Draft](https://github.blog/news-insights/product-news/introducing-dra ## Standard Commands - `make create-requirements`: Creates and/or updates the `requirements.txt` file. - `make env`: Creates a `uv` virtual environment. -- `make lint`: Runs `pre-commit`. +- `make format`: Runs `pre-commit`. - `make run`: Runs the `main` function in the `project` folder. - `make test`: Runs test cases in the `tests` directory.