From 406f6ab1b5d7eb9a524f3f8d8ddf4fa516c57d2a Mon Sep 17 00:00:00 2001 From: Philippe Vienne Date: Sun, 27 Sep 2026 12:49:50 +0200 Subject: [PATCH 1/4] build: validation des ancres des liens internes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Un lien vers une ancre absente (titre renommé, par exemple) fait désormais échouer le build strict. Aucun lien cassé à ce jour. Co-authored-by: Claude --- mkdocs.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mkdocs.yml b/mkdocs.yml index 3fbb9f9..9b271d8 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -9,6 +9,11 @@ edit_uri: edit/main/docs/ copyright: Copyright © 2026 OTSPI — Contenu sous licence Creative Commons Attribution 4.0 International (CC-BY-4.0). +# Liens internes : un lien vers une ancre absente (titre renommé, par exemple) fait échouer +# le build strict, comme un lien vers une page absente. +validation: + anchors: warn + hooks: - hooks/page_lang.py From 641c1d11e7f80944d2d79551f7d646410a82a471 Mon Sep 17 00:00:00 2001 From: Philippe Vienne Date: Sun, 27 Sep 2026 12:50:21 +0200 Subject: [PATCH 2/4] =?UTF-8?q?build:=20recherche=20en=20fran=C3=A7ais=20e?= =?UTF-8?q?t=20en=20anglais?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Le livre blanc et la page des hébergements existent en anglais : l'index de recherche applique désormais les règles des deux langues (racines, mots vides), et « authorities » trouve les pages anglaises. Co-authored-by: Claude --- mkdocs.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mkdocs.yml b/mkdocs.yml index 9b271d8..5496717 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -73,8 +73,11 @@ extra_css: - stylesheets/print.css plugins: + # Recherche en français et en anglais (livre blanc et page des hébergements existent dans les deux langues) - search: - lang: fr + lang: + - fr + - en markdown_extensions: - admonition From f715dafce4afd5d1987d6d939700eb18cbc67c9f Mon Sep 17 00:00:00 2001 From: Philippe Vienne Date: Sun, 27 Sep 2026 12:51:05 +0200 Subject: [PATCH 3/4] =?UTF-8?q?docs:=20section=20Outils=20du=20README=20et?= =?UTF-8?q?=20arborescence=20=C3=A0=20jour?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Commandes de construction et de prévisualisation, chaîne de contrôle complète (build strict, PDF, PDF/UA-1, accessibilité) et tableau des scripts avec leurs prérequis. - Arborescence alignée sur le dépôt : livre blanc, overrides, scripts, workflows ; plus de docs/CNAME inexistant. Les statuts y sont décrits comme un projet non encore adopté, comme sur le portail. Co-authored-by: Claude --- README.md | 85 +++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 61 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index c26b7b1..39a3c3e 100644 --- a/README.md +++ b/README.md @@ -42,38 +42,75 @@ La gouvernance d'OTSPI applique une séparation stricte des devoirs conformémen ## 📁 Panoplie Documentaire Complète ``` -├── docs/ -│ ├── index.md # Page d'accueil du portail web about.otspi.org -│ ├── CNAME # Configuration du domaine personnalisé (about.otspi.org) +├── docs/ # Contenu du portail about.otspi.org +│ ├── index.md # Page d'accueil (bandeau dans overrides/home.html) +│ ├── livre-blanc/ # Livre blanc (FR, fait foi) et historique des versions +│ ├── white-paper/ # Traduction anglaise du livre blanc │ ├── statuts/ -│ │ └── statuts-association.md # Statuts constitutifs adoptés (OTSPI, Lyon, 20 septembre 2026) +│ │ └── statuts-association.md # Projet de statuts, soumis à l'AG constitutive (non encore adopté) │ ├── reglement-interieur/ -│ │ └── reglement-interieur.md # RI complet : cursus Officiers, MFA FIPS/ANSSI, Key Custodians, dépenses -│ ├── administratif/ -│ │ ├── pv-ag-constitutive-modele.md # PV d'AG Constitutive (élections, mandats fiscaux L.80 CB, RC Pro) -│ │ ├── rescrit-fiscal-mecenat.md # Demande formelle de rescrit fiscal DGFIP (Méthode 4P) -│ │ └── declaration-prefecture.md # Guide des formalités préfecture (RNA, JOAFE, SIRET) -│ ├── cadrage/ -│ │ ├── index.md # Présentation du socle d'audit initial TSP / PKI -│ │ ├── cp-cps-cadre.md # Cadre général CP/CPS conforme RFC 3647 & ETSI EN 319 411 -│ │ ├── pssi.md # PSSI (ISO 27001 & ETSI EN 319 401, RSSI, incidents) -│ │ └── termination-plan.md # Plan de fin d'activité (archivage 10-30 ans, séquestre financier) +│ │ └── reglement-interieur.md # RI : cursus Officiers, MFA FIPS/ANSSI, Key Custodians, dépenses │ ├── gouvernance/ -│ ├── charte-ethique.md # Charte d'éthique, de déontologie et de gestion désintéressée -│ │ └── comite-technique.md # Articulation CPC (PMA), TSC (ingénierie logicielle) & RFCs +│ │ ├── charte-ethique.md # Charte d'éthique, de déontologie et de transparence publique +│ │ └── comite-technique.md # Articulation CPC (PMA), TSC (ingénierie logicielle) et RFC +│ ├── administratif/ # PV d'AG constitutive (modèle), rescrit fiscal, guide préfecture… +│ ├── cadrage/ # Socle d'audit TSP / PKI : CP/CPS, PSSI, fin d'activité, OID, devis │ ├── adhesion/ -│ │ └── bulletin-adhesion.md # Formulaires d'adhésion (sympathisants, titulaires, bienfaiteurs) -│ └── reunions/ -│ └── index.md # Registre public des réunions et procès-verbaux (caviardage RGPD) -├── mkdocs.yml # Configuration Material for MkDocs (about.otspi.org) -├── .github/workflows/ -│ └── deploy-o2switch.yml # Déploiement automatique chez o2switch (FTPS) -├── LICENSE # Licence Creative Commons Attribution 4.0 International -└── README.md # Documentation générale du dépôt +│ │ └── bulletin-adhesion.md # Formulaires d'adhésion (sympathisants, titulaires, bienfaiteurs) +│ ├── reunions/ # Registre des réunions, transparence des hébergements (FR / EN) +│ ├── assets/ # Logos, police Inter (OFL), image de partage +│ ├── stylesheets/ # Charte du portail (extra.css), impression et PDF (print.css) +│ └── javascripts/ # Accessibilité, mesure d'audience sans cookie +├── overrides/ # Gabarits Material : accueil, 404, métadonnées de partage +├── hooks/page_lang.py # Langue de la balise selon la page +├── scripts/ # Outils : voir ci-dessous +├── data/qtsp-count.json # Décompte des QTSP cité par le livre blanc (annexe C) +├── deploy/o2switch/ # Configuration Apache (.htaccess) et notes de déploiement +├── .github/workflows/ # Déploiement, vérification des PR, contrôles périodiques +├── mkdocs.yml # Configuration Material for MkDocs +└── LICENSE # Creative Commons Attribution 4.0 International ``` --- +## 🛠️ Outils et contribution + +Le portail est construit avec [Material for MkDocs](https://squidfunk.github.io/mkdocs-material/). Toute pull request vers `main` est vérifiée par `.github/workflows/check-pr.yml` (construction stricte, accessibilité, PDF) ; la fusion déclenche le déploiement (`deploy-o2switch.yml`). + +**Construire et prévisualiser le site** + +```sh +pip install -r requirements.txt +mkdocs serve # http://127.0.0.1:8000, rechargé à chaque modification +mkdocs build --strict # échoue sur tout lien ou ancre interne cassé +``` + +**Scripts** (`scripts/`) + +| Script | Rôle | Prérequis | +|---|---|---| +| `export_pdf.py` | PDF balisés du livre blanc (FR, EN), du projet de statuts, du règlement intérieur et de la charte, dans `site/` | `pip install -r requirements-pdf.txt` (WeasyPrint, Pango) | +| `check_pdf_ua.sh` | Validation PDF/UA-1 de ces PDF avec veraPDF (téléchargé et vérifié au premier lancement) | Java | +| `check_a11y.js` | Accessibilité WCAG 2 AA (pa11y, moteur axe) de toutes les pages du site construit | Node.js, `npm install --no-save pa11y@9`, Chrome | +| `build_diagrams.py` | Régénère les schémas SVG du livre blanc et l'organigramme de l'accueil | — | +| `build_og_image.py` | Régénère l'image de partage par défaut (`docs/assets/og/og-portail.png`) | Chrome | +| `count_qtsp.py` | Décompte des QTSP des listes de confiance de l'EEE (`data/qtsp-count.json`) | — | +| `check_links.py` | Liens externes cassés (contrôle mensuel) | — | +| `check_sites.sh` | Codes HTTP, redirections et certificats des sites OTSPI (contrôle quotidien) | curl, openssl | + +Chaîne complète, comme en CI : + +```sh +mkdocs build --strict +python scripts/export_pdf.py +bash scripts/check_pdf_ua.sh +npm install --no-save pa11y@9 && node scripts/check_a11y.js site +``` + +Les schémas et l'image de partage sont générés puis versionnés : après modification de leur source, relancer le script correspondant et commiter le résultat. + +--- + ## 📬 Contact - **Contact unique (Adhésions, Questions générales, Sécurité)** : `contact@otspi.org` From 6ca29106210ab164000fefb58777199d59195759 Mon Sep 17 00:00:00 2001 From: Philippe Vienne Date: Sun, 27 Sep 2026 12:51:44 +0200 Subject: [PATCH 4/4] =?UTF-8?q?ci:=20action=20commune=20au=20d=C3=A9ploiem?= =?UTF-8?q?ent=20et=20=C3=A0=20la=20v=C3=A9rification=20des=20PR?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .github/actions/build-portal regroupe l'installation, la construction stricte, le contrôle d'accessibilité, l'export des PDF et la validation PDF/UA-1. Le déploiement passe désormais aussi le contrôle d'accessibilité : un site qui échouerait en PR n'est pas publié. Co-authored-by: Claude --- .github/actions/build-portal/action.yml | 55 +++++++++++++++++++++++++ .github/workflows/check-pr.yml | 45 ++------------------ .github/workflows/deploy-o2switch.yml | 31 +++----------- README.md | 2 +- deploy/o2switch/README.md | 2 +- 5 files changed, 65 insertions(+), 70 deletions(-) create mode 100644 .github/actions/build-portal/action.yml diff --git a/.github/actions/build-portal/action.yml b/.github/actions/build-portal/action.yml new file mode 100644 index 0000000..4c7db93 --- /dev/null +++ b/.github/actions/build-portal/action.yml @@ -0,0 +1,55 @@ +name: Construction et contrôle du portail +description: >- + Étapes communes au déploiement et à la vérification des pull requests : construction stricte du + site, contrôle d'accessibilité des pages, export des PDF et validation PDF/UA-1. Le site construit + reste dans ./site pour les étapes suivantes du workflow appelant. + +runs: + using: composite + steps: + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.12" + cache: pip + + - name: Install dependencies + shell: bash + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt -r requirements-pdf.txt + sudo apt-get update + sudo apt-get install -y libpango-1.0-0 libpangoft2-1.0-0 poppler-utils + + - name: Build documentation + shell: bash + run: mkdocs build --strict + + # Accessibilité des pages HTML (WCAG 2 AA, moteur axe) : Chrome du runner, sans téléchargement + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: "22" + + - name: Check accessibility (pa11y, axe) + shell: bash + env: + PUPPETEER_SKIP_DOWNLOAD: "true" + CHROME: /usr/bin/google-chrome + run: | + npm install --no-save --no-audit --no-fund pa11y@9 + node scripts/check_a11y.js site + + - name: Export PDF + shell: bash + run: python scripts/export_pdf.py + + - name: Cache veraPDF + uses: actions/cache@v4 + with: + path: ~/.cache/verapdf + key: verapdf-1.30.2 + + - name: Validate PDF/UA-1 + shell: bash + run: bash scripts/check_pdf_ua.sh diff --git a/.github/workflows/check-pr.yml b/.github/workflows/check-pr.yml index a6c944e..c7526e5 100644 --- a/.github/workflows/check-pr.yml +++ b/.github/workflows/check-pr.yml @@ -1,6 +1,6 @@ name: Vérification des pull requests (build, accessibilité et PDF) -# Mêmes étapes de construction que le déploiement, sans déploiement ni secret : +# Mêmes étapes de construction que le déploiement (.github/actions/build-portal), sans déploiement ni secret : # le site et les PDF du portail (livre blanc, statuts, règlement intérieur, charte) sont validés # avant fusion, et les PDF joints en artefact pour relecture. @@ -24,47 +24,8 @@ jobs: with: persist-credentials: false - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: "3.12" - cache: pip - - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -r requirements.txt -r requirements-pdf.txt - sudo apt-get update - sudo apt-get install -y libpango-1.0-0 libpangoft2-1.0-0 poppler-utils - - - name: Build documentation - run: mkdocs build --strict - - # Accessibilité des pages HTML (WCAG 2 AA, moteur axe) : Chrome du runner, sans téléchargement - - name: Set up Node.js - uses: actions/setup-node@v4 - with: - node-version: "22" - - - name: Check accessibility (pa11y, axe) - env: - PUPPETEER_SKIP_DOWNLOAD: "true" - CHROME: /usr/bin/google-chrome - run: | - npm install --no-save --no-audit --no-fund pa11y@9 - node scripts/check_a11y.js site - - - name: Export PDF - run: python scripts/export_pdf.py - - - name: Cache veraPDF - uses: actions/cache@v4 - with: - path: ~/.cache/verapdf - key: verapdf-1.30.2 - - - name: Validate PDF/UA-1 - run: bash scripts/check_pdf_ua.sh + - name: Build and check the portal + uses: ./.github/actions/build-portal # Polices embarquées : Inter pour le texte ; toute autre police signale un glyphe absent d'Inter - name: List embedded fonts diff --git a/.github/workflows/deploy-o2switch.yml b/.github/workflows/deploy-o2switch.yml index 922a784..caa8aad 100644 --- a/.github/workflows/deploy-o2switch.yml +++ b/.github/workflows/deploy-o2switch.yml @@ -21,33 +21,12 @@ jobs: with: persist-credentials: false - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: "3.12" - cache: pip - - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -r requirements.txt -r requirements-pdf.txt - sudo apt-get update - sudo apt-get install -y libpango-1.0-0 libpangoft2-1.0-0 lftp - - - name: Build documentation - run: mkdocs build --strict - - - name: Export whitepaper PDF - run: python scripts/export_pdf.py - - - name: Cache veraPDF - uses: actions/cache@v4 - with: - path: ~/.cache/verapdf - key: verapdf-1.30.2 + # Construction stricte, accessibilité, PDF et PDF/UA-1 : mêmes contrôles que les pull requests + - name: Build and check the portal + uses: ./.github/actions/build-portal - - name: Validate PDF/UA-1 - run: bash scripts/check_pdf_ua.sh + - name: Install lftp + run: sudo apt-get install -y lftp - name: Add Apache configuration run: cp deploy/o2switch/htaccess site/.htaccess diff --git a/README.md b/README.md index 39a3c3e..1b9ef52 100644 --- a/README.md +++ b/README.md @@ -75,7 +75,7 @@ La gouvernance d'OTSPI applique une séparation stricte des devoirs conformémen ## 🛠️ Outils et contribution -Le portail est construit avec [Material for MkDocs](https://squidfunk.github.io/mkdocs-material/). Toute pull request vers `main` est vérifiée par `.github/workflows/check-pr.yml` (construction stricte, accessibilité, PDF) ; la fusion déclenche le déploiement (`deploy-o2switch.yml`). +Le portail est construit avec [Material for MkDocs](https://squidfunk.github.io/mkdocs-material/). Toute pull request vers `main` est vérifiée par `.github/workflows/check-pr.yml` (construction stricte, accessibilité, PDF) ; la fusion déclenche le déploiement (`deploy-o2switch.yml`), qui repasse les mêmes contrôles. Les deux workflows partagent l'action `.github/actions/build-portal`. **Construire et prévisualiser le site** diff --git a/deploy/o2switch/README.md b/deploy/o2switch/README.md index a327d13..1fce292 100644 --- a/deploy/o2switch/README.md +++ b/deploy/o2switch/README.md @@ -5,7 +5,7 @@ Ce dossier décrit l'hébergement du portail `about.otspi.org` chez o2switch (so ## Ce qui est en place - `htaccess` : redirection HTTPS, domaine canonique, page 404, en-têtes de sécurité, compression et durées de cache. Il est copié à la racine du site au déploiement. -- `.github/workflows/deploy-o2switch.yml` : construit le site, exporte et valide les PDF (PDF/UA-1), ajoute le `.htaccess`, puis envoie tout en FTPS (TLS obligatoire, certificat vérifié). +- `.github/workflows/deploy-o2switch.yml` : construit et contrôle le site avec l'action commune `.github/actions/build-portal` (construction stricte, accessibilité, export et validation PDF/UA-1 des PDF, mêmes contrôles que les pull requests), ajoute le `.htaccess`, puis envoie tout en FTPS (TLS obligatoire, certificat vérifié). - Un compte FTP dédié, cantonné au seul répertoire du site. Il est renseigné dans les secrets `O2_FTP_USERNAME` et `O2_FTP_PASSWORD` du dépôt ; l'hôte est dans la variable `O2_FTP_HOST`. ## Bascule (faite le 26 septembre 2026)