| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Name | Name | Last commit date | ||
|---|---|---|---|---|
Reusable Python quality-gate scripts, a reusable CI workflow, and reference configurations that define a consistent developer experience across all Python repositories in the NWarila GitHub account.
This repo is the Python-specific layer of a two-layer governance model. For org-wide community health files, issue templates, and baseline CI, see NWarila/.github.
| Layer | Repo | Responsibility |
|---|---|---|
| Org governance | NWarila/.github | Community health files, issue and PR templates, baseline CI, workflow templates |
| Python QA | NWarila/python-template | Check scripts, reusable workflow, setup action, sync manifest, reference configs |
Downstream Python repos consume both layers through different mechanisms. The .github repo provides defaults through GitHub's built-in inheritance; this repo ships Python-specific scripts and configs through tagged releases that downstream repos pull on their own schedule.
| Check | Tool | Config Source |
|---|---|---|
| Lint + Format | ruff | [tool.ruff] in pyproject.toml |
| Type Checking | mypy | [tool.mypy] in pyproject.toml |
| Tests + Coverage | pytest + pytest-cov | [tool.pytest.ini_options] in pyproject.toml |
| Security | pip-audit | Environment and dependency metadata |
| Spelling | codespell | [tool.codespell] in pyproject.toml |
| Packaging | build + twine | [build-system] in pyproject.toml |
The starter package is intentionally generic. Rename sample_app before adding product-specific code:
$env:NEW_PKG = "your_pkg"
git mv src/sample_app "src/$env:NEW_PKG"
git mv tests/test_sample_app.py "tests/test_$($env:NEW_PKG).py"
@'
import os
from pathlib import Path
old = "sample_app"
new = os.environ["NEW_PKG"]
dist = new.replace("_", "-")
paths = [
Path("pyproject.toml"),
Path("README.md"),
Path(f"tests/test_{new}.py"),
*sorted((Path("src") / new).rglob("*.py")),
]
for path in paths:
text = path.read_text(encoding="utf-8")
text = text.replace(old, new)
text = text.replace('name = "python-template"', f'name = "{dist}"')
path.write_text(text, encoding="utf-8")
'@ | Set-Content -Encoding UTF8 rename_template_package.py
python rename_template_package.py
Remove-Item rename_template_package.py
python -m pip install --upgrade pip
python -m pip install -e ".[dev]"
python scripts/qa.pyThat flow performs the required git mv src/sample_app src/<your_pkg> rename, updates imports and module strings, changes [tool.setuptools.packages.find].include to the new package name, changes [project].name to the hyphenated distribution name, refreshes the editable install, and runs the QA gates. If a consumer adds [project.scripts], point each entry at <your_pkg>.main:main or another consumer-owned entry point.
The self-demo remains available after the rename:
python -m your_pkgpython-template/
|-- .github/
| |-- actions/
| | `-- setup-python/
| | `-- action.yml # Composite action for Python + dependency setup
| |-- scripts/
| | |-- .version # Deliberate release-copy metadata
| | `-- ... # Released copies synced from scripts/
| `-- workflows/
| |-- auto-release.yml # Creates a release when scripts/ changes land on main
| |-- python-qa.yml # Reusable CI workflow for downstream repos
| |-- self-update.yml # Pulls released files via manifest (dogfood)
| `-- template-ci.yml # CI for this repo, running released scripts
|-- reference/
| |-- pyproject.toml # Reference project config
| |-- pre-commit-config.yaml # Pre-commit hook definitions
| |-- settings.json # VSCode editor settings
| |-- tasks.json # VSCode task definitions
| |-- extensions.json # VSCode recommended extensions
| |-- gitignore # Reference .gitignore
| |-- gitattributes # Reference .gitattributes
| |-- markdownlint-cli2.jsonc # Markdown lint config
| `-- repo-ci.yml # Starter CI workflow for downstream repos
|-- scripts/
| |-- check_lint.py # ruff lint + format
| |-- check_types.py # mypy
| |-- check_tests.py # pytest + coverage
| |-- check_security.py # pip-audit
| |-- check_spelling.py # codespell
| |-- check_package.py # build + twine check
| |-- qa.py # Local orchestrator
| |-- sync.py # Manifest-driven file sync for template updates
| |-- setup.sh # Unix venv bootstrap
| `-- setup.ps1 # Windows venv bootstrap
|-- src/
| `-- sample_app/
| |-- __init__.py # Curated public API and __all__
| |-- __main__.py # python -m sample_app self-demo
| |-- py.typed # PEP 561 typing marker
| |-- config.py # Frozen pydantic-settings API
| |-- exceptions.py # Typed What/Why/Fix exceptions
| |-- _contracts.py # Frozen Pydantic contracts and Result shape
| |-- validators.py # Pure validation helpers
| `-- main.py # CLI entry point and worked sample function
|-- sync-manifest.json # Source-to-dest file mappings for downstream sync
|-- pyproject.toml # Config for this repo
`-- README.md
scripts/ is the canonical source tree for QA scripts, setup scripts, and the sync helper. Edit scripts there first. .github/scripts/ is the released copy used by this template's self-dogfooding CI and by downstream repositories after sync.
The two trees should contain byte-identical copies of every script listed in sync-manifest.json. The only deliberate extra file is .github/scripts/.version, which records the release tag currently pulled into the released-copy tree. There is no scripts/__init__.py; scripts are standalone files, not an importable package.
Downstream repos copy reference/repo-ci.yml into .github/workflows/ci.yml and call the reusable workflow from a tagged release:
jobs:
python-qa:
uses: NWarila/python-template/.github/workflows/python-qa.yml@v1The reusable workflow runs each quality gate as a separate job and publishes a single stable ci-passed aggregator result.
Downstream repos run the synced .github/scripts/ directly:
.venv/bin/python .github/scripts/qa.py
.venv/bin/python .github/scripts/qa.py --fix
.venv/bin/python .github/scripts/qa.py --skip tests securityVSCode tasks in reference/tasks.json expose the same checks in the editor.
The synced .pre-commit-config.yaml calls the same tools with the same pyproject.toml configuration so issues are caught before code leaves the developer's machine.
Downstream repos call the reusable self-update.yml workflow from a thin wrapper:
# .github/workflows/template-sync.yml
name: Template Sync
on:
schedule:
- cron: "0 6 * * 1" # Weekly Monday 06:00 UTC
workflow_dispatch:
permissions:
contents: write
pull-requests: write
jobs:
sync:
uses: NWarila/python-template/.github/workflows/self-update.yml@v1The workflow checks for new releases, reads sync-manifest.json to know which files to copy and where, and opens a PR using the repo's own GITHUB_TOKEN. No PAT required.
Supported sync modes:
Floating vX / vX.Y advancement and .github/scripts/.version stamping are manual maintainer tasks: an admin re-points the floating tag and bumps .version through a normal PR. The drift guard in template-ci.yml fails CI when the latest release, floating tag, or marker drifts, prompting that manual fix. Full automation is blocked until the shelved GitHub App path in github-token-limitation.md exists, because GITHUB_TOKEN cannot push to main or force-update protected tags.
Each repo controls its own update cadence — the template publishes releases, consumers pull when ready. No cross-repo credentials, no push permissions, no coupling.
The org-standard .gitignore uses an explicit allowlist model and starts with **, matching the control-plane style used in NWarila/.github. Repos intentionally allow tracked roots and keep generated artifacts ignored even inside allowed paths.
The org-standard .gitattributes is comment-rich and standardized, defining LF normalization and markdown diff behavior in a format aligned with NWarila/.github.
See LICENSE.
| Back | FazBrowse Home | New Git URL |