Skip to content

Commit 8176104

Browse files
committed
Initial commit
0 parents  commit 8176104

File tree

8 files changed

+404
-0
lines changed

8 files changed

+404
-0
lines changed
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
name: Build all packages
2+
on:
3+
workflow_dispatch:
4+
inputs:
5+
changelog_message:
6+
description: 'Changelog message to add (in addition to "Rebuild for...")'
7+
type: string
8+
9+
jobs:
10+
native:
11+
runs-on: ubuntu-latest
12+
name: Build native packages
13+
14+
steps:
15+
- uses: actions/checkout@v4
16+
17+
- name: Set up Docker Buildx
18+
uses: docker/setup-buildx-action@v3
19+
with:
20+
driver-opts: env.BUILDKIT_STEP_LOG_MAX_SIZE=4194304
21+
22+
- name: Generate Bake override file
23+
run: |
24+
cat <<EOF > docker-bake.override.hcl
25+
target "github_output" {
26+
contexts = {
27+
native = "target:native"
28+
}
29+
dockerfile-inline = <<-EOT
30+
FROM debian:bookworm-slim AS github_output
31+
COPY --from=native /github_outpu[t] /github_output
32+
EOT
33+
inherits = ["native"]
34+
output = ["type=docker"]
35+
tags = ["github_output"]
36+
target = "github_output"
37+
}
38+
EOF
39+
40+
- name: Build the Docker image
41+
uses: docker/bake-action@v4
42+
env:
43+
NAME: "${{ secrets.changelog_name }}"
44+
EMAIL: "${{ secrets.changelog_email }}"
45+
CHANGE: "${{ inputs.changelog_message }}"
46+
with:
47+
targets: native, github_output
48+
set: |
49+
*.cache-from=type=gha
50+
*.cache-to=type=gha,mode=max
51+
52+
- name: Output GA specific messages
53+
run: docker run --rm github_output bash -c "touch /github_output && cat /github_output"
54+
55+
- uses: actions/upload-artifact@v4
56+
with:
57+
name: native-debs
58+
path: artifacts
59+
60+
crossbuild:
61+
runs-on: ubuntu-latest
62+
name: Crossbuild packages
63+
needs: native
64+
strategy:
65+
matrix:
66+
arch: [armhf, arm64]
67+
68+
steps:
69+
- uses: actions/checkout@v4
70+
71+
- name: Set up Docker Buildx
72+
uses: docker/setup-buildx-action@v3
73+
with:
74+
driver-opts: env.BUILDKIT_STEP_LOG_MAX_SIZE=4194304
75+
76+
- name: Build the Docker image
77+
uses: docker/bake-action@v4
78+
env:
79+
NAME: "${{ secrets.changelog_name }}"
80+
EMAIL: "${{ secrets.changelog_email }}"
81+
CHANGE: "${{ inputs.changelog_message }}"
82+
with:
83+
targets: crossbuild-${{ matrix.arch }}
84+
set: |
85+
*.cache-from=type=gha
86+
*.cache-to=type=gha,mode=max
87+
88+
- uses: actions/upload-artifact@v4
89+
with:
90+
name: crossbuild-${{ matrix.arch }}-debs
91+
path: artifacts

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
artifacts

Dockerfile

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
# syntax=docker/dockerfile:1
2+
ARG PYTHON_NAME="python3.12"
3+
ARG PYTHON_VERSION="3.12.2-1"
4+
ARG DIST_NAME="trixie"
5+
6+
# -------------------- Preparation --------------------
7+
FROM debian:bookworm-slim AS pre-build
8+
ARG DIST_NAME
9+
RUN echo "\
10+
Types: deb-src\n\
11+
URIs: http://deb.debian.org/debian\n\
12+
Suites: ${DIST_NAME}\n\
13+
Components: main\n\
14+
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg" \
15+
> /etc/apt/sources.list.d/${DIST_NAME}-src.sources
16+
RUN apt-get update && \
17+
apt-get upgrade -y && \
18+
apt-get install -y --no-install-recommends devscripts equivs
19+
20+
# -------------------- Source preperation --------------------
21+
FROM pre-build AS source
22+
ARG PYTHON_NAME
23+
ARG PYTHON_VERSION
24+
WORKDIR /usr/local/src
25+
RUN apt-get source --download-only ${PYTHON_NAME}=${PYTHON_VERSION} && \
26+
dpkg-source -x --skip-patches ${PYTHON_NAME}*.dsc && \
27+
mv ${PYTHON_NAME}*/ python-source
28+
WORKDIR python-source
29+
ADD ensurepip-enabled.diff debian/patches
30+
RUN sed -i '/^ensurepip-disabled.diff$/s/^/#/' debian/patches/series && \
31+
echo 'ensurepip-enabled.diff' >> debian/patches/series
32+
33+
ADD changelog_previous .
34+
RUN if [ -s changelog_previous ]; then echo "$(cat changelog_previous)\n\
35+
\n\
36+
$(cat debian/changelog)" > debian/changelog; fi
37+
ARG NAME
38+
ARG EMAIL
39+
ARG CHANGE
40+
RUN dch --bpo "$CHANGE"
41+
42+
# -------------------- Build preperation --------------------
43+
FROM pre-build AS build-system
44+
# These packages would be installed by mk-build-deps for all architectures
45+
# so make sure they are only downloaded once
46+
# This command is allowed to fail however if something changes in the future
47+
RUN apt-get install -y --no-install-recommends \
48+
diffstat docutils-common ed fontconfig-config fonts-dejavu-core libbrotli1 \
49+
libbsd0 libc-l10n libdrm-amdgpu1 libdrm-common libdrm-intel1 libdrm-nouveau2 \
50+
libdrm-radeon1 libdrm2 libedit2 libfontconfig1 libfontenc1 libfreetype6 libgl1 \
51+
libgl1-mesa-dri libglapi-mesa libglvnd0 libglx-mesa0 libglx0 libice6 \
52+
libjs-jquery libjs-sphinxdoc libjs-underscore libjson-perl libllvm15 \
53+
libpciaccess0 libpixman-1-0 libpkgconf3 libpng16-16 libsensors-config \
54+
libsensors5 libsm6 libtcl8.6 libtext-unidecode-perl libtk8.6 libunwind8 \
55+
libx11-6 libx11-data libx11-xcb1 libxau6 libxaw7 libxcb-dri2-0 libxcb-dri3-0 \
56+
libxcb-glx0 libxcb-present0 libxcb-randr0 libxcb-shm0 libxcb-sync1 \
57+
libxcb-xfixes0 libxcb1 libxdmcp6 libxext6 libxfixes3 libxfont2 libxft2 \
58+
libxkbfile1 libxml-libxml-perl libxml-namespacesupport-perl \
59+
libxml-sax-base-perl libxml-sax-perl libxmu6 libxmuu1 libxpm4 libxrandr2 \
60+
libxrender1 libxshmfence1 libxss1 libxt6 libxxf86vm1 libz3-4 locales-all \
61+
lsb-release net-tools pkgconf-bin python-babel-localedata python3-alabaster \
62+
python3-babel python3-certifi python3-chardet python3-charset-normalizer \
63+
python3-distutils python3-docs-theme python3-docutils python3-idna \
64+
python3-imagesize python3-jinja2 python3-lib2to3 python3-markupsafe \
65+
python3-packaging python3-pkg-resources python3-pygments python3-requests \
66+
python3-roman python3-six python3-snowballstemmer python3-sphinx python3-tz \
67+
python3-urllib3 quilt sgml-base sharutils sphinx-common tcl tcl8.6 tex-common \
68+
texinfo time tk tk8.6 ucf x11-common x11-xkb-utils x11proto-core-dev \
69+
x11proto-dev xauth xkb-data xml-core xorg-sgml-doctools xserver-common \
70+
xtrans-dev xvfb || \
71+
echo "::warning::Loading packages failed!" | tee -a /github_output
72+
COPY --from=source /usr/local/src/python-source /usr/local/src/python-source
73+
WORKDIR /usr/local/src/python-source
74+
75+
# -------------------- Build native architecture --------------------
76+
FROM build-system AS native
77+
RUN mk-build-deps --install --tool 'apt-get -y --no-install-recommends'
78+
79+
RUN debuild -b -uc -us
80+
RUN mkdir debs && mv ../*.deb debs
81+
82+
# -------------------- Export native build artifacts --------------------
83+
FROM scratch AS native-binaries
84+
ARG PYTHON_NAME
85+
COPY --from=native /usr/local/src/python-source/debs/. /usr/local/src/${PYTHON_NAME}*.build /usr/local/src/${PYTHON_NAME}*.buildinfo /
86+
87+
# -------------------- Crossbuild foreign architectures --------------------
88+
FROM build-system AS crossbuild
89+
ARG ARCH
90+
RUN [ ! -z "${ARCH}" ]
91+
RUN dpkg --add-architecture ${ARCH}
92+
RUN apt-get update
93+
94+
ADD crossbuild-dep.diff .
95+
RUN patch -p1 < crossbuild-dep.diff
96+
97+
COPY --from=native /usr/local/src/python-source/debs native-debs
98+
ARG PYTHON_NAME
99+
RUN cd native-debs && apt-get install -y ./lib${PYTHON_NAME}-minimal*.deb \
100+
./lib${PYTHON_NAME}-stdlib*.deb \
101+
./lib${PYTHON_NAME}_*.deb \
102+
./${PYTHON_NAME}-minimal*.deb \
103+
./${PYTHON_NAME}_*.deb
104+
105+
RUN mk-build-deps --arch ${ARCH} --host-arch ${ARCH}
106+
# We don't need build-essential for cross-compiling, but mk-build-deps insists of adding it
107+
# Hacky way to remove that:
108+
RUN mkdir rebuild-cross-deps && \
109+
dpkg-deb -R ${PYTHON_NAME}-cross-build-deps*.deb rebuild-cross-deps && \
110+
sed -i 's/build-essential:[^ ]* //' rebuild-cross-deps/DEBIAN/control && \
111+
dpkg-deb -b rebuild-cross-deps
112+
RUN apt-get install -y --no-install-recommends ./rebuild-cross-deps.deb
113+
114+
RUN DEB_BUILD_OPTIONS='nocheck nobench' debuild -b -uc -us -a${ARCH} --ignore-builtin-builddeps
115+
RUN mkdir debs && mv ../*.deb debs
116+
117+
# -------------------- Export crossbuild artifacts --------------------
118+
FROM scratch AS crossbuild-binaries
119+
ARG PYTHON_NAME
120+
COPY --from=crossbuild /usr/local/src/python-source/debs/. /usr/local/src/${PYTHON_NAME}*.build /usr/local/src/${PYTHON_NAME}*.buildinfo /

README.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# Python 3.12 backport for Debian 12 bookworm
2+
The aim of this project is to provide a Python 3.12 backport to Debian bookworm. Packages are of course much better manageable than compiling the source from scratch. In my opinion it is also more manageable than using `pyenv`. By using my packages you will also be sure to get the latest patches (on a best effort basis).
3+
4+
Motivation for this project was the [removal of Python 3.11 support in Home Assistant 2024.4](https://github.com/home-assistant/core/pull/108160). Debian bookworm doesn't have Python 3.12 however.
5+
6+
## Scope
7+
The scope of this project is limited to backporting just Python 3.12 itself. So no defaults (which provide virtual packages so `python3` get's automatically linked to `python3.12`) and no precompiled pip-packages or wheels besides pip itself. Therefore it can coexist with your regular Python (3.11) installation without any interference and still being simple to maintain. It's main use is for in virtual environments where you can use pip to compile and install any packages you desire. It does provide all the packages and dependencies needed to create a Python 3.12 virtual environment.
8+
9+
Because the version of pip present in Debian 12 bookworm isn't compatible with Python 3.12, I've included pip inside the Python package. Normally pip on Debian is inside the `python3-pip` package, but backporting that would clash with an existing pip installation. This is the easiest solution for now.
10+
11+
## Repository
12+
Packages can be downloaded from my repository at `deb.pascalroeleven.nl`. First you should also add my PGP (which you can get from my website via https) to APT's sources keyring:
13+
```sh
14+
wget -qO- https://pascalroeleven.nl/deb-pascalroeleven.gpg | sudo tee /etc/apt/trusted.gpg.d/deb-pascalroeleven.gpg
15+
```
16+
17+
Now you can add my repository by adding a file with my repository to the `sources.list.d` directory:
18+
```sh
19+
cat <<EOF
20+
Types: deb
21+
URIs: http://deb.pascalroeleven.nl/python3.12
22+
Suites: bookworm-backports
23+
Components: main
24+
Signed-By: /etc/apt/trusted.gpg.d/deb-pascalroeleven.gpg
25+
EOF
26+
| sudo tee /etc/apt/sources.list.d/pascalroeleven.sources
27+
```
28+
29+
After running `apt update` you should now be able to install Python 3.12 related packages.
30+
31+
Packages are built using Github Actions along with a file containing the checksums of all packages. Therefore, you can compare the checksums of the packages in the repository with the checksums in Github Actions and trace the entire process (up to 90 days after the build after which the artifacts and logs get removed). This way, if you trust the Github Actions build system, you can be sure that the packages I provide are actually built using the instructions in this repo.
32+
33+
## Support
34+
Currently there is support for **`amd64`**, **`arm64`** and **`armhf`** architectures. The `amd64` packages are build natively while the `arm64` and `armhf` packages are crossbuilt. Testing is not possible while crossbuilding, so these packages did not undergo the same amount of testing as usual Debian packages do.
35+
36+
## Building the packages yourself
37+
If you want to build the packages yourself, you can use the Dockerfile and the patches in this repository. Patches will be applied by the Dockerfile. Buildkit is required.
38+
39+
Packages are built using the `buildx bake` command. The following targets are supported: `native`, `crossbuild`, `crossbuild-armhf` and `crossbuild-arm64`. Supplying no target or `default` will build all packages. Build artifacts are extracted to the `artifacts` folder (will be created automatically).
40+
41+
```sh
42+
docker buildx bake default
43+
```
44+
45+
You can supply the following environment variables to modify the changelog: `NAME`, `EMAIL` and `CHANGE` (for an additional message in the changelog besides "Rebuild for bookworm-backports").
46+
47+
```sh
48+
NAME="James Smith" EMAIL="[email protected]" CHANGE="Fixed some bug somewhere" docker buildx bake default
49+
```
50+
51+
Building natively takes about 2 hours on a modern decent PC because of the extensive testing. Cross building takes about 30 minutes (but uses native binaries so requires the extra 2 hours the first time).

changelog_previous

Whitespace-only changes.

crossbuild-dep.diff

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
diff -u a/debian/control b/debian/control
2+
--- a/debian/control
3+
+++ b/debian/control
4+
@@ -19,7 +19,7 @@
5+
net-tools, xvfb <!nocheck>, xauth <!nocheck>, tzdata <!nocheck>,
6+
systemtap-sdt-dev [!hurd-amd64 !hurd-i386],
7+
valgrind-if-available,
8+
-Build-Depends-Indep: python3-sphinx, python3-docs-theme, texinfo
9+
+Build-Depends-Indep: python3-sphinx:all, python3-docs-theme:all, texinfo
10+
Standards-Version: 4.6.2
11+
Vcs-Browser: https://salsa.debian.org/cpython-team/python3
12+
Vcs-Git: https://salsa.debian.org/cpython-team/python3.git
13+
14+
diff -u a/debian/rules b/debian/rules
15+
--- a/debian/rules
16+
+++ b/debian/rules
17+
@@ -1456,7 +1456,7 @@
18+
done
19+
20+
: # devhelp docs
21+
- cd $(buildd_static) && ./python ../debian/pyhtml2devhelp.py \
22+
+ cd $(buildd_static) && python3.12 ../debian/pyhtml2devhelp.py \
23+
../$(d_doc)/usr/share/doc/$(p_base)/html index.html $(VER) \
24+
> ../$(d_doc)/usr/share/doc/$(p_base)/html/$(PVER).devhelp
25+
gzip -9nv $(d_doc)/usr/share/doc/$(p_base)/html/$(PVER).devhelp

docker-bake.hcl

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
group "default" {
2+
targets = ["native","crossbuild"]
3+
}
4+
5+
variable "NAME" {
6+
default = "$NAME"
7+
}
8+
9+
variable "EMAIL" {
10+
default = "$EMAIL"
11+
}
12+
13+
variable "CHANGE" {
14+
default = "$CHANGE"
15+
}
16+
17+
target "base" {
18+
args = {
19+
NAME = NAME
20+
EMAIL = EMAIL
21+
CHANGE = CHANGE
22+
}
23+
output = ["type=local,dest=artifacts"]
24+
}
25+
26+
target "native" {
27+
inherits = ["base"]
28+
target = "native-binaries"
29+
}
30+
31+
target "crossbuild" {
32+
args = {
33+
ARCH = arch
34+
}
35+
inherits = ["base"]
36+
matrix = {
37+
arch = ["armhf", "arm64"]
38+
}
39+
name = "crossbuild-${arch}"
40+
target = "crossbuild-binaries"
41+
}

0 commit comments

Comments
 (0)