templatepy 0.2.9__tar.gz → 0.3.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.
- templatepy-0.3.2/CITATION.cff +17 -0
- templatepy-0.3.2/PKG-INFO +92 -0
- templatepy-0.3.2/README.md +76 -0
- templatepy-0.3.2/VERSION +1 -0
- templatepy-0.3.2/copier.yaml +64 -0
- templatepy-0.3.2/pyproject.toml +46 -0
- templatepy-0.3.2/src/templatepy/__init__.py +6 -0
- templatepy-0.3.2/template/.github/ISSUE_TEMPLATE/bug_report.md +32 -0
- templatepy-0.3.2/template/.github/ISSUE_TEMPLATE/feature_request.md +21 -0
- templatepy-0.3.2/template/.github/PULL_REQUEST_TEMPLATE.md +18 -0
- templatepy-0.3.2/template/.github/workflows/bump.yml +47 -0
- templatepy-0.3.2/template/.github/workflows/ci.yml +83 -0
- templatepy-0.3.2/template/.github/workflows/docs.yml +31 -0
- templatepy-0.3.2/template/.github/workflows/pr-review.yml +96 -0
- templatepy-0.3.2/template/.github/workflows/release.yml +35 -0
- templatepy-0.3.2/template/.gitignore +71 -0
- templatepy-0.3.2/template/.gitleaks.toml +17 -0
- templatepy-0.3.2/template/.pre-commit-config.yaml +34 -0
- templatepy-0.3.2/template/CITATION.cff +33 -0
- templatepy-0.3.2/template/CODE_OF_CONDUCT.md +31 -0
- templatepy-0.3.2/template/CONTRIBUTING.md +29 -0
- templatepy-0.3.2/template/LICENSE +12 -0
- templatepy-0.3.2/template/README.md +41 -0
- templatepy-0.3.2/template/docs/index.md +29 -0
- templatepy-0.3.2/template/mkdocs.yml +23 -0
- templatepy-0.3.2/template/pyproject.toml +112 -0
- templatepy-0.3.2/template/src/[[ project_slug ]]/__init__.py +8 -0
- templatepy-0.3.2/template/src/[[ project_slug ]]/py.typed +0 -0
- templatepy-0.3.2/template/tests/conftest.py +1 -0
- templatepy-0.3.2/template/tests/integration/test_placeholder.py +6 -0
- templatepy-0.3.2/template/tests/unit/test_placeholder.py +8 -0
- templatepy-0.2.9/.bumpversion.cfg +0 -32
- templatepy-0.2.9/.gitignore +0 -139
- templatepy-0.2.9/.pre-commit-config.yaml +0 -20
- templatepy-0.2.9/.secrets.baseline +0 -127
- templatepy-0.2.9/CODE_OF_CONDUCT.md +0 -128
- templatepy-0.2.9/CONTRIBUTING.md +0 -7
- templatepy-0.2.9/LICENSE +0 -29
- templatepy-0.2.9/MANIFEST.in +0 -4
- templatepy-0.2.9/PKG-INFO +0 -402
- templatepy-0.2.9/README.md +0 -345
- templatepy-0.2.9/pyproject.toml +0 -114
- templatepy-0.2.9/setup.cfg +0 -4
- templatepy-0.2.9/setup.py +0 -3
- templatepy-0.2.9/templatepy/__init__.py +0 -13
- templatepy-0.2.9/templatepy/example.data.file.config +0 -2
- templatepy-0.2.9/templatepy/example.data.file.test-extension-yu48 +0 -2
- templatepy-0.2.9/templatepy.egg-info/PKG-INFO +0 -402
- templatepy-0.2.9/templatepy.egg-info/SOURCES.txt +0 -21
- templatepy-0.2.9/templatepy.egg-info/dependency_links.txt +0 -1
- templatepy-0.2.9/templatepy.egg-info/entry_points.txt +0 -2
- templatepy-0.2.9/templatepy.egg-info/not-zip-safe +0 -1
- templatepy-0.2.9/templatepy.egg-info/requires.txt +0 -9
- templatepy-0.2.9/templatepy.egg-info/top_level.txt +0 -2
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
cff-version: 1.2.0
|
|
2
|
+
message: "If you use this software, please cite it as below."
|
|
3
|
+
type: software
|
|
4
|
+
title: "templatepy: Copier template for modern Python packages"
|
|
5
|
+
repository-code: https://github.com/larsrollik/templatepy
|
|
6
|
+
url: https://larsrollik.github.io/templatepy
|
|
7
|
+
license: BSD-3-Clause
|
|
8
|
+
authors:
|
|
9
|
+
- family-names: Rollik
|
|
10
|
+
given-names: Lars B.
|
|
11
|
+
orcid: https://orcid.org/0000-0003-0160-6971
|
|
12
|
+
|
|
13
|
+
# After first Zenodo release, add:
|
|
14
|
+
# identifiers:
|
|
15
|
+
# - type: doi
|
|
16
|
+
# value: 10.5281/zenodo.XXXXXXX
|
|
17
|
+
# description: Zenodo concept DOI
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: templatepy
|
|
3
|
+
Version: 0.3.2
|
|
4
|
+
Summary: Copier template for modern Python packages
|
|
5
|
+
Project-URL: Homepage, https://github.com/larsrollik/templatepy
|
|
6
|
+
Project-URL: Documentation, https://larsrollik.github.io/templatepy
|
|
7
|
+
Project-URL: Repository, https://github.com/larsrollik/templatepy
|
|
8
|
+
Author-email: "Lars B. Rollik" <l.b.rollik@protonmail.com>
|
|
9
|
+
Keywords: copier,packaging,python,template
|
|
10
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Topic :: Software Development :: Code Generators
|
|
14
|
+
Requires-Python: >=3.12
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
|
|
17
|
+
# templatepy
|
|
18
|
+
|
|
19
|
+
Copier template for modern Python packages.
|
|
20
|
+
|
|
21
|
+
**[→ Full documentation](https://larsrollik.github.io/templatepy)**
|
|
22
|
+
|
|
23
|
+
## Stack
|
|
24
|
+
|
|
25
|
+
| Tool | Role |
|
|
26
|
+
|---|---|
|
|
27
|
+
| uv | dependency management, virtual environments |
|
|
28
|
+
| hatchling + hatch-vcs | build backend; version from git tags |
|
|
29
|
+
| commitizen | Conventional Commits enforcement; auto bump on merge |
|
|
30
|
+
| ruff | linting + formatting |
|
|
31
|
+
| mypy | static type checking |
|
|
32
|
+
| pytest + pytest-cov | testing with coverage |
|
|
33
|
+
| gitleaks | secret scanning |
|
|
34
|
+
|
|
35
|
+
## Quickstart
|
|
36
|
+
|
|
37
|
+
```sh
|
|
38
|
+
uv tool install copier
|
|
39
|
+
copier copy gh:larsrollik/templatepy my-new-project
|
|
40
|
+
cd my-new-project
|
|
41
|
+
git init && git add -A && git commit -m "chore: initial commit from templatepy"
|
|
42
|
+
uv sync --extra dev
|
|
43
|
+
uv run pre-commit install --hook-type pre-commit --hook-type commit-msg
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Update existing project
|
|
47
|
+
|
|
48
|
+
```sh
|
|
49
|
+
cd my-existing-project && copier update
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Release flow
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
feature branch → PR → CI gate (lint + test + secrets) must pass
|
|
56
|
+
merge blocked until green
|
|
57
|
+
↓
|
|
58
|
+
merge to main (rebase)
|
|
59
|
+
↓
|
|
60
|
+
bump.yml fires: cz bump → tag vX.Y.Z
|
|
61
|
+
↓
|
|
62
|
+
release.yml fires on tag:
|
|
63
|
+
→ GitHub release (wheel + sdist attached)
|
|
64
|
+
→ PyPI via OIDC trusted publishing (no stored token)
|
|
65
|
+
→ Zenodo webhook (if enabled)
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## PyPI setup (one-time per repo)
|
|
69
|
+
|
|
70
|
+
Uses OIDC trusted publishing — no API token stored in GitHub secrets.
|
|
71
|
+
|
|
72
|
+
1. pypi.org → project → Settings → Publishing → Add trusted publisher
|
|
73
|
+
2. Owner: `<github-user>`, Repository: `<repo>`, Workflow: `release.yml`
|
|
74
|
+
3. Done — the workflow handles authentication automatically.
|
|
75
|
+
|
|
76
|
+
## Branch protection (required for CI gate)
|
|
77
|
+
|
|
78
|
+
Repo settings → Branches → Add rule for `main`:
|
|
79
|
+
- ✅ Require status checks: `CI` job
|
|
80
|
+
- ✅ Require branches to be up to date
|
|
81
|
+
- ✅ Require linear history
|
|
82
|
+
|
|
83
|
+
For the auto-bump workflow to push the bump commit back to main:
|
|
84
|
+
- ✅ Allow specified actors to bypass → add `github-actions[bot]`
|
|
85
|
+
|
|
86
|
+
## Docs
|
|
87
|
+
|
|
88
|
+
```sh
|
|
89
|
+
uv run mkdocs serve
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Deploy to GitHub Pages on push to main via `docs.yml` (automatic).
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# templatepy
|
|
2
|
+
|
|
3
|
+
Copier template for modern Python packages.
|
|
4
|
+
|
|
5
|
+
**[→ Full documentation](https://larsrollik.github.io/templatepy)**
|
|
6
|
+
|
|
7
|
+
## Stack
|
|
8
|
+
|
|
9
|
+
| Tool | Role |
|
|
10
|
+
|---|---|
|
|
11
|
+
| uv | dependency management, virtual environments |
|
|
12
|
+
| hatchling + hatch-vcs | build backend; version from git tags |
|
|
13
|
+
| commitizen | Conventional Commits enforcement; auto bump on merge |
|
|
14
|
+
| ruff | linting + formatting |
|
|
15
|
+
| mypy | static type checking |
|
|
16
|
+
| pytest + pytest-cov | testing with coverage |
|
|
17
|
+
| gitleaks | secret scanning |
|
|
18
|
+
|
|
19
|
+
## Quickstart
|
|
20
|
+
|
|
21
|
+
```sh
|
|
22
|
+
uv tool install copier
|
|
23
|
+
copier copy gh:larsrollik/templatepy my-new-project
|
|
24
|
+
cd my-new-project
|
|
25
|
+
git init && git add -A && git commit -m "chore: initial commit from templatepy"
|
|
26
|
+
uv sync --extra dev
|
|
27
|
+
uv run pre-commit install --hook-type pre-commit --hook-type commit-msg
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Update existing project
|
|
31
|
+
|
|
32
|
+
```sh
|
|
33
|
+
cd my-existing-project && copier update
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Release flow
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
feature branch → PR → CI gate (lint + test + secrets) must pass
|
|
40
|
+
merge blocked until green
|
|
41
|
+
↓
|
|
42
|
+
merge to main (rebase)
|
|
43
|
+
↓
|
|
44
|
+
bump.yml fires: cz bump → tag vX.Y.Z
|
|
45
|
+
↓
|
|
46
|
+
release.yml fires on tag:
|
|
47
|
+
→ GitHub release (wheel + sdist attached)
|
|
48
|
+
→ PyPI via OIDC trusted publishing (no stored token)
|
|
49
|
+
→ Zenodo webhook (if enabled)
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## PyPI setup (one-time per repo)
|
|
53
|
+
|
|
54
|
+
Uses OIDC trusted publishing — no API token stored in GitHub secrets.
|
|
55
|
+
|
|
56
|
+
1. pypi.org → project → Settings → Publishing → Add trusted publisher
|
|
57
|
+
2. Owner: `<github-user>`, Repository: `<repo>`, Workflow: `release.yml`
|
|
58
|
+
3. Done — the workflow handles authentication automatically.
|
|
59
|
+
|
|
60
|
+
## Branch protection (required for CI gate)
|
|
61
|
+
|
|
62
|
+
Repo settings → Branches → Add rule for `main`:
|
|
63
|
+
- ✅ Require status checks: `CI` job
|
|
64
|
+
- ✅ Require branches to be up to date
|
|
65
|
+
- ✅ Require linear history
|
|
66
|
+
|
|
67
|
+
For the auto-bump workflow to push the bump commit back to main:
|
|
68
|
+
- ✅ Allow specified actors to bypass → add `github-actions[bot]`
|
|
69
|
+
|
|
70
|
+
## Docs
|
|
71
|
+
|
|
72
|
+
```sh
|
|
73
|
+
uv run mkdocs serve
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Deploy to GitHub Pages on push to main via `docs.yml` (automatic).
|
templatepy-0.3.2/VERSION
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.3.2
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# templatepy — copier template configuration
|
|
2
|
+
# Usage: copier copy gh:larsrollik/templatepy my-new-project
|
|
3
|
+
# Update: copier update (inside an existing generated project)
|
|
4
|
+
|
|
5
|
+
_subdirectory: template
|
|
6
|
+
_min_copier_version: "9.0"
|
|
7
|
+
_answers_file: .copier-answers.yml
|
|
8
|
+
|
|
9
|
+
# Use [[ ]] delimiters in template files to avoid conflicts with
|
|
10
|
+
# GitHub Actions ${{ }} expression syntax.
|
|
11
|
+
_envops:
|
|
12
|
+
block_start_string: "[%"
|
|
13
|
+
block_end_string: "%]"
|
|
14
|
+
variable_start_string: "[["
|
|
15
|
+
variable_end_string: "]]"
|
|
16
|
+
comment_start_string: "[#"
|
|
17
|
+
comment_end_string: "#]"
|
|
18
|
+
|
|
19
|
+
# ---------------------------------------------------------------------------
|
|
20
|
+
# Questions
|
|
21
|
+
# ---------------------------------------------------------------------------
|
|
22
|
+
|
|
23
|
+
project_name:
|
|
24
|
+
type: str
|
|
25
|
+
help: "Human-readable project name (e.g. 'My Awesome Project')"
|
|
26
|
+
|
|
27
|
+
project_slug:
|
|
28
|
+
type: str
|
|
29
|
+
help: "Python package name — lowercase, underscores (e.g. 'my_awesome_project')"
|
|
30
|
+
default: "{{ project_name | lower | replace(' ', '_') | replace('-', '_') }}"
|
|
31
|
+
|
|
32
|
+
project_description:
|
|
33
|
+
type: str
|
|
34
|
+
help: "Short one-line description"
|
|
35
|
+
|
|
36
|
+
author_name:
|
|
37
|
+
type: str
|
|
38
|
+
help: "Your full name"
|
|
39
|
+
|
|
40
|
+
author_email:
|
|
41
|
+
type: str
|
|
42
|
+
help: "Your email address"
|
|
43
|
+
|
|
44
|
+
github_username:
|
|
45
|
+
type: str
|
|
46
|
+
help: "GitHub username or organization"
|
|
47
|
+
|
|
48
|
+
github_repo:
|
|
49
|
+
type: str
|
|
50
|
+
help: "GitHub repository name"
|
|
51
|
+
default: "{{ project_slug | replace('_', '-') }}"
|
|
52
|
+
|
|
53
|
+
python_requires:
|
|
54
|
+
type: str
|
|
55
|
+
help: "Minimum Python version"
|
|
56
|
+
default: "3.12"
|
|
57
|
+
choices:
|
|
58
|
+
- "3.12"
|
|
59
|
+
- "3.13"
|
|
60
|
+
|
|
61
|
+
year:
|
|
62
|
+
type: int
|
|
63
|
+
help: "Copyright year"
|
|
64
|
+
default: "{{ '%Y' | strftime }}"
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling", "hatch-vcs"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "templatepy"
|
|
7
|
+
dynamic = ["version"]
|
|
8
|
+
description = "Copier template for modern Python packages"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.12"
|
|
11
|
+
authors = [
|
|
12
|
+
{name = "Lars B. Rollik", email = "l.b.rollik@protonmail.com"},
|
|
13
|
+
]
|
|
14
|
+
keywords = ["copier", "template", "packaging", "python"]
|
|
15
|
+
classifiers = [
|
|
16
|
+
"Development Status :: 5 - Production/Stable",
|
|
17
|
+
"Intended Audience :: Developers",
|
|
18
|
+
"Programming Language :: Python :: 3",
|
|
19
|
+
"Topic :: Software Development :: Code Generators",
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
[project.urls]
|
|
23
|
+
Homepage = "https://github.com/larsrollik/templatepy"
|
|
24
|
+
Documentation = "https://larsrollik.github.io/templatepy"
|
|
25
|
+
Repository = "https://github.com/larsrollik/templatepy"
|
|
26
|
+
|
|
27
|
+
[tool.hatch.version]
|
|
28
|
+
source = "vcs"
|
|
29
|
+
fallback-version = "0.3.0"
|
|
30
|
+
|
|
31
|
+
[tool.hatch.build.targets.wheel]
|
|
32
|
+
packages = ["src/templatepy"]
|
|
33
|
+
|
|
34
|
+
[tool.hatch.build.targets.wheel.force-include]
|
|
35
|
+
"copier.yaml" = "templatepy/copier.yaml"
|
|
36
|
+
"template" = "templatepy/template"
|
|
37
|
+
|
|
38
|
+
[tool.hatch.build.targets.sdist]
|
|
39
|
+
include = ["src", "copier.yaml", "template", "CITATION.cff", "README.md", "VERSION"]
|
|
40
|
+
|
|
41
|
+
[tool.commitizen]
|
|
42
|
+
version_provider = "commitizen"
|
|
43
|
+
version = "0.3.2"
|
|
44
|
+
version_files = ["VERSION"]
|
|
45
|
+
tag_format = "v$version"
|
|
46
|
+
update_changelog_on_bump = false
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Bug report
|
|
3
|
+
about: Something isn't working
|
|
4
|
+
labels: bug
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Description
|
|
8
|
+
|
|
9
|
+
_Clear description of the bug._
|
|
10
|
+
|
|
11
|
+
## Steps to reproduce
|
|
12
|
+
|
|
13
|
+
1. ...
|
|
14
|
+
2. ...
|
|
15
|
+
|
|
16
|
+
## Expected behaviour
|
|
17
|
+
|
|
18
|
+
_What should happen._
|
|
19
|
+
|
|
20
|
+
## Actual behaviour
|
|
21
|
+
|
|
22
|
+
_What actually happens._
|
|
23
|
+
|
|
24
|
+
## Environment
|
|
25
|
+
|
|
26
|
+
- OS:
|
|
27
|
+
- Python version:
|
|
28
|
+
- Package version:
|
|
29
|
+
|
|
30
|
+
## Additional context
|
|
31
|
+
|
|
32
|
+
_Logs, screenshots, related issues._
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Feature request
|
|
3
|
+
about: Suggest an idea or improvement
|
|
4
|
+
labels: enhancement
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Problem
|
|
8
|
+
|
|
9
|
+
_What problem does this solve? What use case does it enable?_
|
|
10
|
+
|
|
11
|
+
## Proposed solution
|
|
12
|
+
|
|
13
|
+
_Describe what you'd like to see._
|
|
14
|
+
|
|
15
|
+
## Alternatives considered
|
|
16
|
+
|
|
17
|
+
_Other approaches you've thought about._
|
|
18
|
+
|
|
19
|
+
## Additional context
|
|
20
|
+
|
|
21
|
+
_Anything else relevant._
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
## Summary
|
|
2
|
+
|
|
3
|
+
_What does this PR do? Link to any relevant issue with `closes #N`._
|
|
4
|
+
|
|
5
|
+
## Type
|
|
6
|
+
|
|
7
|
+
- [ ] Bug fix
|
|
8
|
+
- [ ] New feature
|
|
9
|
+
- [ ] Refactor / cleanup
|
|
10
|
+
- [ ] Docs / chore
|
|
11
|
+
|
|
12
|
+
## Checklist
|
|
13
|
+
|
|
14
|
+
- [ ] Branch created from `main`
|
|
15
|
+
- [ ] Commits follow Conventional Commits (`cz commit`)
|
|
16
|
+
- [ ] Version bumped with `cz bump` and pushed with `--follow-tags` (if releasing)
|
|
17
|
+
- [ ] Tests added or updated
|
|
18
|
+
- [ ] `uv run pre-commit run --all-files` passes locally
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
name: Auto bump
|
|
2
|
+
|
|
3
|
+
# Runs after every push to main. If there are bumpable conventional commits
|
|
4
|
+
# since the last tag, creates a version bump commit + tag and pushes both.
|
|
5
|
+
# The tag push then triggers release.yml.
|
|
6
|
+
#
|
|
7
|
+
# Loop prevention: skips if the triggering commit message starts with "bump:"
|
|
8
|
+
# (i.e. the bump commit itself just pushed back to main).
|
|
9
|
+
#
|
|
10
|
+
# Branch protection: the github-actions bot must be allowed to push to main.
|
|
11
|
+
# Repo settings → Branches → edit main rule →
|
|
12
|
+
# "Allow specified actors to bypass required pull requests" → add github-actions[bot]
|
|
13
|
+
|
|
14
|
+
on:
|
|
15
|
+
push:
|
|
16
|
+
branches: [main]
|
|
17
|
+
|
|
18
|
+
permissions:
|
|
19
|
+
contents: write
|
|
20
|
+
|
|
21
|
+
jobs:
|
|
22
|
+
bump:
|
|
23
|
+
name: Version bump
|
|
24
|
+
runs-on: ubuntu-latest
|
|
25
|
+
if: "!startsWith(github.event.head_commit.message, 'bump:')"
|
|
26
|
+
steps:
|
|
27
|
+
- uses: actions/checkout@v4
|
|
28
|
+
with:
|
|
29
|
+
fetch-depth: 0
|
|
30
|
+
token: ${{ secrets.GITHUB_TOKEN }}
|
|
31
|
+
|
|
32
|
+
- name: Configure git identity
|
|
33
|
+
run: |
|
|
34
|
+
git config user.name "github-actions[bot]"
|
|
35
|
+
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
36
|
+
|
|
37
|
+
- uses: astral-sh/setup-uv@v5
|
|
38
|
+
|
|
39
|
+
- name: Bump version
|
|
40
|
+
run: |
|
|
41
|
+
uvx commitizen bump --yes || EXIT=$?
|
|
42
|
+
if [ "${EXIT:-0}" -eq 21 ]; then
|
|
43
|
+
echo "No bumpable commits since last tag — skipping release."
|
|
44
|
+
exit 0
|
|
45
|
+
fi
|
|
46
|
+
[ "${EXIT:-0}" -eq 0 ] || exit $EXIT
|
|
47
|
+
git push --follow-tags
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: ["**"]
|
|
6
|
+
tags-ignore: ["v*"] # tag pushes are handled by release.yml
|
|
7
|
+
pull_request:
|
|
8
|
+
branches: [main]
|
|
9
|
+
|
|
10
|
+
permissions:
|
|
11
|
+
contents: read
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
lint:
|
|
15
|
+
name: Lint
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v4
|
|
19
|
+
with:
|
|
20
|
+
fetch-depth: 0 # needed for hatch-vcs version derivation
|
|
21
|
+
|
|
22
|
+
- uses: astral-sh/setup-uv@v5
|
|
23
|
+
with:
|
|
24
|
+
python-version: "[[ python_requires ]]"
|
|
25
|
+
|
|
26
|
+
- name: Install dependencies
|
|
27
|
+
run: uv sync --extra dev
|
|
28
|
+
|
|
29
|
+
- name: Run pre-commit (ruff + mypy + commitizen + gitleaks)
|
|
30
|
+
run: uv run pre-commit run --all-files --show-diff-on-failure
|
|
31
|
+
|
|
32
|
+
test:
|
|
33
|
+
name: Test (Python ${{ matrix.python-version }})
|
|
34
|
+
runs-on: ubuntu-latest
|
|
35
|
+
if: github.event_name == 'pull_request'
|
|
36
|
+
strategy:
|
|
37
|
+
fail-fast: false
|
|
38
|
+
matrix:
|
|
39
|
+
python-version: ["3.12", "3.13"]
|
|
40
|
+
steps:
|
|
41
|
+
- uses: actions/checkout@v4
|
|
42
|
+
with:
|
|
43
|
+
fetch-depth: 0
|
|
44
|
+
|
|
45
|
+
- uses: astral-sh/setup-uv@v5
|
|
46
|
+
with:
|
|
47
|
+
python-version: ${{ matrix.python-version }}
|
|
48
|
+
|
|
49
|
+
- name: Install dependencies
|
|
50
|
+
run: uv sync --extra dev
|
|
51
|
+
|
|
52
|
+
- name: Run tests
|
|
53
|
+
run: uv run pytest
|
|
54
|
+
|
|
55
|
+
secrets-scan:
|
|
56
|
+
name: Secrets scan
|
|
57
|
+
runs-on: ubuntu-latest
|
|
58
|
+
steps:
|
|
59
|
+
- uses: actions/checkout@v4
|
|
60
|
+
with:
|
|
61
|
+
fetch-depth: 0
|
|
62
|
+
- uses: gitleaks/gitleaks-action@v2
|
|
63
|
+
env:
|
|
64
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
65
|
+
|
|
66
|
+
ci:
|
|
67
|
+
name: CI
|
|
68
|
+
runs-on: ubuntu-latest
|
|
69
|
+
needs: [lint, test, secrets-scan]
|
|
70
|
+
if: always()
|
|
71
|
+
steps:
|
|
72
|
+
- name: Check required jobs
|
|
73
|
+
run: |
|
|
74
|
+
if [[ "${{ needs.lint.result }}" != "success" ]]; then
|
|
75
|
+
echo "lint failed" && exit 1
|
|
76
|
+
fi
|
|
77
|
+
if [[ "${{ needs.test.result }}" != "success" && "${{ needs.test.result }}" != "skipped" ]]; then
|
|
78
|
+
echo "test failed" && exit 1
|
|
79
|
+
fi
|
|
80
|
+
if [[ "${{ needs.secrets-scan.result }}" != "success" ]]; then
|
|
81
|
+
echo "secrets-scan failed" && exit 1
|
|
82
|
+
fi
|
|
83
|
+
echo "All required checks passed."
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
name: Docs
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
paths:
|
|
7
|
+
- "docs/**"
|
|
8
|
+
- "mkdocs.yml"
|
|
9
|
+
- "src/**/*.py" # rebuild on source changes if using mkdocstrings
|
|
10
|
+
|
|
11
|
+
permissions:
|
|
12
|
+
contents: write # needed for gh-deploy to push to gh-pages branch
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
deploy:
|
|
16
|
+
name: Deploy docs to GitHub Pages
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
steps:
|
|
19
|
+
- uses: actions/checkout@v4
|
|
20
|
+
with:
|
|
21
|
+
fetch-depth: 0 # full history for git-revision-date plugin (if added later)
|
|
22
|
+
|
|
23
|
+
- uses: astral-sh/setup-uv@v5
|
|
24
|
+
with:
|
|
25
|
+
python-version: "[[ python_requires ]]"
|
|
26
|
+
|
|
27
|
+
- name: Install dependencies
|
|
28
|
+
run: uv sync --extra dev
|
|
29
|
+
|
|
30
|
+
- name: Deploy
|
|
31
|
+
run: uv run mkdocs gh-deploy --force
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
name: PR Review (optional LLM)
|
|
2
|
+
|
|
3
|
+
# Optional AI-assisted pull request review.
|
|
4
|
+
# Uncomment ONE of the sections below and configure the required secret.
|
|
5
|
+
#
|
|
6
|
+
# This workflow has a no-op placeholder job so it stays valid while
|
|
7
|
+
# both options remain commented out.
|
|
8
|
+
|
|
9
|
+
on:
|
|
10
|
+
pull_request:
|
|
11
|
+
types: [opened, synchronize, ready_for_review]
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
|
|
15
|
+
# ── Option A: Claude API (Anthropic) ─────────────────────────────────────
|
|
16
|
+
# Requires secret: ANTHROPIC_API_KEY
|
|
17
|
+
# Docs: https://docs.anthropic.com/en/api/getting-started
|
|
18
|
+
#
|
|
19
|
+
# llm-review-claude:
|
|
20
|
+
# name: Claude PR review
|
|
21
|
+
# runs-on: ubuntu-latest
|
|
22
|
+
# steps:
|
|
23
|
+
# - uses: actions/checkout@v4
|
|
24
|
+
# with:
|
|
25
|
+
# fetch-depth: 0
|
|
26
|
+
#
|
|
27
|
+
# - name: Generate diff
|
|
28
|
+
# id: diff
|
|
29
|
+
# run: |
|
|
30
|
+
# DIFF=$(git diff origin/main...HEAD -- '*.py' | head -c 8000)
|
|
31
|
+
# echo "content<<EOF" >> "$GITHUB_OUTPUT"
|
|
32
|
+
# echo "$DIFF" >> "$GITHUB_OUTPUT"
|
|
33
|
+
# echo "EOF" >> "$GITHUB_OUTPUT"
|
|
34
|
+
#
|
|
35
|
+
# - name: Review with Claude
|
|
36
|
+
# env:
|
|
37
|
+
# ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
|
38
|
+
# GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
39
|
+
# PR_NUMBER: ${{ github.event.pull_request.number }}
|
|
40
|
+
# run: |
|
|
41
|
+
# if [ -z "$ANTHROPIC_API_KEY" ]; then
|
|
42
|
+
# echo "ANTHROPIC_API_KEY not set — skipping."
|
|
43
|
+
# exit 0
|
|
44
|
+
# fi
|
|
45
|
+
# REVIEW=$(curl -s https://api.anthropic.com/v1/messages \
|
|
46
|
+
# -H "x-api-key: $ANTHROPIC_API_KEY" \
|
|
47
|
+
# -H "anthropic-version: 2023-06-01" \
|
|
48
|
+
# -H "content-type: application/json" \
|
|
49
|
+
# -d "{
|
|
50
|
+
# \"model\": \"claude-sonnet-4-6\",
|
|
51
|
+
# \"max_tokens\": 1024,
|
|
52
|
+
# \"messages\": [{
|
|
53
|
+
# \"role\": \"user\",
|
|
54
|
+
# \"content\": \"Review this Python PR diff for bugs, style issues, and improvements. Be concise.\n\n${{ steps.diff.outputs.content }}\"
|
|
55
|
+
# }]
|
|
56
|
+
# }" | python3 -c "import sys,json; print(json.load(sys.stdin)['content'][0]['text'])")
|
|
57
|
+
# gh pr comment "$PR_NUMBER" --body "## Claude PR Review\n\n${REVIEW}"
|
|
58
|
+
|
|
59
|
+
# ── Option B: Local Ollama (self-hosted runner) ───────────────────────────
|
|
60
|
+
# Requires: a self-hosted runner with Ollama running on localhost:11434
|
|
61
|
+
# Docs: https://ollama.com / https://docs.github.com/en/actions/hosting-your-own-runners
|
|
62
|
+
#
|
|
63
|
+
# llm-review-ollama:
|
|
64
|
+
# name: Ollama PR review
|
|
65
|
+
# runs-on: self-hosted
|
|
66
|
+
# steps:
|
|
67
|
+
# - uses: actions/checkout@v4
|
|
68
|
+
# with:
|
|
69
|
+
# fetch-depth: 0
|
|
70
|
+
#
|
|
71
|
+
# - name: Generate diff
|
|
72
|
+
# id: diff
|
|
73
|
+
# run: |
|
|
74
|
+
# DIFF=$(git diff origin/main...HEAD -- '*.py' | head -c 4000)
|
|
75
|
+
# echo "content<<EOF" >> "$GITHUB_OUTPUT"
|
|
76
|
+
# echo "$DIFF" >> "$GITHUB_OUTPUT"
|
|
77
|
+
# echo "EOF" >> "$GITHUB_OUTPUT"
|
|
78
|
+
#
|
|
79
|
+
# - name: Review with Ollama
|
|
80
|
+
# env:
|
|
81
|
+
# GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
82
|
+
# PR_NUMBER: ${{ github.event.pull_request.number }}
|
|
83
|
+
# OLLAMA_MODEL: "llama3.2" # change to your preferred model
|
|
84
|
+
# run: |
|
|
85
|
+
# PROMPT="Review this Python PR diff for bugs, style issues, and improvements. Be concise.\n\n${{ steps.diff.outputs.content }}"
|
|
86
|
+
# REVIEW=$(curl -s http://localhost:11434/api/generate \
|
|
87
|
+
# -d "{\"model\": \"${OLLAMA_MODEL}\", \"prompt\": \"${PROMPT}\", \"stream\": false}" \
|
|
88
|
+
# | python3 -c "import sys,json; print(json.load(sys.stdin)['response'])")
|
|
89
|
+
# gh pr comment "$PR_NUMBER" --body "## Ollama PR Review (${OLLAMA_MODEL})\n\n${REVIEW}"
|
|
90
|
+
|
|
91
|
+
# Placeholder — remove once an option above is uncommented
|
|
92
|
+
no-op:
|
|
93
|
+
name: LLM review (not configured)
|
|
94
|
+
runs-on: ubuntu-latest
|
|
95
|
+
steps:
|
|
96
|
+
- run: echo "LLM PR review not configured. See .github/workflows/pr-review.yml."
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v[0-9]*"
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: write
|
|
10
|
+
id-token: write # required for PyPI OIDC trusted publishing
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
release:
|
|
14
|
+
name: Build, release, publish
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
with:
|
|
19
|
+
fetch-depth: 0 # required for hatch-vcs to read tags
|
|
20
|
+
|
|
21
|
+
- uses: astral-sh/setup-uv@v5
|
|
22
|
+
with:
|
|
23
|
+
python-version: "[[ python_requires ]]"
|
|
24
|
+
|
|
25
|
+
- name: Build
|
|
26
|
+
run: uv build
|
|
27
|
+
|
|
28
|
+
- name: Create GitHub release
|
|
29
|
+
uses: softprops/action-gh-release@v2
|
|
30
|
+
with:
|
|
31
|
+
files: dist/*
|
|
32
|
+
generate_release_notes: false
|
|
33
|
+
|
|
34
|
+
- name: Publish to PyPI
|
|
35
|
+
run: uv publish --trusted-publishing automatic
|