Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion MAINTAINING.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

These steps only need to be completed once after the project is first created.

### GitHub Repository
### GitHub repository

[Settings → General][repo-settings]:

Expand Down
66 changes: 57 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,77 @@

[Copier][copier] template for Python projects with modern tooling

[![Copier](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/copier-org/copier/master/img/badge/badge-grayscale-inverted-border-purple.json)][copier]
[![License](https://img.shields.io/github/license/smkent/copier-python)](LICENSE)
[![Copier][copier-badge]][copier]
[![License](https://img.shields.io/github/license/smkent/copier-python)](https://github.com/smkent/copier-python/blob/main/LICENSE)
[![PyPI](https://img.shields.io/pypi/v/copier-python)](https://pypi.org/project/copier-python/)
[![Python](https://img.shields.io/pypi/pyversions/copier-python)](https://pypi.org/project/copier-python/)
[![GitHub stars](https://img.shields.io/github/stars/smkent/copier-python?style=social)](https://github.com/smkent/copier-python)

## Prerequisites
## Quick start

- [Astral's **uv** Python project manager][uv]
- [Copier][copier]: `uv tool install copier`

## Usage
With [Astral's **uv**][uv] and [**Copier**][copier] (`uv tool install copier`)
installed:

```sh
copier copy "gh:smkent/copier-python" /new/project/path
```

**[For more details, see the documentation!][docs-usage]**

## Features

* [Astral][astral] toolset: [**uv**][uv], [**ruff**][ruff], and [**ty**][ty]

[![uv][uv-badge]][uv]
[![ruff][ruff-badge]][ruff]
[![ty][ty-badge]][ty]

* [**prek**][prek] for [pre-commit][pre-commit] compatible git hooks

[![prek][prek-badge]][prek]

* Update automation with [**Renovate**][renovate] and
[**`copier update`**][copier-update]

[![Copier][copier-badge]][copier-update]
[![renovate][renovate-badge]][renovate]

* [**PyPI package**][pypi] and [**container image**][ghcr-docs] release
automation via [**GitHub Actions**][github-actions]
* [**pytest**][pytest] test framework with [**codecov.io**][codecovio] support
* [**Zensical**][zensical] project documentation with automatic deployment to
[**GitHub Pages**][github-pages]
* [**Poe the Poet**][poethepoet] for task shortcuts such as
`poe lint`, `poe test`

## Credits

This template was inspired by [pawamoy/copier-uv][copier-uv] and
[ritwiktiwari/copier-astral][copier-astral] -- Thanks!

[astral]: https://astral.sh
[codecovio]: https://codecov.io
[copier-astral]: https://ritwiktiwari.github.io/copier-astral/
[copier-badge]: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/copier-org/copier/master/img/badge/badge-grayscale-inverted-border-purple.json
[copier-update]: https://copier.readthedocs.io/en/stable/updating/
[copier-uv]: https://pawamoy.github.io/copier-uv/
[copier]: https://copier.readthedocs.io
[copier-uv]: https://github.com/pawamoy/copier-uv
[copier-astral]: https://github.com/ritwiktiwari/copier-astral
[docs-usage]: https://smkent.github.io/copier-python/prerequisites/
[ghcr-docs]: https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry
[github-actions]: https://github.com/features/actions
[github-pages]: https://pages.github.com
[poethepoet]: https://poethepoet.natn.io/
[pre-commit]: https://pre-commit.com/
[prek-badge]: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/j178/prek/master/docs/assets/badge-v0.json
[prek]: https://prek.j178.dev/
[pypi]: https://pypi.org
[pytest]: https://docs.pytest.org
[renovate-badge]: https://img.shields.io/badge/renovate-enabled-brightgreen.svg?logo=renovatebot
[renovate]: https://docs.renovatebot.com/
[ruff-badge]: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json
[ruff]: https://docs.astral.sh/ruff/
[ty-badge]: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ty/main/assets/badge/v0.json
[ty]: https://docs.astral.sh/ty/
[uv-badge]: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json
[uv]: https://docs.astral.sh/uv/
[zensical]: https://zensical.org/
8 changes: 6 additions & 2 deletions copier.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,12 @@ _message_after_copy: |
git push -u origin main
{%- if project_visibility == 'public' %}

See MAINTAINING.md for GitHub repository configuration
and additional features setup
For GitHub repository configuration and additional features setup,
either see MAINTAINING.md, or run the documentation site locally:

uv run poe docs

Then, see First Time Setup at: http://localhost:8000/{{ project_name }}/maintaining/
{%- endif %}

_message_after_update: |
Expand Down
26 changes: 26 additions & 0 deletions docs/prerequisites.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
icon: lucide/bookmark-check
---

# Prerequisites

- [x] A [supported version][python-versions] of [**Python**][python]
- [x] [**git** for verson control][git]
- [x] [Astral's **uv** Python project manager][uv]: `pip install uv` or
[other supported method][uv-installation]
- [x] [**Copier**][copier]: `uv tool install copier`

## Optional, but recommended

- [x] [Poe the Poet][poethepoet]: `uv tool install poethepoet`

This provides `poe` without the `uv run` prefix,
e.g. `poe test` instead of `uv run poe test`

[copier]: https://copier.readthedocs.io
[git]: https://git-scm.com
[poethepoet]: https://poethepoet.natn.io/
[python-versions]: https://devguide.python.org/versions/
[python]: https://python.org
[uv-installation]: https://docs.astral.sh/uv/getting-started/installation/
[uv]: https://docs.astral.sh/uv/
71 changes: 71 additions & 0 deletions docs/project-creation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
---
icon: lucide/wand-sparkles
---

# Creating a new project

## Choose a project name

Select a name for your project that meets the
[Python package naming criteria][pyproject-name]. This name will be used for
`pip install` if you choose to [publish your project on PyPI][pypi].

!!! tip
If you plan to publish your project on PyPI, ensure:

1. You have an [active PyPI account][pypi-login]
2. Your desired package name is available!

## Create a GitHub repository

[Create a repository on GitHub for your new project][github-new].
Set **Repository name** to your chosen project name.

## Generate new project from template

1. In the directory where the new project should be created, run Copier:

```sh
copier copy "gh:smkent/copier-python" ./project_name
```

Copier will prompt for project information.
Answer the prompts to configure your project.
When complete, Copier will create your new project in `./project_name`.

2. Change to the new project directory:

```
cd ./project_name
```

## Initialize the project

To complete project initialization, run:

```sh
poe init
```

This will:

1. Create the local git repository
2. Install dependencies and git hooks (same as `poe setup`)
3. Create an initial commit with the newly created project contents
4. Add your GitHub repository as the `origin` remote
(when `project_visibility: public`)

## Push repository to GitHub

Push your new project to your GitHub repository:

```sh
git push -u origin main
```

Your project's contents should now be visible on GitHub!

[github-new]: https://github.com/new
[pypi-login]: https://pypi.org/account/login/
[pypi]: https://pypi.org
[pyproject-name]: https://packaging.python.org/en/latest/guides/writing-pyproject-toml/#name
35 changes: 35 additions & 0 deletions docs/project-development.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
icon: lucide/braces
---

# Project development workflow

## Cloning the repository

Run `poe setup` in new repository clones to enable git hooks:

```sh
git clone https://github.com/<github_user>/<project_name>
cd project_name
uv sync
uv run poe setup # Enables pre-commit hooks
```

## Common tasks

| Command | Description |
|---|---|
| `poe docs` | Run documentation server locally |
| `poe lint` | Run all formatters and static checks |
| `poe lt` | Run all formatters, static checks and tests (`lint` and `test`) |
| `poe snapup` | Update test snapshots |
| `poe test` | Run tests |

## Creating a release

Create and push a tag:

```sh
git tag vX.Y.Z
git push --tags
```
87 changes: 87 additions & 0 deletions docs/project-features.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
---
icon: lucide/settings
---

# Preparing project features

!!! tip
These instructions are also present in your new project, with links directly
to your project's specific settings pages! To view these instructions in
your project:

1. Start the local documentation server: `poe docs`
2. In your browser:

1. Open **<http://localhost:8000>**
2. Click the **Development** tab
3. Click **Maintaining** in the left nav bar


## GitHub repository

[Repository Settings → General][github-settings-docs]:

- [x] Allow merge commits
- [ ] Allow squash merging
- [ ] Allow rebase merging
- [x] Automatically delete head branches

Repository Settings → Branches → Add branch protection rule for the default branch
(`main`):

- [x] Restrict deletions
- [x] Require a pull request before merging
- [x] Block force pushes

## Renovate

Ensure the [Renovate app][renovate] is installed on your account, then enable
it for your repository.

## PyPI publishing

!!! info "Only needed if your project will publish packages to PyPI"

This template uses [trusted publishing][pypi-trusted-publishing] so no API
tokens need to be stored as secrets.

1. On PyPI, add a (pending) trusted publisher in your
[Trusted Publisher Management][pypi-publishing-settings] settings:
- Publisher: GitHub Actions
- Owner: `<your-github-user>`
- Repository: `<your-project-name>`
- Workflow: `release.yaml`
- Environment: `pypi`
2. Create the `pypi` environment in the GitHub repository:
Repository Settings → Environments → New environment → `pypi`
3. Publish a release by pushing a tag:
```sh
git tag v0.1.0 # or your desired first version number
git push --tags
```

## Container registry (ghcr.io)

!!! info "Only needed if your project will build and publish container images"

Enable write access for Actions:

Repository Settings → Actions → General → Workflow permissions
→ Read and write permissions

## GitHub Pages

!!! info "Only needed if your project will publish the documentation site"

Repository Settings → Pages → Source → GitHub Actions

[copier]: https://copier.readthedocs.io
[github-new]: https://github.com/new
[github-settings-docs]: https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features
[pypi-publishing-settings]: https://pypi.org/manage/account/publishing/
[pypi-trusted-publishing]: https://docs.pypi.org/trusted-publishers/
[pypi]: https://pypi.org
[pypi-login]: https://pypi.org/account/login/
[pyproject-name]: https://packaging.python.org/en/latest/guides/writing-pyproject-toml/#name
[renovate]: https://github.com/apps/renovate
[uv]: https://docs.astral.sh/uv/
32 changes: 32 additions & 0 deletions docs/project-updates.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
icon: lucide/git-merge
---

# Applying copier-python template updates

Copier can update your project with template changes that have occurred since
the project was created.

To apply updates, simply run in your project directory:

```sh
copier update
```

This will repeat the setup prompts, in case any prompts have been added or
changed.

!!! tip
To change template-provided features in your project, simply change your
answers in the update prompts.

To apply updates without being prompted (reusing all previous answers), run:

```sh
copier update -l
```

When `copier update` is finished, view changes with `git status` and `git diff`.
Resolve any conflicts, and then commit the result.

[copier-update]: https://copier.readthedocs.io/en/stable/updating/
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ keywords = []
dependencies = []

[project.urls]
Homepage = "https://github.com/smkent/copier-python"
Homepage = "https://smkent.github.io/copier-python"
Repository = "https://github.com/smkent/copier-python"
Issues = "https://github.com/smkent/copier-python/issues"

Expand Down
2 changes: 1 addition & 1 deletion template/README.md.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
{{ project_description }}
{%- if project_visibility == 'public' %}

[![License](https://img.shields.io/github/license/{{ github_user }}/{{ project_name }})](LICENSE)
[![License](https://img.shields.io/github/license/{{ github_user }}/{{ project_name }})](https://github.com/{{ github_user }}/{{ project_name }}/blob/main/LICENSE)
{%- if enable_pypi %}
[![PyPI](https://img.shields.io/pypi/v/{{ project_name }})](https://pypi.org/project/{{ project_name }}/)
[![Python](https://img.shields.io/pypi/pyversions/{{ project_name }})](https://pypi.org/project/{{ project_name }}/)
Expand Down
4 changes: 4 additions & 0 deletions template/pyproject.toml.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,11 @@ dependencies = []
{%- if project_visibility == 'public' %}

[project.urls]
{%- if enable_docs %}
Homepage = "https://{{ github_user }}.github.io/{{ project_name }}"
{%- else %}
Homepage = "https://github.com/{{ github_user }}/{{ project_name }}"
{%- endif %}
Repository = "https://github.com/{{ github_user }}/{{ project_name }}"
Issues = "https://github.com/{{ github_user }}/{{ project_name }}/issues"
{%- endif %}
Expand Down
Loading
Loading