Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

7. Passer en production

Tu sais composer une flotte, travailler à travers elle, livrer des changesets, la compiler et la tester. Ce dernier chapitre porte sur le fait de faire tout cela pour de vrai — en toute sécurité, en CI, avec une piste d’audit — et sur la seule échappatoire d’extensibilité qui relie les fonctionnalités de gouvernance : les plugins. C’est ce qui distingue un petit outil local sympa d’un outil auquel tu confies le verrouillage de tes releases.

Taking haw to production

D’un petit outil local sympa à un outil auquel tu confies le verrouillage de tes releases — c’est parti.

🎯 Dans ce chapitre, tu vas apprendre à…

  • Intérioriser le modèle de confiance — le manifeste est du code de confiance, les jetons ne vivent que dans l’environnement.
  • Câbler le pipeline CI en quatre temps : sync → verify → build → test.
  • Imposer la reproductibilité avec haw sync –locked et haw verify.
  • Étendre haw avec des plugins — tout haw <name> inconnu lance haw-<name>, sans fork.
  • Distribuer les artefacts avec haw publish, et produire SBOM, provenance et signatures.
  • Regrouper une piste d’audit avec haw evidence et la faire correspondre aux normes de conformité.

🛡️ 1. D’abord, le modèle de confiance — parce que ça compte

Avant de lancer haw sur quoi que ce soit que tu n’as pas écrit, intériorise une règle :

The hawser trust model

Traite un haw.toml comme un Makefile : puissant, et ne lance que ceux en qui tu as confiance.

Le manifeste est du code de confiance. Les commandes build, test, run et exec d’un haw.toml sont exécutées à travers ton shell.

Lancer haw build, haw run ou haw sync sur un checkout non fiable revient à lancer son Makefile. Traite haw.toml exactement comme un Makefile ou un bloc scripts de package.json : ne le lance que sur des manifestes en qui tu as confiance.

Deux corollaires que tu connais déjà à moitié :

  • Les plugins sont des binaires de confiance. haw <name> lance haw-<name> depuis ton PATH avec l’intégralité de ton environnement (y compris les éventuels tokens). N’installe que des plugins en qui tu as confiance ; garde ton PATH propre.
  • Les tokens vivent uniquement dans l’environnement. haw lit les tokens de forge depuis les variables d’environnement au moment de l’appel, et ne les stocke ni ne les journalise jamais. L’authentification du transport Git reste gérée par tes clés SSH / ton credential helper existants — haw n’y touche pas.

Lis le modèle de confiance en entier avant de brancher haw sur quoi que ce soit de partagé.

🧩 2. Étends-le avec des plugins — sans fork

Avant de brancher le pipeline, découvre l’échappatoire qui alimente les fonctionnalités de gouvernance ci-dessous. haw suit le même modèle que git, cargo et kubectl : toute sous-commande que haw ne reconnaît pas est déléguée à un exécutable haw-<name> présent sur ton PATH.

Extending haw with plugins

Un plugin, c’est juste un programme qui lit du JSON et affiche du JSON — écris-en un dans n’importe quel langage.

haw jira sync      # pas intégré → lance `haw-jira sync`

Le plugin s’exécute dans un processus séparé (un plugin défaillant ne peut jamais faire planter haw), haw lui transmet la flotte courante en JSON via HAW_JSON + stdin (haw.plugin/1), et le code de sortie du plugin devient celui de haw — un plugin est donc un gate de CI à part entière. Découvre-les, installe-les et génère-en le squelette :

haw plugins list                     # plugins natifs + installés
haw plugins list --remote            # l'index communautaire
haw plugins install aspice           # délègue à cargo install
haw plugins new mycheck --lang python   # squelette exécutable (rust|python|go|shell)

Le squelette est un plugin complet et exécutable : il lit le contexte, gère --help et --format json, émet un document haw.plugin.report/1, et échoue en mode ouvert en dehors d’un espace de travail. Mets-le sur ton PATH et il devient instantanément une sous-commande haw — sans recompiler haw.

Astuce : les fonctionnalités de gouvernance propres à haw — SBOM, signature, secret-gate — sont livrées sous forme de plugins sur exactement ce modèle, donc rien ici n’est de seconde zone. Le contrat complet, les JSON Schemas et les bindings de langage se trouvent dans Plugins.

La vraie puissance, ce sont les hooks de cycle de vie : abonne un plugin à une phase dans [plugins] et il se déclenche automatiquement autour des opérations de flotte — c’est exactement ainsi que sont branchées les fonctionnalités de chaîne d’approvisionnement ci-dessous.

🔧 3. Le pipeline de CI — toujours les mêmes quatre mouvements

Voici le fruit de tout ce que tu as appris aux chapitres 3 et 6. Un pipeline haw a partout la même forme :

sync  →  verify  →  build  →  test
  • sync l’arbre vers les SHAs épinglés dans haw.lock,
  • verify que l’arbre correspond au lock — le gate de dérive, sortie 3 en cas de dérive,
  • build et test toute la flotte (chacun fait échouer le job avec un code non nul).

Un job GitHub Actions, tout droit sorti du README :

jobs:
  flotte:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4          # le dépôt du manifeste (haw.toml + haw.lock)
      - run: cargo install hawser          # ou télécharge le binaire musl signé
      - run: haw sync --filter=blob:none   # clone partiel → rapide sur les grandes flottes
      - run: haw verify                    # sortie 3 si l'arbre dérive de haw.lock
      - run: haw build
      - run: haw test
    env:
      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}   # uniquement si une étape appelle l'API de la forge

La CI GitLab, ce sont les quatre mêmes mouvements identiques avec variables: { GITLAB_TOKEN: $CI_JOB_TOKEN }.

Astuce : sur une grande flotte, associe haw sync --filter=blob:none (clone partiel — tout l’historique, blobs paresseux) à un cache du magasin d’objets partagé. Les clones restent rapides sans casser les SHAs épinglés, car chaque commit reste accessible.

♻️ 4. La reproductibilité, imposée

Tout le pipeline repose sur haw.lock. Deux flags le rendent hermétique en CI :

haw sync --locked        # échoue sauf si haw.lock existe (pas de résolution de rev)
haw verify               # vérifie arbre == lock, sortie 3 en cas de dérive

--locked refuse d’inventer un lock à la volée — la CI doit compiler à partir de la baseline committée, jamais résoudre à neuf. verify prouve ensuite que le checkout y correspond. Ensemble, ils garantissent que l’arbre en CI est octet pour octet celui que tu as committé.

📦 5. Distribution — publie ce que la flotte a produit

Une fois la flotte compilée, haw publish téléverse ses artefacts vers un registre d’artefacts generic/raw — Nexus, Artifactory, GitLab ou Bitbucket :

haw publish dist/*.tar.gz --to nexus
haw publish dist/*.tar.gz --to nexus --dry-run   # affiche le plan, pas d'identifiants, pas de réseau

--dry-run affiche exactement ce qui serait téléversé (cible, nom, version, chaque fichier) sans toucher au réseau ni nécessiter d’identifiants — parfait pour brancher l’étape en toute sécurité d’abord. Les identifiants proviennent des variables d’environnement de la cible (par ex. NEXUS_URL, NEXUS_USER, NEXUS_PASS).

🔏 6. Signature, SBOM et provenance — la chaîne d’approvisionnement

C’est là que haw prend toute sa valeur pour les releases sérieuses. Chaque release signée est livrée avec une somme de contrôle .sha256 et une signature cosign sans clé (.sig/.pem) que tu peux vérifier hors ligne — même sur un hôte isolé du réseau (voir Installer hawser).

Pour ta flotte, les fonctionnalités de chaîne d’approvisionnement sont livrées sous forme des plugins de gouvernance que tu as découverts en haut de ce chapitre, abonnés à des phases du cycle de vie :

[plugins]
compliance = ["post-build"]    # SBOM (CycloneDX + SPDX) après un build
artifact   = ["post-land"]     # provenance SLSA/in-toto + signature cosign/minisign
gate       = ["pre-request"]   # le gate secret/hygiène bloque une mauvaise PR avant son ouverture
  • SBOM — une nomenclature (CycloneDX + SPDX) de ce qui est entré dans le build.
  • Provenance — des enregistrements SLSA/in-toto de comment ça a été compilé et par qui.
  • Signature — des signatures cosign/minisign pour que les consommateurs puissent vérifier l’authenticité.

Et quand quelqu’un demande « qu’est-ce qui a été livré exactement ? », haw evidence regroupe le manifeste, le lock, le journal d’audit et le statut dans une seule archive :

haw evidence --out haw-evidence.tar.gz
wrote evidence bundle haw-evidence.tar.gz

(Lancé seul, haw evidence écrit ./haw-evidence.tar.gz par défaut ; --out ne fait que choisir le chemin.)

🏛️ 7. L’angle conformité / automobile

Si tu travailles sous une norme — ISO 26262, DO-178C, Automotive SPICE, CRA — les éléments ci-dessus sont tes preuves, parce qu’ils s’ancrent dans le lock épinglé :

Norme / artefactComment haw la couvre
Automotive SPICEhaw-aspice émet une traçabilité dépôt → SHA épinglé → domaine de processus
MISRA Chaw-misra lance cppcheck --addon=misra sur toute la flotte comme gate pre-request
ISO 26262 / DO-178Carchive haw evidence + SBOM + provenance issus des plugins de gouvernance
AUTOSAR ARXMLdépôts de config épinglés à des SHAs exacts dans haw.lock, versionnés avec le code

Le lock reproductible est le fondement : il transforme « la baseline qui était en production en mars » en un fait exact, re-compilable et auditable, plutôt qu’en une supposition. Voir Domaines et Conformité pour le mapping complet.

🪝 8. Hooks d’intégrité — attrape la dérive avant qu’elle soit committée

Un dernier garde-fou. haw hooks install écrit un hook pre-commit dans chaque dépôt qui lance haw verify — ainsi un commit qui ferait dériver l’arbre du lock est attrapé localement, avant même d’atteindre la CI :

haw hooks install
  ✓ hello-world  pre-commit -> haw verify
  ✓ spoon-knife  pre-commit -> haw verify
installed the integrity pre-commit in 2 repo(s)

haw hooks list affiche les hooks de cycle de vie que l’espace de travail définit (exécutables sous .haw/hooks) — distincts du pre-commit d’intégrité par dépôt ci-dessus. Sur un espace de travail neuf où aucun n’est encore défini, il t’indique où les ajouter :

haw hooks list
no lifecycle hooks — add executables under /path/to/my-first-stack/.haw/hooks

Voilà toute la boucle de production. Lock épinglé, gate de dérive, build/test de flotte, artefacts signés et une archive de preuves — les mêmes primitives servent un projet perso comme un audit ISO 26262.

✅ Récapitulatif

  • Le manifeste est du code de confiance — ne lance haw que sur des haw.toml / plugins en qui tu as confiance ; les tokens restent dans l’environnement, jamais stockés.
  • Le pipeline de CI, c’est toujours sync → verify → build → test ; verify sort avec 3 en cas de dérive.
  • --locked + verify imposent que la CI compile la baseline committée, de manière reproductible.
  • haw publish --to <nexus|artifactory|gitlab|bitbucket> distribue les artefacts (--dry-run pour prévisualiser).
  • Tout haw <name> inconnu lance un plugin haw-<name> depuis le PATH — sans fork ; les plugins de gouvernance ajoutent SBOM, provenance et signature sur les phases du cycle de vie ; haw evidence regroupe la piste d’audit ; les releases sont signées avec cosign.
  • Les mêmes primitives se transposent directement sur la conformité ASPICE / ISO 26262 / DO-178C / CRA.

🎉 Tu l’as fait

Course complete — you've learned hawser

Toute la boucle, cochée — composer, orchestrer, livrer, étendre et gouverner.

Tu es passé de « c’est quoi ce truc, au juste ? » à composer une flotte, l’épingler à un lockfile, vivre dans le cockpit, livrer des changesets cross-dépôts, compiler et tester le tout, l’étendre avec un plugin, et faire tourner l’ensemble en production avec une piste d’audit. Voilà tout l’outil.

Et maintenant :

Maintenant, va composer quelque chose. Bienvenue à bord.