Skip to content

Commit 7786e65

Browse files
committed
github workflows, move to uv + ruff
1 parent dfcee68 commit 7786e65

File tree

10 files changed

+156
-110
lines changed

10 files changed

+156
-110
lines changed

.github/workflows/release.yml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags:
6+
- '*'
7+
8+
jobs:
9+
release:
10+
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v3
14+
with:
15+
fetch-depth: 0
16+
- name: Set up Python 3.10
17+
uses: actions/setup-python@v4
18+
with:
19+
python-version: "3.10"
20+
- name: Build dev environment
21+
run: make dev
22+
- name: Unit tests
23+
run: make test
24+
- name: Build distribution
25+
run: make dist
26+
- name: Push release
27+
env:
28+
PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }}
29+
run: make release
30+
- name: Update docs
31+
env:
32+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
33+
run: make docs

.github/workflows/unit-tests.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
name: Unit tests
2+
3+
on: [push]
4+
5+
jobs:
6+
build:
7+
8+
runs-on: ubuntu-latest
9+
strategy:
10+
# You can use PyPy versions in python-version.
11+
# For example, pypy2.7 and pypy3.9
12+
matrix:
13+
python-version: ["3.10", "3.11"]
14+
15+
steps:
16+
- uses: actions/checkout@v3
17+
- name: Set up Python ${{ matrix.python-version }}
18+
uses: actions/setup-python@v4
19+
with:
20+
python-version: ${{ matrix.python-version }}
21+
- name: Build dev environment
22+
run: make dev
23+
- name: Unit tests
24+
run: make test

.pre-commit-config.yaml

Lines changed: 22 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,23 @@
11
repos:
2-
- repo: https://github.com/pre-commit/pre-commit-hooks
3-
rev: v5.0.0
4-
hooks:
5-
- id: check-toml
6-
- id: check-symlinks
7-
- id: check-merge-conflict
8-
- id: check-case-conflict
9-
- id: check-shebang-scripts-are-executable
10-
- id: mixed-line-ending
11-
- id: trailing-whitespace
12-
- repo: https://github.com/psf/black
13-
rev: 25.1.0
14-
hooks:
15-
- id: black
16-
- repo: https://github.com/PyCQA/isort
17-
rev: 6.0.1
18-
hooks:
19-
- id: isort
20-
- repo: https://github.com/PyCQA/autoflake
21-
rev: v2.3.1
22-
hooks:
23-
- id: autoflake
24-
args: [
25-
"--in-place",
26-
"--remove-unused-variables",
27-
"--remove-all-unused-imports",
28-
]
29-
- repo: https://github.com/PyCQA/flake8
30-
rev: 7.2.0
31-
hooks:
32-
- id: flake8
33-
- repo: https://github.com/shellcheck-py/shellcheck-py
34-
rev: v0.10.0.1
35-
hooks:
36-
- id: shellcheck
2+
- repo: https://github.com/pre-commit/pre-commit-hooks
3+
rev: v5.0.0
4+
hooks:
5+
- id: check-toml
6+
- id: check-symlinks
7+
- id: check-merge-conflict
8+
- id: check-case-conflict
9+
- id: check-shebang-scripts-are-executable
10+
- id: mixed-line-ending
11+
- id: trailing-whitespace
12+
13+
- repo: https://github.com/astral-sh/ruff-pre-commit
14+
rev: v0.5.0
15+
hooks:
16+
- id: ruff
17+
args: ["--fix"]
18+
- id: ruff-format
19+
20+
- repo: https://github.com/shellcheck-py/shellcheck-py
21+
rev: v0.10.0.1
22+
hooks:
23+
- id: shellcheck

.vscode/extensions.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
{
2-
"recommendations": [
3-
"ms-python.python",
4-
"davidanson.vscode-markdownlint",
5-
"ms-vscode.makefile-tools",
6-
"ms-python.flake8"
7-
]
2+
"recommendations": [
3+
"ms-python.python",
4+
"davidanson.vscode-markdownlint",
5+
"ms-vscode.makefile-tools",
6+
"charliermarsh.ruff"
7+
]
88
}

.vscode/settings.json

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
{
2-
"python.linting.pylintEnabled": false,
3-
"python.linting.flake8Enabled": true,
4-
"python.linting.flake8Args": ["--config", "${workspaceFolder}/.flake8"],
5-
"python.linting.enabled": true,
6-
"python.testing.pytestEnabled": true,
7-
"python.testing.unittestEnabled": false,
8-
"python.defaultInterpreterPath": "${workspaceFolder}/.venv/bin/python",
9-
"python.analysis.extraPaths": ["${workspaceFolder}/src"],
10-
"python.envFile": "${workspaceFolder}/.env",
11-
"[python]": {
12-
"editor.defaultFormatter": "ms-python.black-formatter"
13-
},
14-
"python.formatting.provider": "none"
2+
"python.linting.pylintEnabled": false,
3+
"python.linting.flake8Enabled": false,
4+
"python.linting.enabled": true,
5+
"python.testing.pytestEnabled": true,
6+
"python.testing.unittestEnabled": false,
7+
"python.defaultInterpreterPath": "${workspaceFolder}/.venv/bin/python",
8+
"python.analysis.extraPaths": ["${workspaceFolder}/src"],
9+
"python.envFile": "${workspaceFolder}/.env",
10+
"[python]": {
11+
"editor.defaultFormatter": "charliermarsh.ruff"
12+
}
1513
}

README.md

Lines changed: 38 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,26 @@
11
# Example Python Project
22

33
This is how I like to lay my Python projects out. You don't have to do it
4-
this way, but this way works for me. If you think it's bad or out of date
5-
feel free to create an issue or even a pull request.
4+
this way, but this way works for me.
5+
6+
You can use it as a template, if you're reading this on GitHub then push the
7+
"Use this template" button
68

79
## To run me
810

911
make dev
1012

11-
Then open the project dir in Visual Studio code, if you like to use an IDE.
13+
Then open the project dir in Visual Studio code, if you like to use an IDE. I
14+
only use it for debugging my tests, I use `vim` most of the time.
1215

1316
## Project structure
1417

1518
### Makefile
1619

1720
I like to use a `Makefile` to install my dependencies, build env, run tests
18-
and create packages. I get tab completion and it doesn't matter what CI
19-
platform I use, I just run `make stuff` and let GNU Make deal with it.
21+
and create packages. I get tab completion in my IDE and it doesn't matter what
22+
CI platform I use, I just run `make stuff` and let GNU Make deal with it.
23+
2024
`Makefile`s are of course an ancient curse, but if you don't use them you'll
2125
have to live in interesting times, which is a far worse curse.
2226

@@ -43,35 +47,39 @@ do.
4347

4448
### Linting and commit checks
4549

46-
I'm using `ruff` now for formatting and linting.
50+
I'm using `ruff` now for formatting and linting, dropping the `flake8`, `black`
51+
and `isort` mess that I used before.
4752

4853
Part of the `make dev` setup installs `pre-commit`, which will make sure that
4954
commits are up to a certain standard. The provided config file runs the code
50-
formatters, linters and a few other checks. Have a look at
51-
`.pre-commit-config.yaml` to see what's going on in there. pre-commit is very
52-
slow and very annoying, but it forces code quality on us which makes up for the
53-
inconvenience.
55+
formatters, linters and a few other checks. Read `.pre-commit-config.yaml` and
56+
see what's going on in there. `pre-commit` is very slow and very annoying, but
57+
it forces code quality on us which mostly makes up for the inconvenience of it
58+
blocking your commits.
59+
60+
You can use `git commit -n` to skip the pre-commit tests.
5461

5562
### IDE
5663

57-
I'm using VS Code when I use an IDE because it works everywhere and supports
58-
all the things that I need. I commit my config to source control so
59-
anyone can open the project dir and start hacking with a working debugger and
60-
tests auto-detected. This is a nice new paradigm where the IDE settings don't
61-
belong to the user, they belong to the project, so it's appropriate to put
62-
them in source control. If your
64+
I'm using VS Code when I use an IDE. It works everywhere and supports all the
65+
things that I need. I commit my config to source control so anyone can open the
66+
project dir and start hacking with a working debugger and tests auto-detected.
67+
68+
This modern paradigm where the IDE settings belong to the project rather than
69+
the user means it's appropriate to put them in source control. If your
70+
colleagues disagree, they're wrong.
6371

6472
The config also provides recommendations for extensions, which you'll be
6573
prompted to install when you open the project for the first time.
6674

6775
I could (and sometimes do) go one step further and use devcontainers, but at
68-
time of writing it's still a bit fiddly to get set up.
76+
time of writing it's still a bit fiddly to get set up. Plus I've not been stuck
77+
in Windows for a while. If you're in Windows, install WSL and get a proper
78+
console.
6979

7080
### Package layout
7181

72-
Under the `example_package` dir there's a `pyproject.toml` that defines the
73-
package and its dependencies. Then there's `src` and `test` dirs that contain
74-
the code and tests.
82+
There's a `pyproject.toml` here at the root dependencies.
7583

7684
The layout is as-per the pypi packaging guidelines. When referencing stuff in
7785
the code I tend to use the full `package.module` names because otherwise imports
@@ -96,23 +104,16 @@ Run `make coverage` for a test coverage report.
96104
### CI and CD
97105

98106
There's a couple of workflows in the `.github` dir, one to run the unit tests
99-
and one to release the project to pypi. The first
100-
101-
The release process runs whenever you
102-
push tag changes to GitHub.
103-
104-
Before the release process will work you
105-
need to get a key from pypi and add
106-
107-
there's a couple of workflows, one that runs the
108-
`make test` any time a commit is pushed. This
107+
and one to release the project to pypi. The unit tests one runs on every push,
108+
the release one runs on
109109

110110
### Documentation
111111

112112
You'll see a `mkdocs` config in the root. This is combined with the `make docs`
113-
script to make the github pages documentation for the project. If you look at
114-
this README.md file you'll see it's actually a symlink to the one in the package
115-
dir, and it's also symlinked from
113+
script to make the github pages documentation for the project.
114+
115+
I don't use this anymore as I have my own docs script for my website - it
116+
pushes a new commit to my github pages website. If I remember to, I'll
116117

117118
## Some opinionated stuff
118119

@@ -127,6 +128,9 @@ stubs, test data, functional and integration tests, infrastructure code,
127128
architecture diagrams and specs - everything you need to actually understand
128129
the project in one place.
129130

131+
Unfortunately you can't `pip install` a path within a git repository, so
132+
everything is still at the root in this one.
133+
130134
## Docs in Markdown
131135

132136
Did you know that you can add a `README.md` to any dir and it'll get rendered
@@ -138,3 +142,4 @@ general rule, up to a point anyway. The project wiki is somewhere else, it goes
138142
out of sync, it's difficult to see what the docs were on a specific release
139143
tag. Docs in the codebase can be edited alongside new features and have a much
140144
richer history.
145+

pyproject.toml

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,28 @@ authors = [
66
{ name = "Random Hacker", email = "no@dev.null" }
77
]
88
readme = "README.md"
9+
requires-python = ">=3.10"
910

10-
dependencies = [
11-
]
11+
[project.dependencies]
1212

1313
[project.optional-dependencies]
1414
dev = [
15-
"flake8",
1615
"pre-commit",
1716
"pytest",
1817
"coverage",
1918
"pytest-cov",
2019
"build",
21-
"twine"
20+
"twine",
21+
"ruff"
2222
]
2323

2424
[build-system]
2525
build-backend = "flit_core.buildapi"
2626
requires = ["flit_core >=3.2,<4"]
27-
[tool.isort]
28-
profile = "black"
2927

28+
[tool.ruff]
29+
line-length = 120
30+
target-version = "py310"
31+
32+
[tool.ruff.format]
33+
docstring-code-format = true

scripts/install-dev.sh

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
11
#!/usr/bin/env bash
22

3-
# activate venv
43
source .venv/bin/activate
4+
: "${PIP:=python3 -m pip}"
55

66
set -e
7+
$PIP install -e .[dev]
78

8-
# install our package
9-
python3 -m pip install -e .[dev]
10-
11-
# let make know that we are installed in user mode
129
echo "Installed in dev mode"
1310
touch .venv/.installed-dev
14-
rm .venv/.installed || true
11+
rm .venv/.installed 2>/dev/null || true

scripts/install.sh

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,11 @@
11
#!/usr/bin/env bash
22

3-
# activate venv
43
source .venv/bin/activate
4+
: "${PIP:=python3 -m pip}"
55

66
set -e
7+
$PIP install .
78

8-
# install our package
9-
python3 -m pip install .
10-
11-
# let make know that we are installed in user mode
129
echo Installed normally
13-
1410
touch .venv/.installed
15-
rm .venv/.installed-dev || true
16-
11+
rm .venv/.installed-dev 2>/dev/null || true

scripts/venv.sh

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
#!/usr/bin/env bash
22

3-
# create the python virtual environment
43
python3 -m venv .venv
5-
6-
# activate it
74
source .venv/bin/activate
5+
6+
if command -v uv >/dev/null 2>&1; then
7+
export PIP="uv pip"
8+
else
9+
export PIP="python3 -m pip"
10+
fi

0 commit comments

Comments
 (0)