Skip to content

Commit d5d66b7

Browse files
authored
Merge pull request #1 from SFTtech/milo/tooling-bootstrap
tooling bootstrap - ci, devcontainer, linting and testing toolchains
2 parents d142416 + 0865e0d commit d5d66b7

File tree

25 files changed

+596
-80
lines changed

25 files changed

+596
-80
lines changed

.devcontainer/Dockerfile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1-
FROM mcr.microsoft.com/devcontainers/base:noble
1+
ARG DISTRO=trixie
2+
FROM mcr.microsoft.com/devcontainers/base:${DISTRO}
23

4+
# enable deb-src repositories for apt source to work
5+
RUN sed -i -e 's/Types: deb/Types: deb deb-src/g' /etc/apt/sources.list.d/debian.sources
36
# install everything required for debian package building
47
RUN apt-get update && apt-get -y install build-essential python3 python3-pip curl debhelper devscripts dh-python
58
RUN echo "/workspaces/debmagic/src" > /usr/lib/python3/dist-packages/debmagic.pth

.devcontainer/devcontainer.json

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
2-
// README at: https://github.com/devcontainers/templates/tree/main/src/ubuntu
2+
// README at: https://github.com/devcontainers/templates/tree/main/src/debian
33
{
4-
"name": "Ubuntu",
4+
"name": "Debian Trixie",
55
"build": {
6-
"dockerfile": "Dockerfile"
6+
"dockerfile": "Dockerfile",
7+
"args": {
8+
"DISTRO": "trixie"
9+
}
710
},
8-
"postCreateCommand": "uv sync",
11+
"postCreateCommand": "./.devcontainer/post-create.sh",
912

1013
// Configure tool-specific properties.
1114
"customizations": {
@@ -16,5 +19,9 @@
1619
"tamasfe.even-better-toml"
1720
]
1821
}
19-
}
22+
},
23+
// make sure we always mount the project at the same path in the container to have our debmagic.pth symlinking
24+
// work properly to allow the debmagic package to be globally installed in the system python environment
25+
"workspaceMount": "source=${localWorkspaceFolder},target=/workspaces/debmagic,type=bind,consistency=uncached",
26+
"workspaceFolder": "/workspaces/debmagic"
2027
}

.devcontainer/post-create.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/usr/bin/env bash
2+
3+
uv sync
4+
uv run pre-commit install

.github/workflows/ci.yml

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
name: CI
2+
3+
permissions: {}
4+
5+
on:
6+
pull_request:
7+
types: [opened, synchronize]
8+
push:
9+
branches:
10+
- main
11+
12+
jobs:
13+
lint:
14+
runs-on: ubuntu-latest
15+
steps:
16+
- uses: actions/checkout@v5
17+
- name: Set up Python
18+
uses: actions/setup-python@v6
19+
with:
20+
python-version: "3.12"
21+
- name: Install uv
22+
uses: astral-sh/setup-uv@v6
23+
with:
24+
enable-cache: true
25+
- name: Install the project
26+
run: uv sync --locked --all-extras --dev
27+
- name: Run Ruff Lint
28+
run: uv run ruff check
29+
30+
typecheck:
31+
runs-on: ubuntu-latest
32+
steps:
33+
- uses: actions/checkout@v5
34+
- name: Set up Python
35+
uses: actions/setup-python@v6
36+
with:
37+
python-version: "3.12"
38+
- name: Install uv
39+
uses: astral-sh/setup-uv@v6
40+
with:
41+
enable-cache: true
42+
- name: Install the project
43+
run: uv sync --locked --all-extras --dev
44+
- name: Run Mypy
45+
run: uv run mypy .
46+
47+
format:
48+
runs-on: ubuntu-latest
49+
steps:
50+
- uses: actions/checkout@v5
51+
- name: Set up Python
52+
uses: actions/setup-python@v6
53+
with:
54+
python-version: "3.12"
55+
- name: Install uv
56+
uses: astral-sh/setup-uv@v6
57+
with:
58+
enable-cache: true
59+
- name: Install the project
60+
run: uv sync --locked --all-extras --dev
61+
- name: Run Ruff Format Check
62+
run: uv run ruff format --check
63+
64+
unit-tests:
65+
runs-on: ${{ matrix.os }}
66+
strategy:
67+
matrix:
68+
python-version:
69+
- "3.12"
70+
- "3.13"
71+
os: [ubuntu-latest]
72+
steps:
73+
- uses: actions/checkout@v5
74+
- name: Set up Python
75+
uses: actions/setup-python@v6
76+
with:
77+
python-version: "3.12"
78+
- name: Install uv
79+
uses: astral-sh/setup-uv@v6
80+
with:
81+
enable-cache: true
82+
- name: Install the project
83+
run: uv sync --locked --all-extras --dev
84+
- name: Run Unittests
85+
run: uv run pytest tests/unit --cov=debmagic
86+
87+
# TODO: integration tests currently don't work in the CI since they require running apt source on debian trixie -> CI runs on ubuntu
88+
# integration-tests:
89+
# runs-on: ${{ matrix.os }}
90+
# strategy:
91+
# matrix:
92+
# python-version:
93+
# - "3.12"
94+
# - "3.13"
95+
# os: [ubuntu-latest]
96+
# steps:
97+
# - uses: actions/checkout@v5
98+
# - name: Set up Python
99+
# uses: actions/setup-python@v6
100+
# with:
101+
# python-version: "3.12"
102+
# - name: Install uv
103+
# uses: astral-sh/setup-uv@v6
104+
# with:
105+
# enable-cache: true
106+
# - name: Install the project
107+
# run: uv sync --locked --all-extras --dev
108+
# - name: Run Integrationtests
109+
# run: uv run pytest tests/integration

.gitignore

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,3 @@
1-
# project specific
2-
config.yaml
3-
config.devcontainer.yml
4-
server.yaml
5-
61
# python
72
__pycache__
83
*.pyc
@@ -23,8 +18,6 @@ __pycache__
2318
pyvenv.cfg
2419
venv*
2520
.venv
26-
.pdm-python
27-
.python-version
2821

2922
# building
3023
MANIFEST
@@ -33,7 +26,6 @@ src/*/*.lock
3326

3427
# testing
3528
/*.conf
36-
/*.yaml
3729
/test
3830
/build
3931

.pre-commit-config.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
repos:
2+
- repo: https://github.com/astral-sh/ruff-pre-commit
3+
rev: v0.14.6
4+
hooks:
5+
- id: ruff-check
6+
args: [ --fix ]
7+
- id: ruff-format

README.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,56 @@
33
Debian build instructions written in Python.
44

55
> Explicit is better than implicit.
6+
7+
```python
8+
#!/usr/bin/env python3
9+
10+
from debmagic.v0 import Build, package
11+
from debmagic.v0 import autotools as autotools_mod
12+
from debmagic.v0 import dh as dh_mod
13+
14+
autotools = autotools_mod.Preset()
15+
dh = dh_mod.Preset()
16+
17+
pkg = package(
18+
preset=[dh, autotools],
19+
maint_options="hardening=+all",
20+
)
21+
22+
@pkg.stage
23+
def configure(build: Build):
24+
autotools_mod.autoreconf(build)
25+
autotools.configure(
26+
build,
27+
["--enable-something"],
28+
)
29+
30+
31+
@dh.override
32+
def dh_installgsettings(build: Build):
33+
print("test dh override works :)")
34+
build.cmd("dh_installgsettings")
35+
36+
37+
@pkg.custom_function
38+
def something_custom(some_param: int, another_param: str = "some default"):
39+
print(f"you called {some_param=} {another_param=}")
40+
41+
42+
pkg.pack()
43+
```
44+
45+
## Developing
46+
47+
Prerequisites:
48+
49+
- Debian >= trixie, either roll your own environment or to get started faster use the [devcontainer](https://containers.dev/)
50+
- Python >= 3.12
51+
- [UV](https://docs.astral.sh/uv/)
52+
53+
Setup:
54+
55+
```bash
56+
uv sync
57+
uv run pre-commit install
58+
```

debian/rules

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
#!/usr/bin/env python3
22

3-
from pathlib import Path
43
import sys
4+
from pathlib import Path
55

66
repo_root = Path(__file__).parent.parent / "src"
77
sys.path.append(str(repo_root))
88

99
from debmagic.v1 import package, python
1010

11-
1211
package(
1312
preset=python,
1413
)

pyproject.toml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,20 @@ requires = ["setuptools>=77.0.0", "setuptools-scm"]
2222
build-backend = "setuptools.build_meta"
2323

2424
[dependency-groups]
25-
dev = ["pytest>=8.4.2"]
25+
dev = ["pytest>=9.0.1", "pytest-cov>=7.0.0", "ruff", "pre-commit", "mypy"]
2626

2727
[tool.mypy]
2828
mypy_path = '$MYPY_CONFIG_FILE_DIR/src'
29+
exclude_gitignore = true
2930

3031
[tool.ruff]
3132
line-length = 120
3233
target-version = "py312"
33-
exclude = [".git", ".idea", ".mypy_cache", ".venv*", "docs"]
34+
exclude = [".git", ".idea", ".mypy_cache", ".venv*", "docs", "debian"]
3435

3536
[tool.ruff.lint]
3637
select = ["E4", "E7", "E9", "F", "I", "PLE", "PLW"]
3738
ignore = ["E722"]
39+
40+
[tool.pytest]
41+
testpaths = ["tests"]

src/debmagic/_build.py

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ def cmd(self, cmd: list[str] | str, **kwargs):
3636
execute a command, auto-converts command strings/lists.
3737
use this to supports build dry-runs.
3838
"""
39-
cmd_args : list[str] | str = cmd
39+
cmd_args: list[str] | str = cmd
4040
is_shell = kwargs.get("shell")
4141
if not is_shell and isinstance(cmd, str):
4242
cmd_args = shlex.split(cmd)
@@ -47,14 +47,11 @@ def cmd(self, cmd: list[str] | str, **kwargs):
4747

4848
@property
4949
def install_dirs(self) -> dict[str, Path]:
50-
""" return { binary_package_name: install_directory } """
51-
return {
52-
pkg.name: self.install_base_dir / pkg.name
53-
for pkg in self.binary_packages
54-
}
50+
"""return { binary_package_name: install_directory }"""
51+
return {pkg.name: self.install_base_dir / pkg.name for pkg in self.binary_packages}
5552

5653
def select_packages(self, names: set[str]):
57-
""" only build those packages """
54+
"""only build those packages"""
5855
if not names:
5956
self._selected_packages = None
6057

@@ -64,9 +61,8 @@ def select_packages(self, names: set[str]):
6461
self._selected_packages.append(pkg)
6562

6663
def filter_packages(self, package_filter: PackageFilter) -> None:
67-
""" apply filter to only build those packages """
68-
self.select_packages({pkg.name for pkg in
69-
package_filter.get_packages(self.binary_packages)})
64+
"""apply filter to only build those packages"""
65+
self.select_packages({pkg.name for pkg in package_filter.get_packages(self.binary_packages)})
7066

7167
def is_stage_completed(self, stage: BuildStage) -> bool:
7268
return stage in self._completed_stages
@@ -90,7 +86,7 @@ def run(
9086

9187
# run stage function from debian/rules.py
9288
if rules_stage_function := self.source_package.stage_functions.get(stage):
93-
print(f"debmagic: running stage from rules file...")
89+
print("debmagic: running stage from rules file...")
9490
rules_stage_function(self)
9591
self._mark_stage_done(stage)
9692

0 commit comments

Comments
 (0)