Scaffold python
Cross-platform dotfiles managed by Chezmoi with Homebrew/apt and per-language version managers. One-command bootstrap for macOS and Linux with Neovim, Tmux, Zsh, and AI agent skills.
npx -y skills add urmzd/dotfiles --skill scaffold-pythonAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 2 stars2 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Scaffold a complete Python project with CI/CD, release pipeline, justfile, sr.yaml, pyproject.toml, .envrc, and standard files. Uses uv, ruff, and justfile (Python lacks a native task runner like pnpm scripts, so just fills that gap). Loads on top of scaffold-project (run that first for cross-language standard files). Use when creating a new Python CLI, library, or application, or when the user mentions "new Python project", "uv init", or "Python scaffold". Do NOT use for Go, Rust, Node, or Terraform projects; use the matching scaffold-<lang> skill.
SKILL.md
6.0 KB, ~1.5k tokens by cl100k_base, as published. Nobody here has run it
Scaffold Python Project
Generate a production-ready Python project following established CI/CD patterns. Read the scaffold-project skill first for standard files (README, AGENTS.md, LICENSE, CONTRIBUTING.md, llms.txt).
When to Use
- Creating a new Python CLI, library, or application
- Adding CI/CD to an existing Python project missing workflows
- Standardizing a Python project to match org conventions
Generated Files
.github/workflows/ci.yml
name: CI
on:
pull_request:
branches: [main]
workflow_call:
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v5
- run: uv python install
- run: uv sync --group dev
- name: Check formatting
run: uv run ruff format --check .
- name: Run linter
run: uv run ruff check .
test:
name: Test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v5
- run: uv python install
- run: uv sync --group dev
- name: Run tests
run: uv run pytest
.github/workflows/release.yml
name: Release
on:
push:
branches: [main]
workflow_dispatch:
concurrency:
group: release
cancel-in-progress: false
permissions:
contents: write
jobs:
ci:
if: github.actor != 'sr[bot]'
uses: ./.github/workflows/ci.yml
release:
needs: ci
runs-on: ubuntu-latest
steps:
- name: Generate app token
id: app-token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ secrets.SR_RELEASER_APP_ID }}
private-key: ${{ secrets.SR_RELEASER_PRIVATE_KEY }}
repositories: ${{ github.event.repository.name }}
- uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ steps.app-token.outputs.token }}
- uses: urmzd/sr@v8
id: sr
with:
github-token: ${{ steps.app-token.outputs.token }}
outputs:
released: ${{ steps.sr.outputs.released }}
tag: ${{ steps.sr.outputs.tag }}
version: ${{ steps.sr.outputs.version }}
For PyPI publishing, use the pypi typed publisher in sr.yaml (below) and split into sr prepare → uv build → sr release jobs so wheels embed the bumped version. See sync-release for the multi-job pattern.
sr.yaml
Generate with sr init:
git:
tag_prefix: "v"
floating_tag: true
v0_protection: true
commit:
types:
minor: [feat]
patch: [fix, perf, refactor]
none: [docs, revert, chore, ci, test, build, style]
changelog:
file: CHANGELOG.md
groups:
- { name: breaking, content: [breaking] }
- { name: features, content: [feat] }
- { name: bug-fixes, content: [fix] }
- { name: performance, content: [perf] }
- { name: misc, content: [chore, ci, test, build, style] }
channels:
default: stable
branch: main
content:
- name: stable
packages:
- path: .
version_files: [pyproject.toml]
stage_files: [uv.lock]
# Uncomment to publish to PyPI (requires wheels to be built in CI between
# `sr prepare` and `sr release` so they embed the bumped version):
# publish:
# type: pypi
# workspace: true # iterate [tool.uv.workspace].members
See sync-release for the full schema and sr migrate for upgrading from older versions.
pyproject.toml
[project]
name = "<project-name>"
version = "0.1.0"
description = ""
readme = "README.md"
license = "Apache-2.0"
requires-python = ">=3.12"
dependencies = []
[project.scripts]
# <project-name> = "<package>.cli:main"
[dependency-groups]
dev = ["pytest", "ruff", "ty"]
[tool.ruff]
line-length = 100
select = ["E", "W", "F", "I", "UP", "B", "SIM", "RUF"]
[tool.pytest.ini_options]
testpaths = ["tests"]
pythonpath = ["src"]
justfile
default: check
init:
git config core.hooksPath .githooks
uv sync --group dev
build:
uv build
test:
uv run pytest
lint:
uv run ruff check .
fmt:
uv run ruff format .
typecheck:
uv run ty check src/
check: fmt lint test
run *args="":
uv run python -m <package_name> {{args}}
record:
teasr showme
Replace <package_name> with the actual package name.
.envrc
layout python # Auto-creates and activates .venv
.python-version
3.12
Project Layout
src/<package_name>/
__init__.py
cli.py # if CLI
py.typed # if library with type stubs
tests/
__init__.py
test_*.py
pyproject.toml
uv.lock
Gotchas
- Use
uvexclusively. No pip, pipenv, poetry, or conda uv sync --group devinstalls dev dependencies;uv syncfor production onlyuv runprefixes all commands to ensure they run in the project venvruffreplaces black, isort, flake8, and pyflakes. One tool for format + lint- Python version comes from
pyproject.tomlrequires-pythonfield;uv python installresolves it astral-sh/setup-uv@v5handles caching automatically- For PyPI publishing,
uv publishuses trusted publishers (OIDC). Configure on pypi.org first stage_files: [uv.lock]ensures lockfile stays in sync after version bumps
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.
Gives 0 of the 12 instructions most project setup skills give in ~1.5k tokens
Counted across 999 of the 1,637 authors here whose files we hold, read 2026-08-07
- Ask one question at a timein 29 of 999, across 28 files
- Detect the package manager from lockfilesin 28 of 999, across 9 files
- Present findings to the userin 26 of 999, across 5 files
- Explore current repo statein 24 of 999, across 3 files
- Update the agent skills block in place if it existsin 24 of 999, across 3 files
- Install husky lint-staged and prettierin 23 of 999, across 4 files
- Create the lintstagedrc filein 22 of 999, across 3 files
- Commit all changed filesin 22 of 999, across 3 files
- Run lint-staged to verify it worksin 22 of 999, across 3 files
- Create the husky pre-commit filein 21 of 999, across 2 files
- Create a prettierrc file if missingin 21 of 999, across 2 files
- Initialize huskyin 21 of 999, across 2 files
Said here and by no other author read
- read scaffold-project skill first
- generate sr.yaml via sr init
- generate .envrc
- generate .python-version
- prefix all commands with uv run
- use uv exclusively
Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.