Aller au contenu

Guide Opérationnel des Workflows CI/CD Érable

Ce guide présente de manière concise et structurée les trois cycles de vie fondamentaux du gestionnaire de paquets Érable (Ajout de Paquet, Autoupdate, Évolution du Trampoline) ainsi que le protocole de qualification complète et automatisée de bout en bout.


1. Workflow : Ajout d'un Paquet (Tous OS ou OS Spécifiques)

1.1 Schéma du Flux

flowchart TD
    A["1. Ouverture Issue Normalisée (Dépôt GitLab)"] --> B["2. Processeur CI : scripts/ci/process_issue.py"]
    B --> C{"3. Contrôles Préliminaires"}
    C -->|Rejet| C_ERR["Rejet : IP, HTTP, non-OSI, Zip-Bomb, Domaines Anonymes"]
    C -->|Conforme| D["4. Double Barrière : Audit Anti-Obfuscation + Confinement Réseau Runtime"]
    D -->|Violation curl / ssh / base64 / collision alias| D_ERR["Rejet Bloquant de la Demande"]
    D -->|Validé| E["5. Sharding & Génération des Manifestes (packages/<l>/<nom>/parts/)"]
    E --> F["6. Création Branche dédiée & Merge Request (glab mr create)"]
    F --> G["7. Déclenchement du Banc Multi-OS Agnostique sur GitHub Actions (5 Plateformes)"]
    G --> H["8. Runners Matériels : install.ps1/sh -> erable install -> verification.toml -> unshare/sandbox uninstall -> purge"]
    H -->|Échec 1 OS| H_ERR["MR Bloquée / Pipeline Rouge"]
    H -->|Succès 5 OS| I["9. Auto-Merge MR dans main & Clôture de l'Issue"]

1.2 Principes et Déroulement du Workflow

Le processus d'intégration d'un nouveau logiciel suit des règles strictes d'automatisation et de sécurité :

  • Atomicité et Traçabilité Stricte : L'ajout s'amorce systématiquement par une Issue GitLab structurée. La règle est absolue : exactement 1 Merge Request par binaire / paquet. Toute tentative de regrouper plusieurs logiciels dans une même demande est rejetée.

  • Double Barrière de Contrôle CI : Le processeur d'issue audite les sources et les hooks de cycle de vie (pre/post_install.nu, pre/post_uninstall.nu) sous politique Zero Egress et anti-obfuscation (from base64, decode, source, use), tout en prévenant le détournement d'alias système réservés.

  • Génération Modulaire Shardée : Les manifestes sont découpés et stockés sous l'arborescence packages/<initiale>/<paquet>/parts/, et une unique MR dédiée est générée automatiquement.

  • Banc de Test Multi-OS Agnostique : Avant toute fusion dans main, le cycle de vie complet (installation Zero Cache, validation des commandes sanitaires, désinstallation hermétique et purge matérielle) est éprouvé sur les 5 plateformes cibles matérielles.

1.3 Étapes Détaillées

1.3.1 Ouverture de l'Issue Normalisée (1 Issue = 1 Paquet Unique)

Chaque bucket officiel expose trois templates d'issues GitLab strictement typés dans .gitlab/issue_templates/ :

  • package_add.md (package-add) : demande d'ajout d'un paquet inexistant dans le bucket. Rejetée automatiquement si le paquet existe déjà sur main.
  • package_update.md (package-update) : demande de mise à jour d'un paquet existant vers une version supérieure (créée automatiquement par check_updates.py ou manuellement).
  • platform_add.md (platform-add) : ajout d'une nouvelle plateforme cible (x86_64-linux, aarch64-macos, etc.) sur un paquet existant sans écraser les cibles déjà supportées (utilisée par les scripts de veille multi-sources).

Pour package-add, le contributeur déclare un seul et unique outil (interdiction de batching) : nom, version, homepage, licence FOSS OSI, URLs officielles HTTPS et sommes SHA-256 par plateforme (windows_x64_url, linux_x64_url, macos_arm64_url, etc.), commandes de vérification (check_version, check_help), et éventuellement scripts de cycle de vie .nu. Les outils spécifiques à un seul système doivent déclarer explicitement platform_specific = true.

1.3.2 Contrôles Préliminaires, Unicité Stricte et Orchestration Horaire

Le processeur (process_issue.py) et les scripts de veille sont orchestrés toutes les heures selon quatre créneaux planifiés en chaîne causale dans .gitlab-ci/ :

flowchart LR
    H00[":00 : Détection multi-plateforme (create -> issues package-add)"] --> H15_B[":15 : Traitement issues package-add"]
    H15_A[":15 : Détection mises à jour (check_updates -> issues package-update)"] --> H30_B[":30 : Traitement issues package-update"]
    H30_A[":30 : Détection nouvelles plateformes (enrich_targets -> issues platform-add)"] --> H45[":45 : Traitement issues platform-add"]
Créneau (UTC) Variable SCHEDULE_TYPE Rôle Principal
:00 (0 * * * *) hourly_00 Détection multi-plateforme amont (upstream_discovery --action-filter create) pour créer les issues package-add
:15 (15 * * * *) hourly_15 Détection des mises à jour disponibles (check_package_updates → issues package-update) et traitement des issues package-add
:30 (30 * * * *) hourly_30 Détection des nouvelles plateformes sur paquets existants (upstream_discovery --action-filter enrich_targets → issues platform-add) et traitement des issues package-update
:45 (45 * * * *) hourly_45 Traitement et fusion multi-OS des issues platform-add

À chaque exécution, process_issue.py applique :

  1. Contrôle d'Unicité et de Cohérence de Mode : vérifie que l'issue ne contient qu'une seule déclaration de paquet et valide son existence sur main selon le type (package-add interdit sur paquet existant ; package-update et platform-add exigés sur paquet existant).
  2. Contrôles de Sécurité : contrôle la validité du domaine (FQDN strict, pas d'IP, rejet formel des raccourcisseurs d'URL et services de stockage anonymes), vérifie la licence FOSS reconnue, inspecte les archives (.zip, .tar.gz, .tar.xz, .tar.zst, binaires bruts) contre les failles Zip Slip / Tar Traversal, et invoque audit_package_scripts.py. Tout hook contenant des primitives d'exfiltration (curl, wget, http), de l'obfuscation dynamique (from base64, decode, char 0x), des modules externes (source, use) ou tentant d'écraser un alias système réservé (erable, cmd, powershell, bash, sudo, git) est immédiatement et formellement rejeté.

1.3.3 Génération des Manifestes Modulaires et de la MR Dédiée (1 MR par Binaire)

Les fragments TOML sont créés sous packages/<initiale>/<nom>/parts/ (package.toml, targets.toml, verification.toml, et optionnellement shortcuts.toml, env.toml, autoupdate.toml). Les scripts .nu validés sont copiés à la racine du paquet. Une branche dédiée isolée (feat/package-<nom>-v<version>) est créée et poussée, puis une unique Merge Request GitLab est ouverte avec auto-fusion programmée.

1.3.4 Qualification Agnostique sur les Runners Multi-OS (GitHub Actions)

Le pipeline GitLab CI (.gitlab-ci/package-test.yml) relaie la demande au banc GitHub Actions (package-test.yml) via repository_dispatch OIDC sur 5 environnements matériels réels :

  1. Linux Ubuntu x86_64 (ubuntu-latest)
  2. Linux Ubuntu ARM64 (ubuntu-24.04-arm)
  3. Windows Server x86_64 (windows-latest)
  4. macOS Apple Silicon ARM64 (macos-14)
  5. macOS Intel x86_64 (macos-13)

Sur chaque runner :

  • Érable est installé nativement via install.ps1 ou install.sh dans un environnement vierge (Zero Cache).
  • Le paquet est installé avec erable install <nom>, exécutant automatiquement pre_install.nu et post_install.nu.
  • Les commandes sanitaires de parts/verification.toml sont exécutées via les trampolines : validation du code de retour 0, de la regex de version (check_version), et de la sortie d'aide (check_help).
  • Le paquet est désinstallé avec erable uninstall <nom> sous confinement réseau physique (unshare --net sous Linux, sandbox-exec deny network* sous macOS), exécutant pre_uninstall.nu et post_uninstall.nu.
  • La purge matérielle est validée : disparition de ~/.erable/packages/<nom>/, des trampolines et pointeurs dans ~/.erable/bin/, ainsi que des raccourcis et variables d'environnement.

1.3.5 Fusion Automatique et Signature du Catalogue

Dès que l'ensemble des runners cibles rapportent un statut vert, la Merge Request est fusionnée dans main, l'index souverain index.nuon est actualisé et signé cryptographiquement en Ed25519 (index.nuon.sig), puis l'issue d'origine est clôturée.


2. Workflow : Autoupdate des Paquets

2.1 Schéma du Flux

flowchart TD
    A["1. Planification Horaire GitLab CI (.gitlab-ci/check-updates.yml)"] --> B["2. Scan Amont (scripts/ci/check_updates.py)"]
    B --> C{"3. Nouvelle Version Détectée (vN > vN-1) ?"}
    C -->|Non| C_END["Aucune Action (À Jour)"]
    C -->|Oui| D["4. Téléchargement & Calcul Empreinte SHA-256"]
    D --> E["5. Contrôle Anti-Zip Slip & Intégrité"]
    E --> F["6. Création Branche Dédiée & Merge Request"]
    F --> G["7. Validation Multiplateforme du Nouveau Binaire vN"]
    G -->|Sanity Checks OK| H["8. Fusion Automatique & Signature Ed25519 de l'Index"]

2.2 Description Succincte

Le processus d'Autoupdate surveille de façon autonome les releases des dépôts amont (GitHub Releases, tags officiels) configurés dans parts/autoupdate.toml. Dès qu'une version N supérieure à la version N-1 actuelle est détectée, le bot CI télécharge les artefacts de chaque architecture, calcule et fige les nouvelles empreintes SHA-256, crée une Merge Request de mise à jour, et déclenche les tests de cycle de vie sur les OS cibles avant la fusion et la publication automatique.

2.3 Étapes Détaillées

2.3.1 Détection Amont Planifiée

Un job planifié (check_package_updates) parcourt tous les dossiers packages/*/*/parts/autoupdate.toml activés. Il interroge les APIs amont pour identifier les nouveaux tags respectant tag_regex.

2.3.2 Résolution des URLs et Contrôle d'Intégrité

Pour chaque architecture ciblée dans targets.toml, l'URL de téléchargement est résolue à partir du modèle url_template. L'archive est téléchargée en mémoire, son empreinte SHA-256 est calculée, et la structure est inspectée contre les failles d'évasion (Zip Slip / Tar Traversal).

2.3.3 Mise à Jour Déclarative et MR

Les fichiers package.toml (champ version) et targets.toml (URLs et sommes SHA-256) sont actualisés sans modifier les scripts de hooks existants. Une branche autoupdate/<nom>-<version> est générée et une MR est soumise.

2.3.4 Qualification en Version vN et Fusion

Le pipeline de test multiplateforme valide l'installation de la nouvelle version vN, l'exécution des tests de version/aide (verification.toml), et la désinstallation propre. À validation complète, la MR est fusionnée et l'index est republié avec signature Ed25519.


3. Workflow : Modification et Qualification du Trampoline (Rust)

3.1 Schéma du Flux

flowchart TD
    A["1. Validation Humaine Obligatoire de la Modification"] --> B["2. Branche Dédiée (feat/trampoline-*) & cargo test Local"]
    B --> C["3. Ouverture MR & Déclenchement Pipeline Unique (.gitlab-ci/trampoline.yml)"]
    C --> D["4. Stage Build : Compilation Distribuée (Linux musl ARM64 + Windows MSVC + Linux/macOS x86_64)"]
    D --> E["5. Stage Test Éliminatoire : Mise à Jour Native & Non-Régression sur les 3 OS"]
    E --> F["6. Exécution native 'erable update-trampolines' sur les OS distants"]
    F --> G["7. Test de Non-Régression sur Paquets Témoins ('jq --version', etc.)"]
    G -->|Échec Build ou Test Upgrade| G_ERR["MR Rejetée / Bloquée (Interdiction de Release & Merge)"]
    G -->|Succès 100% sur les 3 OS| H["8. Auto-Merge MR & Publication Release (.gitlab-ci/trampoline.yml:release)"]

3.2 Description Succincte

Toute évolution du Trampoline Rust (tools/trampoline/) visant des gains de performance ou des renforcements de sécurité requiert impérativement une validation humaine préalable. La compilation et la qualification s'effectuent au sein d'un pipeline unique de Merge Request (.gitlab-ci/trampoline.yml) comprenant deux étapes indissociables :

  1. Stage build : Compilation distribuée (Linux musl ARM64 natif, Windows compilé sous toolchain MSVC pour éliminer les faux positifs antivirus, et macOS).
  2. Stage test (Éliminatoire) : Déploiement et mise à jour native via erable update-trampolines sur chaque OS cible et épreuve de non-régression sur paquets certifiés.

Règle absolue : Aucune fusion de MR n'est autorisée si l'une des deux étapes échoue.

3.3 Garanties de Sécurité et de Robustesse du Trampoline

  • Zéro Allocation Dynamique : Buffer de pile statique de 4096 octets ([0u8; 4096]) pour le parsing ultra-rapide des fichiers pointeurs .target.
  • Immunisation Anti-DLL Hijacking (Windows) : Retrait du dossier courant et restriction exclusive à System32 via SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_SYSTEM32) et SetSearchPathMode.
  • Garde-Fou Anti-Boucle & Anti-Fork-Bomb (check_recursion_guard) :
  • Interdiction de l'Auto-Ciblage : Comparaison canonique bloquant tout fichier .target qui pointerait sur l'exécutable trampoline lui-même (canon(target) == canon(current_exe)).
  • Limite de Récursion en Cascade : Suivi du compteur d'environnement ERABLE_TRAMPOLINE_DEPTH (arrêt d'urgence immédiat avec code 126 si la profondeur atteint ou dépasse 5).
  • Mitigation des Injections de Scripts : Encapsulation stricte Batch/CMD (CVE-2024-24576) via cmd.exe /d /e:off /c et PowerShell via -NoProfile -NonInteractive -ExecutionPolicy Bypass -File.

3.4 Étapes Détaillées

3.4.1 Accord Humain et Tests Locaux

Avant d'altérer le code critique de tools/trampoline/src/main.rs, le développeur ou l'agent soumet obligatoirement la proposition technique à validation humaine. Une fois validée, les modifications sont testées localement via cargo test dans tools/trampoline/ (couverture complète des résolutions, déduplications de slashes, anti-boucle et auto-ciblage).

3.4.2 Stage build : Cross-Compilation Distribuée Sécurisée

Le commit sur branche dédiée déclenche le stage de compilation build_trampolines du pipeline de MR :

  • Sur l'environnement Linux ARM64 natif : compilation de trampoline-aarch64-linux avec la cible musl (aarch64-unknown-linux-musl).
  • Délégué aux runners distants GitHub Actions (build-trampoline.yml) : compilation Windows avec stable-x86_64-pc-windows-msvc, Linux x86_64 et macOS, rapatriés via fetch_trampoline_artifacts.py.

3.4.3 Stage test : Épreuve Éliminatoire de Mise à Jour Native et Non-Régression (test_trampoline_upgrade)

Ce stage éliminatoire s'exécute immédiatement après le stage de compilation au sein du même pipeline (allow_failure: false, needs: [build_trampolines]) :

  1. Il déploie les binaires trampolines nouvellement compilés sur les runners des 3 OS.
  2. Il exécute la commande native d'Érable : erable update-trampolines.
  3. Il vérifie que les paquets déjà installés (ex: jq, fd, zoxide) s'exécutent instantanément avec succès (jq --version), garantissant l'absence de régression mémoire ou de rupture de compatibilité d'exécution.
  4. Tout échec sur l'un quelconque des OS bloque immédiatement la Merge Request.

3.4.4 Fusion Automatique et Pipeline de Release Officielle

Si et seulement si la compilation et l'épreuve éliminatoire sont 100% vertes sur les 3 systèmes d'exploitation, la Merge Request est fusionnée dans main, et le job de publication (release_trampolines) génère l'attestation SLSA 3 et publie la release officielle des binaires trampolines.


4. Protocole de Qualification Complète de Bout en Bout (Méthodologie N-1)

Ce protocole définit le scénario intégral et autonome permettant d'éprouver la robustesse de l'intégralité de l'architecture Érable.
Règle absolue : Aucune manipulation sur la machine hôte. Tout le banc d'épreuve est exécuté et vérifié exclusivement au travers des pipelines natifs du projet (GitLab CI et GitHub Actions).

flowchart TD
    subgraph Phase1 ["Phase 1 : Ingestion & Qualification Initiale du Paquet N-1"]
        P1["Pipeline 1 : Traitement de l'Issue (package-requests.yml & Child Pipeline)"] -->|MR Auto & Merge| M1["Fusion dans main & Signature Ed25519 (index.nuon.sig)"]
        M1 --> P2["Pipeline 2 : Qualification Multi-OS du Binaire N-1 sur main (validate-package.yml)"]
    end
    subgraph Phase2 ["Phase 2 : Évolution Sécurisée du Trampoline (Pipeline Unique)"]
        T1["Accord Humain & MR Trampoline"] --> P3["Pipeline 3 : Pipeline Unique Trampoline (Stage Build + Stage Test Éliminatoire)"]
        P3 -->|Succès 100% Vert sur les 3 OS| M2["Fusion MR & Release Trampoline"]
    end
    subgraph Phase3 ["Phase 3 : Autoupdate et Qualification Multi-OS de la Version N"]
        P4["Pipeline 4 : Scan Dynamique & Émission Issue vN (check-updates.yml)"] -->|Issue vN| P5["Pipeline 5 : Ingestion de l'Issue d'Autoupdate vN (Child Pipeline & MR)"]
        P5 -->|MR Auto & Merge| M3["Fusion vN dans main & Signature Ed25519"]
        M3 --> P6["Pipeline 6 : Qualification Multi-OS Finale de la Version N sur main"]
    end
    Phase1 --> Phase2 --> Phase3

4.1 Orchestration Séquentielle des Six Pipelines

4.1.1 Pipeline 1 : Découverte, Audit et Ingestion de l'Issue Paquet (Version N-1)

  • Déclenchement : Déclenché par le pipeline planifié GitLab CI au créneau :15 (.gitlab-ci/package-requests.yml avec SCHEDULE_TYPE="hourly_15", ou :45 / hourly_45 pour platform-add), suite à la détection amont effectuée à :00 (upstream_discovery --action-filter create). L'étape d'orchestration (discover_issues) engendre dynamiquement un Pipeline Enfant Aval (Child Pipeline) dédié avec exécution parallèle immédiate (needs: []).
  • Rôle et Actions de Chaque Élément :
  • Issue Déclarative (GitLab) : Reçoit la demande décrivant le paquet non encore présent dans les buckets (ex: fd v10.2.0, zoxide v0.9.5) avec métadonnées complètes, URLs officielles HTTPS, hashs SHA-256 par OS, sanity checks dans parts/verification.toml et les 4 scripts de cycle de vie .nu.
  • Processeur d'Issue (scripts/ci/process_issue.py) : Détecte l'issue ouverte, contrôle le FQDN avec liste noire anti-anonymisation / anti-pastebin, vérifie l'absence de collision avec les alias système réservés (erable, cmd, powershell, bash, sudo, git), vérifie la licence FOSS reconnue (OSI) et inspecte les archives amont (.zip, .tar.gz, .tar.xz, .tar.zst, binaires bruts) contre les failles Zip Slip et Tar Traversal.
  • Module d'Audit Statique Zero Egress (scripts/ci/audit_package_scripts.py) : Audite chaque script .nu selon la double barrière Zero Egress et anti-obfuscation (from base64, decode, char 0x, source, use, registry::). Tout appel réseau ou tentative de contournement entraîne le rejet immédiat de l'issue.
  • Générateur Modulaire Shardé : Découpe et crée l'arborescence standardisée packages/<initiale>/<nom>/parts/ (package.toml, targets.toml, verification.toml, autoupdate.toml).
  • Moteur Git / GitLab : Crée la branche dédiée feat/package-<nom>-v<version>, pousse les fichiers de manifests, ouvre la Merge Request avec auto-fusion programmée, signe l'index index.nuon en Ed25519 (index.nuon.sig), et clôture l'Issue d'origine.
  • Critère de Validation : Pipeline Enfant au vert, Merge Request fusionnée dans main et index Ed25519 régénéré.

4.1.2 Pipeline 2 : Qualification Multi-OS du Binaire N-1 sur main

  • Déclenchement : Déclenché automatiquement lors de l'intégration ou sur demande via le script de relais scripts/ci/trigger_github_actions.py --package-name <nom> --branch main --wait avec polling adaptatif ultra-réactif (2s-3.5s).
  • Rôle et Actions de Chaque Élément :
  • Dispatch GitHub Actions (repository_dispatch) : Émet un événement authentifié via OIDC/token vers le workflow validate-package.yml sur DeVinci-Leonard/erable-ci-runner.
  • Runners Matériels Distants Agnostiques (5 cibles) : Exécution simultanée sur 5 environnements réels distincts :
    • Linux Ubuntu x86_64 (ubuntu-latest)
    • Linux Ubuntu ARM64 (ubuntu-24.04-arm)
    • Windows Server x86_64 (windows-latest)
    • macOS Apple Silicon ARM64 (macos-14)
    • macOS Intel x86_64 (macos-13)
  • Installateur Natif Érable : Exécute install.ps1 (Windows) ou install.sh (Linux/macOS), initialisant l'arborescence hermétique ~/.erable/ sur le runner sans aucun cache persistant (Zero Cache).
  • Moteur d'Installation Érable (erable install <nom>) : Télécharge l'archive vN-1, vérifie l'empreinte SHA-256, extrait dans le store immuable, positionne les trampolines et shims dans ~/.erable/bin/, et exécute séquentiellement pre_install.nu et post_install.nu.
  • Contrôleur Sanitaire (parts/verification.toml) : Exécute au travers du trampoline :
    • check_version : valide le code de retour 0 et la concordance stricte avec l'expression régulière de version.
    • check_help : valide le code de retour 0 et la présence des mots-clés d'aide standard (Usage, Options).
  • Moteur de Désinstallation avec Confinement Réseau (erable uninstall <nom>) : Exécute pre_uninstall.nu et post_uninstall.nu sous isolation réseau physique (unshare --net sous Linux, sandbox-exec deny network* sous macOS), supprime les références physiques et le dossier du store.
  • Auditeur de Purge Matérielle : Constate la disparition totale des fichiers du store (~/.erable/packages/<nom>/), des shims trampolines dans ~/.erable/bin/, ainsi que des raccourcis (shortcuts.toml) et variables d'environnement (env.toml).
  • Critère de Validation : Matrice 5 cibles 100% verte sur les runners matériels.

4.1.3 Pipeline 3 : Pipeline Unique du Trampoline (Compilation Distribuée + Qualification Éliminatoire & Non-Régression)

  • Déclenchement : Déclenché automatiquement par l'ouverture d'une Merge Request sur une branche dédiée (feat/trampoline-*) modifiant tools/trampoline/** (pipeline .gitlab-ci/trampoline.yml).
  • Rôle et Actions de Chaque Élément :
  • Garde-Fou & Validation Humaine : Exige l'accord explicite d'un mainteneur humain sur la proposition de modification.
  • Stage build (build_trampolines) :
    • Exécuteur Linux ARM64 natif : Exécute cargo test localement (14 tests unitaires), puis compile nativement trampoline-aarch64-linux avec la cible musl (aarch64-unknown-linux-musl).
    • Runners Distants GitHub Actions (build-trampoline.yml) : Compilation Windows MSVC (stable-x86_64-pc-windows-msvc), Linux x86_64 et macOS Universal (x86_64-apple-darwin et aarch64-apple-darwin). Rapatriement et archivage dans erable-trampolines-<sha>.zip.
  • Stage test (test_trampoline_upgrade) :
    • Déploie immédiatement les nouveaux trampolines compilés sur les runners des 3 OS.
    • Exécute erable update-trampolines pour remplacer atomiquement les binaires de référence.
    • Exécute l'épreuve de non-régression sur paquets certifiés (jq --version, fd --version, zoxide --version).
  • Garde-Fou Bloquant & Auto-Merge : Tout échec sur l'un quelconque des OS bloque immédiatement la MR. Aucun merge n'est possible si la compilation ou le test upgrade échoue. Dès succès 100% vert des deux stages, la MR est fusionnée dans main, l'attestation SLSA 3 est générée, et la release officielle des trampolines est publiée.
  • Critère de Validation : Pipeline unique 100% vert sur les 3 OS ; MR fusionnée dans main.

4.1.4 Pipeline 4 : Scan Dynamique d'Autoupdate vers la Version N

  • Déclenchement : Déclenché par le pipeline planifié GitLab CI :15 .gitlab-ci/check-updates.yml avec la variable SCHEDULE_TYPE="hourly_15", en parallèle du traitement des issues package-add.
  • Rôle et Actions de Chaque Élément :
  • Moteur d'Inspection Dynamique (scripts/ci/check_updates.py) : Parcourt tous les manifestes packages/*/*/parts/autoupdate.toml dans le bucket cible (aucun binaire ni paquet codé en dur).
  • Interrogation Sécurisée & Bloqueur de Redirection (StrictRedirectHandler) : Toutes les requêtes HTTP passent par un gestionnaire strict interceptant les codes 301/302/307/308 pour bloquer toute redirection vers un domaine d'anonymisation ou hors liste blanche.
  • Vérification des Checksums Amont Officiels : Détecte et parse les fichiers checksums.txt, SHA256SUMS, SHASUMS256.txt publiés par les mainteneurs officiels amont. En cas de divergence avec le hash calculé, le paquet est rejeté pour alerte de sécurité.
  • Parallélisation Multi-Thread (ThreadPoolExecutor) : Téléchargement et calcul d'empreintes des 5 plateformes cibles exécutés en parallèle (réduction de ~15s à ~2s par paquet).
  • Émetteur d'Issue Déclarative : Ouvre automatiquement une Issue normalisée basée sur le template package_update.md, étiquetée package-update et autoupdate sur le bucket cible (Demande de mise à jour : <nom> v<version>) avec tous les hashs et URLs résolus (ex: zoxide v0.10.0).
  • Critère de Validation : Issue d'autoupdate vN créée sur le bucket cible de manière 100% autonome.

4.1.5 Pipeline 5 : Traitement & Intégration de l'Issue d'Autoupdate vN

  • Déclenchement : Découvert et déclenché au créneau :30 (SCHEDULE_TYPE="hourly_30"), en parallèle de la détection des nouvelles plateformes sur paquets existants (upstream_discovery --action-filter enrich_targets), qui lance le Pipeline Enfant Aval (process_issue --issue-type package-update) pour la version N.
  • Rôle et Actions de Chaque Élément :
  • Audit Zero Egress & Intégrité : Ré-audit complet des sources, contrôle anti-obfuscation, contrôle d'absence de Zip/Tar Slip sur formats étendus (.tar.xz, .tar.zst), validation de conformité des manifestes et téléchargement sous StrictRedirectHandler.
  • Génération de la MR : Création de la branche feat/package-update-<nom>-v<version>, mise à jour ciblée de package.toml et targets.toml avec les nouvelles URLs et sommes SHA-256 tout en préservant les métadonnées, autoupdate.toml, shortcuts.toml, env.toml et hooks .nu existants.
  • Fusion et Signature Souveraine Ed25519 : La MR est fusionnée automatiquement dans main, l'index index.nuon est reconstruit et signé cryptographiquement (index.nuon.sig), et l'issue d'autoupdate vN est fermée avec notification de conformité.
  • Critère de Validation : Version vN fusionnée dans main et index souverain signé.

4.1.6 Pipeline 6 : Qualification Multi-OS Finale de la Version N sur main

  • Déclenchement : Déclenché automatiquement post-fusion ou via le script de relais scripts/ci/trigger_github_actions.py --package-name <nom> --branch main --wait avec polling adaptatif et extraction automatique des manifestes distants.
  • Rôle et Actions de Chaque Élément :
  • Dispatch GitHub Actions (repository_dispatch) : Émet un événement vers le workflow validate-package.yml sur DeVinci-Leonard/erable-ci-runner ciblant la branche main.
  • Validation Complète sur 5 Plateformes Réelles :
    • Linux Ubuntu x86_64 (ubuntu-latest)
    • Linux Ubuntu ARM64 (ubuntu-24.04-arm)
    • Windows Server x86_64 (windows-latest)
    • macOS Apple Silicon ARM64 (macos-14)
    • macOS Intel x86_64 (macos-13)
  • Banc d'Épreuve en Confinement Hermétique :
    • Assainissement Total de l'Environnement (sanitize_environment) : Purge intégrale de 100% des tokens d'environnement (GH_TOKEN, GITLAB_TOKEN, CI_JOB_TOKEN, clés SSH, secrets) avant l'exécution du processus de test.
    • Isolation Réseau Zero-Egress : Confinement réseau physique lors du test des binaires (docker --network none, unshare -n sur Linux, sandbox-exec sur macOS).
    • Cycle de Vie Éprouvé : Installation hermétique d'Érable (Zero Cache), installation de la version vN (erable install <nom>), exécution sanitaire (check_version, check_help), désinstallation et purge matérielle intégrale.
  • Critère de Validation : Qualification 100% verte sur les 5 plateformes de la version mise à jour ; cycle intégral N-1 $\rightarrow$ Trampoline $\rightarrow$ N certifié sans aucune régression.