toolbelt-cli 0.2.0__tar.gz → 0.2.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. {toolbelt_cli-0.2.0 → toolbelt_cli-0.2.2}/CHANGELOG.md +13 -0
  2. {toolbelt_cli-0.2.0 → toolbelt_cli-0.2.2}/PKG-INFO +98 -114
  3. toolbelt_cli-0.2.2/README.md +328 -0
  4. {toolbelt_cli-0.2.0 → toolbelt_cli-0.2.2}/pyproject.toml +1 -1
  5. {toolbelt_cli-0.2.0 → toolbelt_cli-0.2.2}/src/toolbelt/__init__.py +1 -1
  6. {toolbelt_cli-0.2.0 → toolbelt_cli-0.2.2}/src/toolbelt/commands/version.py +1 -1
  7. {toolbelt_cli-0.2.0 → toolbelt_cli-0.2.2}/src/toolbelt_cli.egg-info/PKG-INFO +98 -114
  8. toolbelt_cli-0.2.0/README.md +0 -344
  9. {toolbelt_cli-0.2.0 → toolbelt_cli-0.2.2}/.env.example +0 -0
  10. {toolbelt_cli-0.2.0 → toolbelt_cli-0.2.2}/LICENSE +0 -0
  11. {toolbelt_cli-0.2.0 → toolbelt_cli-0.2.2}/MANIFEST.in +0 -0
  12. {toolbelt_cli-0.2.0 → toolbelt_cli-0.2.2}/assets/demo.png +0 -0
  13. {toolbelt_cli-0.2.0 → toolbelt_cli-0.2.2}/setup.cfg +0 -0
  14. {toolbelt_cli-0.2.0 → toolbelt_cli-0.2.2}/src/toolbelt/cli.py +0 -0
  15. {toolbelt_cli-0.2.0 → toolbelt_cli-0.2.2}/src/toolbelt/commands/__init__.py +0 -0
  16. {toolbelt_cli-0.2.0 → toolbelt_cli-0.2.2}/src/toolbelt/commands/audit.py +0 -0
  17. {toolbelt_cli-0.2.0 → toolbelt_cli-0.2.2}/src/toolbelt/commands/commit.py +0 -0
  18. {toolbelt_cli-0.2.0 → toolbelt_cli-0.2.2}/src/toolbelt/commands/new.py +0 -0
  19. {toolbelt_cli-0.2.0 → toolbelt_cli-0.2.2}/src/toolbelt/services/__init__.py +0 -0
  20. {toolbelt_cli-0.2.0 → toolbelt_cli-0.2.2}/src/toolbelt/services/auditor.py +0 -0
  21. {toolbelt_cli-0.2.0 → toolbelt_cli-0.2.2}/src/toolbelt/services/llm.py +0 -0
  22. {toolbelt_cli-0.2.0 → toolbelt_cli-0.2.2}/src/toolbelt/services/scaffolder.py +0 -0
  23. {toolbelt_cli-0.2.0 → toolbelt_cli-0.2.2}/src/toolbelt/templates/java/.gitignore.j2 +0 -0
  24. {toolbelt_cli-0.2.0 → toolbelt_cli-0.2.2}/src/toolbelt/templates/java/LICENSE.j2 +0 -0
  25. {toolbelt_cli-0.2.0 → toolbelt_cli-0.2.2}/src/toolbelt/templates/java/README.md.j2 +0 -0
  26. {toolbelt_cli-0.2.0 → toolbelt_cli-0.2.2}/src/toolbelt/templates/java/pom.xml.j2 +0 -0
  27. {toolbelt_cli-0.2.0 → toolbelt_cli-0.2.2}/src/toolbelt/templates/java/src/main/java/com/{{project_name}}/App.java.j2 +0 -0
  28. {toolbelt_cli-0.2.0 → toolbelt_cli-0.2.2}/src/toolbelt/templates/java/src/test/java/com/{{project_name}}/AppTest.java.j2 +0 -0
  29. {toolbelt_cli-0.2.0 → toolbelt_cli-0.2.2}/src/toolbelt/templates/node/.eslintrc.json.j2 +0 -0
  30. {toolbelt_cli-0.2.0 → toolbelt_cli-0.2.2}/src/toolbelt/templates/node/.gitignore.j2 +0 -0
  31. {toolbelt_cli-0.2.0 → toolbelt_cli-0.2.2}/src/toolbelt/templates/node/.prettierrc.j2 +0 -0
  32. {toolbelt_cli-0.2.0 → toolbelt_cli-0.2.2}/src/toolbelt/templates/node/LICENSE.j2 +0 -0
  33. {toolbelt_cli-0.2.0 → toolbelt_cli-0.2.2}/src/toolbelt/templates/node/README.md.j2 +0 -0
  34. {toolbelt_cli-0.2.0 → toolbelt_cli-0.2.2}/src/toolbelt/templates/node/package.json.j2 +0 -0
  35. {toolbelt_cli-0.2.0 → toolbelt_cli-0.2.2}/src/toolbelt/templates/node/src/index.test.ts.j2 +0 -0
  36. {toolbelt_cli-0.2.0 → toolbelt_cli-0.2.2}/src/toolbelt/templates/node/src/index.ts.j2 +0 -0
  37. {toolbelt_cli-0.2.0 → toolbelt_cli-0.2.2}/src/toolbelt/templates/node/tsconfig.json.j2 +0 -0
  38. {toolbelt_cli-0.2.0 → toolbelt_cli-0.2.2}/src/toolbelt/templates/python/.github/workflows/ci.yml.j2 +0 -0
  39. {toolbelt_cli-0.2.0 → toolbelt_cli-0.2.2}/src/toolbelt/templates/python/.gitignore.j2 +0 -0
  40. {toolbelt_cli-0.2.0 → toolbelt_cli-0.2.2}/src/toolbelt/templates/python/.pre-commit-config.yaml.j2 +0 -0
  41. {toolbelt_cli-0.2.0 → toolbelt_cli-0.2.2}/src/toolbelt/templates/python/Dockerfile.j2 +0 -0
  42. {toolbelt_cli-0.2.0 → toolbelt_cli-0.2.2}/src/toolbelt/templates/python/LICENSE.j2 +0 -0
  43. {toolbelt_cli-0.2.0 → toolbelt_cli-0.2.2}/src/toolbelt/templates/python/Makefile.j2 +0 -0
  44. {toolbelt_cli-0.2.0 → toolbelt_cli-0.2.2}/src/toolbelt/templates/python/README.md.j2 +0 -0
  45. {toolbelt_cli-0.2.0 → toolbelt_cli-0.2.2}/src/toolbelt/templates/python/pyproject.toml.j2 +0 -0
  46. {toolbelt_cli-0.2.0 → toolbelt_cli-0.2.2}/src/toolbelt/templates/python/src/{{project_name}}/__init__.py.j2 +0 -0
  47. {toolbelt_cli-0.2.0 → toolbelt_cli-0.2.2}/src/toolbelt/templates/python/src/{{project_name}}/main.py.j2 +0 -0
  48. {toolbelt_cli-0.2.0 → toolbelt_cli-0.2.2}/src/toolbelt/templates/python/tests/test_main.py.j2 +0 -0
  49. {toolbelt_cli-0.2.0 → toolbelt_cli-0.2.2}/src/toolbelt/utils/__init__.py +0 -0
  50. {toolbelt_cli-0.2.0 → toolbelt_cli-0.2.2}/src/toolbelt/utils/console.py +0 -0
  51. {toolbelt_cli-0.2.0 → toolbelt_cli-0.2.2}/src/toolbelt/utils/git.py +0 -0
  52. {toolbelt_cli-0.2.0 → toolbelt_cli-0.2.2}/src/toolbelt_cli.egg-info/SOURCES.txt +0 -0
  53. {toolbelt_cli-0.2.0 → toolbelt_cli-0.2.2}/src/toolbelt_cli.egg-info/dependency_links.txt +0 -0
  54. {toolbelt_cli-0.2.0 → toolbelt_cli-0.2.2}/src/toolbelt_cli.egg-info/entry_points.txt +0 -0
  55. {toolbelt_cli-0.2.0 → toolbelt_cli-0.2.2}/src/toolbelt_cli.egg-info/requires.txt +0 -0
  56. {toolbelt_cli-0.2.0 → toolbelt_cli-0.2.2}/src/toolbelt_cli.egg-info/top_level.txt +0 -0
  57. {toolbelt_cli-0.2.0 → toolbelt_cli-0.2.2}/tests/test_audit.py +0 -0
  58. {toolbelt_cli-0.2.0 → toolbelt_cli-0.2.2}/tests/test_commit.py +0 -0
  59. {toolbelt_cli-0.2.0 → toolbelt_cli-0.2.2}/tests/test_new.py +0 -0
  60. {toolbelt_cli-0.2.0 → toolbelt_cli-0.2.2}/tests/test_version.py +0 -0
@@ -5,6 +5,19 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.2.2] - 2026-11-08
9
+
10
+ ### Changed
11
+ - Replaced the README badge markup with standard Markdown badges and removed the externally hosted Ruff badge endpoint.
12
+
13
+ ## [0.2.1] - 2026-11-08
14
+
15
+ ### Changed
16
+ - Updated the README with accurate installation, command usage, configuration, and deployment instructions.
17
+ - Synchronized the docs site and version-command fallback with the package version.
18
+ - Updated GitHub Actions to current Node.js 24-compatible major versions.
19
+ - Restricted CI workflow permissions to read-only repository contents.
20
+
8
21
  ## [0.2.0] - 2026-10-17
9
22
 
10
23
  ### Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: toolbelt-cli
3
- Version: 0.2.0
3
+ Version: 0.2.2
4
4
  Summary: A developer productivity CLI that scaffolds projects, generates conventional commit messages with Claude API, and audits repos.
5
5
  Author-email: Christopher Njihia <crnjihia@gmail.com>
6
6
  License-Expression: MIT
@@ -42,24 +42,17 @@ Dynamic: license-file
42
42
  <img src="assets/demo.png" alt="Toolbelt CLI in action" width="800" />
43
43
  </p>
44
44
 
45
- *The screenshot above demonstrates live execution of Toolbelt CLI in Windows Terminal:*
46
- 1. **`toolbelt --help`**: Rich command overview, argument formatting, and shell completion options.
47
- 2. **`toolbelt version`**: Fast local package version readout and automated PyPI release checking.
48
- 3. **`toolbelt audit .`**: 10-point repository quality audit checking README sections, license files, `.gitignore` entries, test directories, and CI workflows.
49
-
50
45
  <p align="center">
51
- <strong>Opinionated Developer Productivity CLI: Multi-Language Scaffolding, AI Git Commits, and Repository Auditing.</strong>
46
+ <strong>Scaffold projects, draft Conventional Commits, and audit repositories.</strong>
52
47
  </p>
53
48
 
54
- <p align="center">
55
- <a href="https://crnjihia.github.io/toolbelt-cli/"><img src="https://img.shields.io/badge/Docs-GitHub%20Pages-10b981?style=flat&logo=github" alt="Documentation" /></a>
56
- <a href="https://github.com/crnjihia/toolbelt-cli/actions/workflows/ci.yml"><img src="https://github.com/crnjihia/toolbelt-cli/actions/workflows/ci.yml/badge.svg" alt="CI Status" /></a>
57
- <a href="https://pypi.org/project/toolbelt-cli/"><img src="https://img.shields.io/pypi/v/toolbelt-cli.svg?color=blue" alt="PyPI Version" /></a>
58
- <a href="https://pypi.org/project/toolbelt-cli/"><img src="https://img.shields.io/pypi/pyversions/toolbelt-cli.svg" alt="Python Versions" /></a>
59
- <a href="https://github.com/astral-sh/ruff"><img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json" alt="Ruff" /></a>
60
- <a href="https://mypy.readthedocs.io/"><img src="https://img.shields.io/badge/types-Mypy-blue.svg" alt="Type Checked" /></a>
61
- <a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT" /></a>
62
- </p>
49
+ [![Documentation](https://img.shields.io/badge/Docs-GitHub%20Pages-10b981?logo=github)](https://crnjihia.github.io/toolbelt-cli/)
50
+ [![CI Status](https://github.com/crnjihia/toolbelt-cli/actions/workflows/ci.yml/badge.svg)](https://github.com/crnjihia/toolbelt-cli/actions/workflows/ci.yml)
51
+ [![PyPI Version](https://img.shields.io/pypi/v/toolbelt-cli?logo=pypi&label=PyPI)](https://pypi.org/project/toolbelt-cli/)
52
+ [![Python Versions](https://img.shields.io/pypi/pyversions/toolbelt-cli?logo=python)](https://pypi.org/project/toolbelt-cli/)
53
+ [![Linted with Ruff](https://img.shields.io/badge/lint-Ruff-D7FF64?logo=ruff&logoColor=black)](https://github.com/astral-sh/ruff)
54
+ [![Type checked with Mypy](https://img.shields.io/badge/types-Mypy-blue)](https://mypy.readthedocs.io/)
55
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow)](https://opensource.org/licenses/MIT)
63
56
 
64
57
  ---
65
58
 
@@ -67,15 +60,16 @@ Dynamic: license-file
67
60
  - [Overview](#overview)
68
61
  - [Installation](#installation)
69
62
  - [Command Reference](#command-reference)
63
+ - [Usage](#usage)
70
64
  - [Feature Tour & Usage Examples](#feature-tour)
71
65
  - [1. Project Scaffolding (`toolbelt new`)](#1-toolbelt-new-type-name)
72
66
  - [2. AI-Powered Commits (`toolbelt commit`)](#2-toolbelt-commit)
73
67
  - [3. Repository Auditing (`toolbelt audit`)](#3-toolbelt-audit-path)
74
- - [4. Version & Upstream Sync (`toolbelt version`)](#4-toolbelt-version)
68
+ - [4. Version Check (`toolbelt version`)](#4-toolbelt-version)
75
69
  - [Configuration & Environment Variables](#configuration--environment-variables)
76
70
  - [Architecture & Tech Stack](#architecture--tech-stack)
77
71
  - [Development & Testing](#development--testing)
78
- - [GitHub Setup & Publication Guide](#github-setup--publication-guide)
72
+ - [Deployments](#deployments)
79
73
  - [Publishing to PyPI](#publishing-to-pypi)
80
74
  - [Contributing](#contributing)
81
75
  - [License](#license)
@@ -84,12 +78,10 @@ Dynamic: license-file
84
78
 
85
79
  ## Overview
86
80
 
87
- **Toolbelt CLI** (`toolbelt`) is a command-line tool built with Python 3.11+, Typer, Rich, and Jinja2 that automates repetitive developer workflows:
88
-
89
- 1. 🚀 **Scaffold New Projects (`toolbelt new`)**: Instantly generate clean, production-ready project templates for **Python**, **Node.js / TypeScript**, and **Java** with pre-configured linters, test harnesses, CI pipelines, and Dockerfiles.
90
- 2. 🤖 **AI-Powered Commits (`toolbelt commit`)**: Automatically analyze staged git diffs and draft structured Conventional Commit messages using **Claude** (`claude-sonnet-4`), with an offline rule-based fallback when no API key is set.
91
- 3. 🔍 **Repository Auditing (`toolbelt audit`)**: Scan any codebase for missing documentation sections (`Installation`, `Usage`, `License`), required configuration files (`.gitignore`, `pyproject.toml`, test suites, CI workflows), and automatically repair missing files with `--fix`.
92
- 4. 📦 **Version & PyPI Sync (`toolbelt version`)**: Inspect currently installed version and verify release availability against the Python Package Index.
81
+ Toolbelt CLI is a Python 3.11+ command-line utility built with Typer, Rich, and
82
+ Jinja2. It provides starter templates for Python, Node.js/TypeScript, and Java,
83
+ commit-message drafting from staged Git changes, repository checks, and an
84
+ optional PyPI update check.
93
85
 
94
86
  ---
95
87
 
@@ -112,13 +104,15 @@ uv tool install toolbelt-cli
112
104
  pip install toolbelt-cli
113
105
  ```
114
106
 
115
- ### Local Development Installation
107
+ ### Install from source
116
108
  ```bash
117
109
  git clone https://github.com/crnjihia/toolbelt-cli.git
118
110
  cd toolbelt-cli
119
111
  pip install -e ".[dev]"
120
112
  ```
121
113
 
114
+ The installation provides both `toolbelt` and `zana` command names.
115
+
122
116
  ---
123
117
 
124
118
  ## Command Reference
@@ -133,10 +127,25 @@ pip install -e ".[dev]"
133
127
 
134
128
  ---
135
129
 
130
+ ## Usage
131
+
132
+ ```bash
133
+ toolbelt --help
134
+ toolbelt new python my_service
135
+ git add src/
136
+ toolbelt commit --dry-run
137
+ toolbelt audit .
138
+ toolbelt version
139
+ ```
140
+
141
+ `toolbelt commit` reads staged changes. Use `--dry-run` to preview a message
142
+ without creating a commit.
143
+
136
144
  ## Feature Tour
137
145
 
138
146
  ### 1. `toolbelt new <type> <name>`
139
- Scaffolds a new project directory with interactive prompts powered by Typer and Rich:
147
+ Scaffolds a new project directory. When options are omitted, the command prompts
148
+ for author, license, CI, and Docker choices:
140
149
 
141
150
  ```bash
142
151
  toolbelt new python my_service
@@ -164,22 +173,26 @@ Include Docker? (y/n) [False]: y
164
173
  - `pyproject.toml` (configured with Ruff, MyPy, and Pytest)
165
174
  - `.pre-commit-config.yaml`
166
175
  - `Makefile` (`install`, `test`, `lint`, `format`, `clean`)
167
- - `README.md`, `.gitignore`, `LICENSE`
168
- - `.github/workflows/ci.yml` (optional)
169
- - `Dockerfile` (optional)
176
+ - `README.md`, `.gitignore`, and optionally `LICENSE`
177
+ - `.github/workflows/ci.yml` when CI is enabled
178
+ - `Dockerfile` when Docker is enabled
170
179
 
171
180
  - **Node.js / TypeScript (`toolbelt new node <name>`)**:
172
- - `package.json` (TypeScript, ESLint, Prettier, Vitest)
181
+ - `package.json` (TypeScript, ESLint, Prettier, and Vitest dependencies/scripts)
173
182
  - `tsconfig.json`
174
183
  - `src/index.ts`, `src/index.test.ts`
175
184
  - `.eslintrc.json`, `.prettierrc`
176
- - `README.md`, `.gitignore`, `LICENSE`
185
+ - `README.md`, `.gitignore`, and optionally `LICENSE`
177
186
 
178
187
  - **Java (`toolbelt new java <name>`)**:
179
188
  - `pom.xml` (Maven, JUnit 5 Jupiter, compiler plugins)
180
189
  - `src/main/java/com/<name>/App.java`
181
190
  - `src/test/java/com/<name>/AppTest.java`
182
- - `README.md`, `.gitignore`, `LICENSE`
191
+ - `README.md`, `.gitignore`, and optionally `LICENSE`
192
+
193
+ `--yes` accepts defaults: the configured Git author (or `Developer`), MIT license,
194
+ CI enabled, and Docker disabled. CI and Docker templates are currently available
195
+ for Python projects.
183
196
 
184
197
  ---
185
198
 
@@ -199,10 +212,16 @@ Apply commit? [y/n/edit] (y): y
199
212
  ✅ Commit created successfully!
200
213
  ```
201
214
 
202
- - **Claude Sonnet 4 Integration**: Export your Anthropic API key (`export ANTHROPIC_API_KEY="sk-ant-..."`) for contextual messages following standard types: `feat`, `fix`, `docs`, `style`, `refactor`, `test`, `chore`.
203
- - **Smart Fallback**: If no key is set, Toolbelt falls back to an offline heuristic analyzer that inspects diff sizes, lines added/removed, and modified file types.
215
+ - **Claude integration**: Set `ANTHROPIC_API_KEY` to draft a message with the Anthropic API (`claude-sonnet-4`). The staged diff is sent to Anthropic when this is enabled.
216
+ - **Local fallback**: Without an API key, a heuristic uses the diff to draft a message without making a network call.
204
217
  - **Dry-run Mode**: Preview generated messages without applying commits using `toolbelt commit --dry-run`.
205
- - **Safety**: Rejects any commit message shorter than 10 characters and offers interactive `[y/n/edit]` revision.
218
+ - **Confirmation**: Review, edit, or reject the proposed message before committing. `--yes` skips confirmation.
219
+
220
+ Use `--type` and `--scope` to provide parts of the commit header:
221
+
222
+ ```bash
223
+ toolbelt commit --type feat --scope cli
224
+ ```
206
225
 
207
226
  ---
208
227
 
@@ -213,27 +232,9 @@ Performs a structured quality check on any repository:
213
232
  toolbelt audit .
214
233
  ```
215
234
 
216
- ```text
217
- Repository Audit: Toolbelt-CLI
218
- ┌────────────────────────────┬──────────┬──────────────────────────┐
219
- │ Check │ Status │ Details │
220
- ├────────────────────────────┼──────────┼──────────────────────────┤
221
- │ README.md exists │ ✅ │ 227 lines │
222
- │ README has Install │ ✅ │ found "## Installation" │
223
- │ README has Usage │ ✅ │ found "## Usage" │
224
- │ README has License │ ✅ │ found "## License" │
225
- │ LICENSE file │ ✅ │ MIT │
226
- │ .gitignore exists │ ✅ │ 29 entries │
227
- │ .gitignore has __pycache__ │ ✅ │ │
228
- │ Tests directory │ ✅ │ tests/ found │
229
- │ CI config │ ✅ │ .github/workflows/ci.yml │
230
- │ pyproject.toml │ ✅ │ │
231
- └────────────────────────────┴──────────┴──────────────────────────┘
232
- ```
233
-
234
- - **Exit Code**: Returns `0` if all checks pass, and `1` if any check fails (ready for pre-commit hooks and CI gates).
235
- - **Auto-Fix (`--fix`)**: Automatically prompts to create missing `.gitignore` files and `LICENSE` files (MIT or Apache-2.0).
235
+ - **Auto-Fix (`--fix`)**: Prompts to create a missing `.gitignore` and/or MIT or Apache-2.0 `LICENSE`. It does not repair other failed checks.
236
236
  - **JSON Mode (`--json`)**: Outputs machine-readable JSON for integration into reporting tools or CI/CD pipelines.
237
+ - **Exit status**: Returns `0` when all checks pass and `1` when one or more checks fail.
237
238
 
238
239
  ---
239
240
 
@@ -248,16 +249,26 @@ toolbelt version
248
249
 
249
250
  ## Configuration & Environment Variables
250
251
 
251
- Copy `.env.example` to `.env` to configure your environment:
252
+ The optional `ANTHROPIC_API_KEY` environment variable is used by `toolbelt commit`.
253
+ The CLI does not load `.env` files; set the variable in your shell before running
254
+ the command.
252
255
 
253
- ```ini
254
- # Optional: Set Claude API key for AI-assisted git commit message generation
255
- ANTHROPIC_API_KEY=sk-ant-api03-...
256
+ PowerShell:
256
257
 
257
- # Optional: Set debug logging
258
- LOG_LEVEL=INFO
258
+ ```powershell
259
+ $env:ANTHROPIC_API_KEY = "your-api-key"
260
+ toolbelt commit
261
+ ```
262
+
263
+ macOS/Linux:
264
+
265
+ ```bash
266
+ export ANTHROPIC_API_KEY="your-api-key"
267
+ toolbelt commit
259
268
  ```
260
269
 
270
+ Without this variable, commit-message generation uses the local fallback.
271
+
261
272
  ---
262
273
 
263
274
  ## Architecture & Tech Stack
@@ -302,66 +313,39 @@ mypy src
302
313
 
303
314
  ---
304
315
 
305
- ## GitHub Setup & Publication Guide
316
+ ## Deployments
306
317
 
307
- Follow these steps to publish this repository to your personal or organization GitHub account:
318
+ GitHub Actions manages CI, the documentation site, and PyPI releases:
308
319
 
309
- ### 1. Initialize & Link GitHub Remote
310
- Create a new repository named `toolbelt-cli` on [GitHub](https://github.com/new) (leave "Initialize with README" unchecked). Then connect your local repository:
320
+ - **CI** ([`.github/workflows/ci.yml`](.github/workflows/ci.yml)) runs on pushes and pull requests targeting `main`. It tests Python 3.11 and 3.12 with Ruff, MyPy, and Pytest.
321
+ - **Documentation** ([`.github/workflows/pages.yml`](.github/workflows/pages.yml)) deploys the static `docs/` site to GitHub Pages when documentation or its workflow changes on `main`; it can also be started manually. In repository settings, Pages must use **GitHub Actions** as its deployment source.
322
+ - **PyPI release** ([`.github/workflows/release.yml`](.github/workflows/release.yml)) runs for tags matching `v*`. It builds and checks the package, then publishes using PyPI Trusted Publishing (OIDC).
311
323
 
312
- ```bash
313
- # Add your GitHub remote
314
- git remote add origin https://github.com/crnjihia/toolbelt-cli.git
324
+ ### Configure PyPI Trusted Publishing
315
325
 
316
- # Ensure default branch is main
317
- git branch -M main
326
+ Before the first release, register a publisher on PyPI for the **`toolbelt-cli`**
327
+ project with these exact values:
318
328
 
319
- # Push code, tags, and complete history to GitHub
320
- git push -u origin main
321
- ```
329
+ | PyPI setting | Value |
330
+ |---|---|
331
+ | Owner | `crnjihia` |
332
+ | Repository | `toolbelt-cli` |
333
+ | Workflow filename | `release.yml` |
334
+ | Environment name | `pypi` |
322
335
 
323
- ### 2. Configure PyPI Trusted Publishing (OIDC)
324
- Toolbelt CLI uses GitHub Actions **Trusted Publishing** (OIDC) so no API tokens or passwords need to be saved in repository secrets:
325
-
326
- 1. Log into your [PyPI](https://pypi.org/) account.
327
- 2. Navigate to **Account settings** → **Publishing** → **Add a GitHub publisher**.
328
- 3. Set:
329
- - **PyPI Project Name**: `toolbelt-cli`
330
- - **Owner**: `crnjihia`
331
- - **Repository name**: `toolbelt-cli`
332
- - **Workflow name**: `release.yml`
333
- - **Environment name**: `pypi`
334
- 4. In your GitHub repository, ensure the `pypi` environment is enabled under **Settings** → **Environments**.
335
- 5. When ready to release, simply tag and push:
336
- ```bash
337
- git tag v0.1.0
338
- git push origin v0.1.0
339
- ```
340
- GitHub Actions will automatically build source distributions and wheels, run `twine check`, and publish to PyPI!
341
-
342
- ### 3. Continuous Integration Checks
343
- On every push and pull request, [`.github/workflows/ci.yml`](.github/workflows/ci.yml) automatically executes:
344
- - Matrix testing across Python **3.11** and **3.12**.
345
- - Fast code hygiene validation via `ruff check .`.
346
- - Code format verification via `ruff format --check .`.
347
- - Static type analysis via `mypy src`.
348
- - Complete test suite execution via `pytest -v` (19 offline tests with 100% pass guarantee).
336
+ The GitHub repository must also have a `pypi` environment. The build and
337
+ distribution checks can pass even when publishing is not configured; in that case,
338
+ the publish step fails with an `invalid-publisher` error. Configure the publisher
339
+ in the PyPI project settings. Do not add a PyPI API token to the workflow for this
340
+ OIDC setup.
349
341
 
350
- ---
342
+ For a release, update the version in `pyproject.toml` and `src/toolbelt/__init__.py`,
343
+ update `CHANGELOG.md`, then push a version tag:
351
344
 
352
- ## Publishing to PyPI
353
-
354
- This project is configured with GitHub Actions **Trusted Publishing** using OpenID Connect (OIDC). No long-lived API tokens are stored in repository secrets.
355
-
356
- To release a new version:
357
- 1. Bump the version in `pyproject.toml` and `src/toolbelt/__init__.py`.
358
- 2. Update `CHANGELOG.md`.
359
- 3. Create and push a git tag:
360
- ```bash
361
- git tag v0.1.0
362
- git push origin v0.1.0
363
- ```
364
- 4. The `.github/workflows/release.yml` workflow will automatically build wheels and sdist distributions and publish them directly to PyPI.
345
+ ```bash
346
+ git tag v0.3.0
347
+ git push origin v0.3.0
348
+ ```
365
349
 
366
350
  ---
367
351
 
@@ -371,7 +355,7 @@ Contributions are welcome! Please follow these steps:
371
355
 
372
356
  1. Fork the repository on GitHub.
373
357
  2. Create a feature branch: `git checkout -b feat/my-new-feature`
374
- 3. Ensure all tests and linters pass: `pytest && ruff check . && mypy src`
358
+ 3. Ensure tests, lint, formatting, and type checks pass: `pytest -v`, `ruff check .`, `ruff format --check .`, and `mypy src`.
375
359
  4. Commit your changes using conventional commits: `git commit -m "feat(scope): describe change"`
376
360
  5. Open a Pull Request.
377
361