diff --git a/CHANGELOG.base.md b/CHANGELOG.base.md index 38ecb59..bba60ed 100644 --- a/CHANGELOG.base.md +++ b/CHANGELOG.base.md @@ -161,6 +161,7 @@ au [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - `make` and `make todo` go through `install.sh`, which picks an interpreter able to READ the code before running it: `.venv.erplibre` on the right version, else a recent enough system `python3`, else the install. A system older than `conf/python-erplibre-version` would otherwise stop on a syntax error raised before any guard could name the command to type. TODO then relaunches itself in `.venv.erplibre`, or offers to run `install_erplibre.sh` in a terminal - The production Docker image builds `.venv.erplibre` on Odoo's Python and stops when that Python cannot parse `script/` - Debian 11 is dropped from the deployment catalogue: its LTS ended, and its security suite is neither served nor archived — the index it still publishes names packages whose pool no longer holds the file, so apt stops before installing git. Debian 13 takes its place, its cloud image always being the latest point release +- Every container image is built on bookworm, whatever the Odoo version. The base is `python:-slim-`: the interpreter comes from the official image, never from Debian, and the bookworm variants exist down to 3.7.17. The wkhtmltopdf build follows the suite — bullseye's requires libssl1.1, absent from bookworm - The PATCH bounds only Odoo's venv, whose pyproject requires `>=3.12.10,<3.13`. For the tooling one, the major.minor is enough: requiring the patch turned away a distribution's Python one step behind — NixOS 25.11 ships 3.14.2 where conf asks 3.14.7 — and made pyenv COMPILE CPython for a difference nothing needs - `make format` picks the formatter from each file's context: an Odoo module keeps isort and black on `py37`, the series still supported going down that far, while this repository's own tooling goes through ruff, configured once in `.ruff.toml`. ruff follows CPython's versions, where black 24.8.0 stops at `py313`, and its import sorting replaces isort; it is also what the OCA standard uses since it left black - The repositories that Google Repo checks out under `script/` are excluded from that formatting, a named path included: reformatting them would write in someone else's history. `target-version` stays at `py310` there, because the git hooks carry `#!/usr/bin/env python3` and a distribution still ships 3.10 — from 3.14 on, ruff would write `except A, B:` without parentheses @@ -185,6 +186,7 @@ au [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - `make` et `make todo` passent par `install.sh`, qui choisit un interpréteur capable de LIRE le code avant de le lancer : `.venv.erplibre` s'il porte la bonne version, sinon le `python3` du système s'il est assez récent, sinon l'installation. Un système plus ancien que `conf/python-erplibre-version` s'arrêterait autrement sur une erreur de syntaxe levée avant qu'aucun garde puisse nommer la commande à taper. TODO se relance ensuite dans `.venv.erplibre`, ou propose de lancer `install_erplibre.sh` en terminal - L'image Docker de production bâtit `.venv.erplibre` sur le Python d'Odoo et s'arrête quand ce Python ne sait pas lire `script/` - Debian 11 quitte le catalogue de déploiement : son LTS est terminé, et sa suite de sécurité n'est ni servie ni archivée — l'index qu'elle publie encore nomme des paquets dont le pool ne porte plus le fichier, et apt s'arrête avant d'installer git. Debian 13 la remplace, son image cloud étant toujours le dernier point de version +- Toutes les images de conteneur reposent sur bookworm, quelle que soit la version d'Odoo. La base est `python:-slim-` : l'interpréteur vient de l'image officielle, jamais de Debian, et les variantes bookworm existent jusqu'à 3.7.17. Le build de wkhtmltopdf suit la version — celui de bullseye réclame libssl1.1, absente de bookworm - Le PATCH ne borne que le venv d'Odoo, dont le pyproject exige `>=3.12.10,<3.13`. Pour celui de l'outillage, la majeure.mineure suffit : exiger le patch écartait le Python d'une distribution d'un cran en retard — NixOS 25.11 livre 3.14.2 quand conf demande 3.14.7 — et faisait COMPILER CPython à pyenv pour une différence que rien ne réclame - `make format` choisit le formateur d'après le contexte de chaque fichier : un module Odoo garde isort et black en `py37`, la série la plus ancienne encore supportée, quand l'outillage de ce dépôt passe par ruff, réglé une fois dans `.ruff.toml`. ruff suit les versions de CPython, là où black 24.8.0 s'arrête à `py313`, et son tri d'imports remplace isort ; c'est aussi ce qu'emploie la norme OCA depuis qu'elle a quitté black - Les dépôts que Google Repo rapatrie sous `script/` sont écartés de ce formatage, chemin nommé compris : les reformater écrirait dans l'historique d'autrui. `target-version` y reste à `py310`, parce que les hooks git portent `#!/usr/bin/env python3` et qu'une distribution livre encore 3.10 — à partir de 3.14, ruff écrirait `except A, B:` sans parenthèses diff --git a/CHANGELOG.fr.md b/CHANGELOG.fr.md index 25fef03..c59cd77 100644 --- a/CHANGELOG.fr.md +++ b/CHANGELOG.fr.md @@ -83,6 +83,7 @@ au [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - `make` et `make todo` passent par `install.sh`, qui choisit un interpréteur capable de LIRE le code avant de le lancer : `.venv.erplibre` s'il porte la bonne version, sinon le `python3` du système s'il est assez récent, sinon l'installation. Un système plus ancien que `conf/python-erplibre-version` s'arrêterait autrement sur une erreur de syntaxe levée avant qu'aucun garde puisse nommer la commande à taper. TODO se relance ensuite dans `.venv.erplibre`, ou propose de lancer `install_erplibre.sh` en terminal - L'image Docker de production bâtit `.venv.erplibre` sur le Python d'Odoo et s'arrête quand ce Python ne sait pas lire `script/` - Debian 11 quitte le catalogue de déploiement : son LTS est terminé, et sa suite de sécurité n'est ni servie ni archivée — l'index qu'elle publie encore nomme des paquets dont le pool ne porte plus le fichier, et apt s'arrête avant d'installer git. Debian 13 la remplace, son image cloud étant toujours le dernier point de version +- Toutes les images de conteneur reposent sur bookworm, quelle que soit la version d'Odoo. La base est `python:-slim-` : l'interpréteur vient de l'image officielle, jamais de Debian, et les variantes bookworm existent jusqu'à 3.7.17. Le build de wkhtmltopdf suit la version — celui de bullseye réclame libssl1.1, absente de bookworm - Le PATCH ne borne que le venv d'Odoo, dont le pyproject exige `>=3.12.10,<3.13`. Pour celui de l'outillage, la majeure.mineure suffit : exiger le patch écartait le Python d'une distribution d'un cran en retard — NixOS 25.11 livre 3.14.2 quand conf demande 3.14.7 — et faisait COMPILER CPython à pyenv pour une différence que rien ne réclame - `make format` choisit le formateur d'après le contexte de chaque fichier : un module Odoo garde isort et black en `py37`, la série la plus ancienne encore supportée, quand l'outillage de ce dépôt passe par ruff, réglé une fois dans `.ruff.toml`. ruff suit les versions de CPython, là où black 24.8.0 s'arrête à `py313`, et son tri d'imports remplace isort ; c'est aussi ce qu'emploie la norme OCA depuis qu'elle a quitté black - Les dépôts que Google Repo rapatrie sous `script/` sont écartés de ce formatage, chemin nommé compris : les reformater écrirait dans l'historique d'autrui. `target-version` y reste à `py310`, parce que les hooks git portent `#!/usr/bin/env python3` et qu'une distribution livre encore 3.10 — à partir de 3.14, ruff écrirait `except A, B:` sans parenthèses diff --git a/CHANGELOG.md b/CHANGELOG.md index eb4e25f..0586dcb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -83,6 +83,7 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - `make` and `make todo` go through `install.sh`, which picks an interpreter able to READ the code before running it: `.venv.erplibre` on the right version, else a recent enough system `python3`, else the install. A system older than `conf/python-erplibre-version` would otherwise stop on a syntax error raised before any guard could name the command to type. TODO then relaunches itself in `.venv.erplibre`, or offers to run `install_erplibre.sh` in a terminal - The production Docker image builds `.venv.erplibre` on Odoo's Python and stops when that Python cannot parse `script/` - Debian 11 is dropped from the deployment catalogue: its LTS ended, and its security suite is neither served nor archived — the index it still publishes names packages whose pool no longer holds the file, so apt stops before installing git. Debian 13 takes its place, its cloud image always being the latest point release +- Every container image is built on bookworm, whatever the Odoo version. The base is `python:-slim-`: the interpreter comes from the official image, never from Debian, and the bookworm variants exist down to 3.7.17. The wkhtmltopdf build follows the suite — bullseye's requires libssl1.1, absent from bookworm - The PATCH bounds only Odoo's venv, whose pyproject requires `>=3.12.10,<3.13`. For the tooling one, the major.minor is enough: requiring the patch turned away a distribution's Python one step behind — NixOS 25.11 ships 3.14.2 where conf asks 3.14.7 — and made pyenv COMPILE CPython for a difference nothing needs - `make format` picks the formatter from each file's context: an Odoo module keeps isort and black on `py37`, the series still supported going down that far, while this repository's own tooling goes through ruff, configured once in `.ruff.toml`. ruff follows CPython's versions, where black 24.8.0 stops at `py313`, and its import sorting replaces isort; it is also what the OCA standard uses since it left black - The repositories that Google Repo checks out under `script/` are excluded from that formatting, a named path included: reformatting them would write in someone else's history. `target-version` stays at `py310` there, because the git hooks carry `#!/usr/bin/env python3` and a distribution still ships 3.10 — from 3.14 on, ruff would write `except A, B:` without parentheses diff --git a/script/docker/docker_build.sh b/script/docker/docker_build.sh index a615fd2..2572666 100755 --- a/script/docker/docker_build.sh +++ b/script/docker/docker_build.sh @@ -9,9 +9,6 @@ ODOO_VERSION=$(cat .odoo-version | xargs) PYTHON_VERSION=$(cat .python-odoo-version | xargs) POETRY_VERSION=$(cat .poetry-version | xargs) -IS_DEBIAN_BOOKWORM=true -IS_DEBIAN_BULLSEYE=true -# or IS_DEBIAN_BUSTER ARGS="" IS_RELEASE=false IS_RELEASE_ALPHA=false @@ -37,20 +34,12 @@ for arg in "$@"; do elif [ "$arg" == "--odoo_16" ]; then output_version=$(python ./script/version/get_version.py --odoo_version 16.0) elif [ "$arg" == "--odoo_15" ]; then - IS_DEBIAN_BOOKWORM=false - IS_DEBIAN_BULLSEYE=false output_version=$(python ./script/version/get_version.py --odoo_version 15.0) elif [ "$arg" == "--odoo_14" ]; then - IS_DEBIAN_BOOKWORM=false - IS_DEBIAN_BULLSEYE=false output_version=$(python ./script/version/get_version.py --odoo_version 14.0) elif [ "$arg" == "--odoo_13" ]; then - IS_DEBIAN_BOOKWORM=false - IS_DEBIAN_BULLSEYE=false output_version=$(python ./script/version/get_version.py --odoo_version 13.0) elif [ "$arg" == "--odoo_12" ]; then - IS_DEBIAN_BOOKWORM=false - IS_DEBIAN_BULLSEYE=false output_version=$(python ./script/version/get_version.py --odoo_version 12.0) fi done @@ -100,13 +89,18 @@ cd docker ARGS="${ARGS} --build-arg WORKING_BRANCH=$(git rev-parse --abbrev-ref HEAD) --build-arg WORKING_HASH=$(git rev-parse --verify HEAD)" -if [ "$IS_DEBIAN_BOOKWORM" == true ]; then - ARGS="${ARGS} --build-arg DEBIAN_NAME=bookworm --build-arg URL_WKHTMLTOX=github.com/wkhtmltopdf/packaging/releases/download/0.12.6.1-3/wkhtmltox_0.12.6.1-3.bookworm_amd64.deb --build-arg SHA1SUM_WKTHMLTOX=e9f95436298c77cc9406bd4bbd242f4771d0a4b2" -elif [ "$IS_DEBIAN_BOOKWORM" != true ]; then - ARGS="${ARGS} --build-arg DEBIAN_NAME=bullseye --build-arg URL_WKHTMLTOX=github.com/wkhtmltopdf/packaging/releases/download/0.12.6.1-2/wkhtmltox_0.12.6.1-2.bullseye_amd64.deb --build-arg SHA1SUM_WKTHMLTOX=cecbf5a6abbd68d324a7cd6c51ec843d71e98951" -elif [ "$IS_DEBIAN_BULLSEYE" != true ]; then - ARGS="${ARGS} --build-arg DEBIAN_NAME=buster --build-arg URL_WKHTMLTOX=github.com/wkhtmltopdf/packaging/releases/download/0.12.6-1/wkhtmltox_0.12.6-1.buster_amd64.deb --build-arg SHA1SUM_WKTHMLTOX=d9f259a67e05e1c221d48b504453645e6c491fab" -fi +# UNE seule base, bookworm, pour toutes les versions d'Odoo. +# +# La base est « python:-slim- » : le Python vient de l'image +# officielle, jamais de Debian. Changer de nom de version ne change donc pas +# l'interpréteur, et les variantes bookworm existent jusqu'à 3.7.17 — vérifié +# sur le registre. Rien n'obligeait les vieux Odoo à rester sur bullseye, dont +# le dépôt de sécurité est aujourd'hui démantelé. +# +# Le build de wkhtmltopdf suit la version : celui de bullseye réclame +# libssl1.1, absente de bookworm ; celui de bookworm réclame libssl3, et ses +# quinze dépendances y sont toutes — vérifié dans l'index. +ARGS="${ARGS} --build-arg DEBIAN_NAME=bookworm --build-arg URL_WKHTMLTOX=github.com/wkhtmltopdf/packaging/releases/download/0.12.6.1-3/wkhtmltox_0.12.6.1-3.bookworm_amd64.deb --build-arg SHA1SUM_WKTHMLTOX=e9f95436298c77cc9406bd4bbd242f4771d0a4b2" set -e # Build base diff --git a/test/test_docker_base_bookworm.py b/test/test_docker_base_bookworm.py new file mode 100644 index 0000000..0613d32 --- /dev/null +++ b/test/test_docker_base_bookworm.py @@ -0,0 +1,81 @@ +#!/usr/bin/env python3 +# © 2026 TechnoLibre (http://www.technolibre.ca) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) +"""Les conteneurs reposent-ils tous sur la même base ? + +La base est « python:-slim- » : le Python vient +de l'image officielle, jamais de Debian. Changer de nom de version ne change +donc pas l'interpréteur, et rien n'obligeait les vieux Odoo à rester sur +bullseye — dont le dépôt de sécurité est aujourd'hui démantelé. + +Ce que ces tests gardent : + +- une seule base, pour toutes les versions d'Odoo. L'aiguillage précédent + portait une branche « buster » INATTEIGNABLE : sa condition était la + négation de celle qui la précédait ; +- le build de wkhtmltopdf suit la version. Celui de bullseye réclame + libssl1.1, absente de bookworm : un .deb mal apparié s'installe puis ne se + lance pas, et l'impression PDF échoue à l'exécution, pas à la construction ; +- l'empreinte accompagne l'URL. Le Dockerfile la vérifie avant d'installer, + et une URL changée sans son empreinte ferait échouer la construction. +""" + +import re +import unittest +from pathlib import Path + +RACINE = Path(__file__).resolve().parents[1] +SCRIPT = (RACINE / "script/docker/docker_build.sh").read_text(encoding="utf-8") +DOCKERFILE = (RACINE / "docker/Dockerfile.base").read_text(encoding="utf-8") + + +class TestUneSeuleBase(unittest.TestCase): + def test_aucune_version_debian_anterieure(self): + for ancienne in ("bullseye", "buster", "stretch"): + with self.subTest(version=ancienne): + self.assertNotIn(f"DEBIAN_NAME={ancienne}", SCRIPT) + + def test_la_base_est_bookworm(self): + self.assertIn("--build-arg DEBIAN_NAME=bookworm", SCRIPT) + + def test_elle_est_posee_une_seule_fois(self): + """Plusieurs branches redonneraient un aiguillage à entretenir.""" + self.assertEqual(1, SCRIPT.count("--build-arg DEBIAN_NAME=")) + + def test_plus_aucun_drapeau_de_version(self): + self.assertNotIn("IS_DEBIAN_", SCRIPT) + + +class TestWkhtmltopdf(unittest.TestCase): + def test_le_build_suit_la_version_de_la_base(self): + """Le .deb de bullseye réclame libssl1.1, absente de bookworm.""" + urls = re.findall(r"URL_WKHTMLTOX=(\S+)", SCRIPT) + self.assertTrue(urls) + for url in urls: + with self.subTest(url=url): + self.assertIn("bookworm", url) + + def test_l_empreinte_accompagne_l_url(self): + self.assertEqual( + SCRIPT.count("URL_WKHTMLTOX="), + SCRIPT.count("SHA1SUM_WKTHMLTOX="), + ) + + def test_le_dockerfile_verifie_l_empreinte_avant_d_installer(self): + """Sans ce contrôle, une page d'erreur HTML s'installerait comme + un paquet.""" + verif = DOCKERFILE.index("sha1sum -c -") + pose = DOCKERFILE.index( + "apt-get install -y --no-install-recommends ./wkhtmltox.deb" + ) + self.assertLess(verif, pose) + + def test_le_defaut_du_dockerfile_s_accorde_au_script(self): + """Une construction lancée sans argument ne doit pas changer de base.""" + self.assertIn("ARG DEBIAN_NAME=bookworm", DOCKERFILE) + attendue = re.search(r"URL_WKHTMLTOX=(\S+)", SCRIPT).group(1) + self.assertIn(attendue, DOCKERFILE) + + +if __name__ == "__main__": + unittest.main()