Aller au contenu

Bootstrapper la pipeline CI

Tu installes Kirexo sur une nouvelle instance GitLab (fork, miroir, nouveau namespace) et tu veux que la pipeline CI tourne complètement : quality, tests, builds Docker, publication de la doc sur https://doc.kirexo.app/, schedule de maintenance quotidienne (Renovate, audit Composer, scan CVE, version-check d'outils).

Cette page enchaîne dans l'ordre les actions manuelles à réaliser. Chaque étape débloque la suivante — ne pas en sauter. Le détail de chaque sous-procédure est documenté ailleurs ; cette page-ci sert d'index séquentiel.

Prérequis

  • Tu as les droits Maintainer ou Owner sur le projet GitLab.
  • Tu as accès à la zone DNS de kirexo.app (registrar, panneau Cloudflare, etc.).
  • Le code Kirexo est déjà poussé sur la branche main du projet GitLab cible (la pipeline ne peut pas tourner si le repo est vide).

Vue d'ensemble

Étape Action Débloque
1 Réserver doc.kirexo.app dans la zone DNS Étape 4 (custom domain Pages)
2 Créer le Personal Access Token GITLAB_TOKEN Étape 3
3 Configurer la variable CI/CD GITLAB_TOKEN (masked, non protected) Étapes 4 et 5
4 Associer le domaine doc.kirexo.app à GitLab Pages Publication de la doc sur l'URL canonique
5 Créer la schedule cron 0 5 * * * sur main Audit Composer + Renovate + tools:version-check + scan CVE quotidiens
6 Bootstrap manuel docker:build-base puis docker:build-dev Tous les jobs PHP (quality:*, test:*)
7 Activer la cleanup policy du Container Registry Empêche kirexo-prod:<YYYYMMDDHHMM> d'accumuler indéfiniment au fil des releases

Étape 1 — Réserver le DNS doc.kirexo.app

Préalable à toute association de custom domain côté GitLab Pages. Si l'enregistrement DNS n'existe pas, la vérification de propriété (étape 4) échoue immédiatement.

Dans le panneau DNS de ton registrar, crée un enregistrement CNAME :

Type Nom Valeur
CNAME doc <namespace>.gitlab.io. (le point final est important — shaurifr.gitlab.io. pour l'instance de référence)

Cloudflare : DNS only

Si la zone est gérée par Cloudflare, mets l'enregistrement en mode DNS only (nuage gris). Le proxy Cloudflare casserait le challenge Let's Encrypt à l'étape 4.

La propagation DNS prend de quelques minutes à 24 h selon le TTL — autant la lancer au plus tôt.

Vérifier la propagation

dig +short CNAME doc.kirexo.app
Attendu : la valeur du CNAME cible. Tant que la commande ne renvoie rien, l'étape 4 échouera.

Étape 2 — Créer le Personal Access Token GITLAB_TOKEN

Le token est utilisé par quatre jobs CI : tag:create (création de tag), security:composer-audit (MR de patch sécurité ou issue de fallback), tools:version-check (issue de retard d'outils) et dependencies:renovate (ouverture des MRs Renovate).

PAT et pas project access token

Sur GitLab.com tier gratuit, les project access tokens sont réservés à Premium/Ultimate. Le seul type de token utilisable en variable CI/CD est un Personal Access Token rattaché à un compte ayant au moins le rôle Maintainer sur le projet.

  1. Sur le compte propriétaire, aller dans User Settings → Access Tokens.
  2. Cliquer sur Add new token.
  3. Renseigner :

    Champ Valeur
    Token name kirexo-ci (ou ce que tu veux)
    Expiration date une date dans 1 an max (GitLab impose une expiration)
    Scopes api + write_repository
  4. Cliquer sur Create personal access token.

  5. Copier la valeur affichée immédiatement — GitLab ne la ré-affichera plus.

Les deux scopes sont obligatoires

  • api couvre la création d'issues et de merge requests (security:composer-audit en fallback, tools:version-check, Renovate qui ouvre les MRs).
  • write_repository couvre la création de branches et de tags : requis par security:composer-audit quand l'update résout les vulnérabilités (il pousse une branche security/composer-* puis ouvre la MR), par tag:create (création du tag de release) et par Renovate (création des branches renovate/*).

Un token avec api seul faisait tourner la pipeline avant l'étape 4 ; à partir de l'étape 4, security:composer-audit échoue sur 403 Forbidden au moment du git push si write_repository manque.

Étape 3 — Configurer la variable CI/CD GITLAB_TOKEN

  1. Dans le projet GitLab cible, aller dans Settings → CI/CD → Variables.
  2. Cliquer sur Add variable.
  3. Renseigner :

    Champ Valeur
    Type Variable
    Environments All (default)
    Visibility Masked
    Flags Protect variable décoché
    Key GITLAB_TOKEN
    Value (la valeur PAT copiée à l'étape 2)
  4. Cliquer sur Add variable.

Masked oui, Protected non

  • Mask doit être coché : sans lui, le token apparaît en clair si un job l'echo par mégarde dans son log.
  • Protect doit rester décoché : security:container-issue (+ :builders) tourne sur la pipeline de la MR / feature branch courante pour ouvrir l'issue d'alerte CVE, et Protect variable rendrait GITLAB_TOKEN indisponible sur ces refs non protégées — l'appel POST /projects/:id/issues partirait sans PRIVATE-TOKEN et retomberait en HTTP 401.

Si Mask refuse la valeur (« value does not meet the masking requirements »), regénère le PAT — sa valeur contient probablement un caractère interdit (rare avec les PATs récents).

Détail complet et liste des jobs qui consomment ce token : voir Variables CI/CD GitLab.

Les jobs security:container-issue réutilisent le même GITLAB_TOKEN

Les deux jobs d'alerting CVE conteneur (security:container-issue et security:container-issue:builders) s'authentifient via GITLAB_TOKEN (PRIVATE-TOKEN), le même PAT que celui que tu viens de configurer pour security:composer-audit, tools:version-check et Renovate. Aucune variable supplémentaire à provisionner, et aucun pré-requis Token Access à activer pour ce projet : on n'utilise pas CI_JOB_TOKEN ici parce que sa whitelist sur GitLab Free ne couvre pas POST /projects/:id/issues (retour HTTP 401 testé empiriquement). Le scope api du PAT déjà créé suffit.

Étape 4 — Configurer le custom domain GitLab Pages

L'enregistrement DNS de l'étape 1 doit avoir propagé (vérifier avec dig +short CNAME doc.kirexo.app).

Suivre la procédure complète dans Configurer le domaine GitLab Pages : déclaration du domaine, enregistrement TXT de vérification, certificat Let's Encrypt, Force HTTPS.

La première release peut attendre

GitLab Pages affiche un 404 tant que le job pages n'a pas tourné au moins une fois. C'est attendu — le bootstrap final (étape 6) ne crée pas de release ; la première vraie URL https://doc.kirexo.app/ n'apparaîtra qu'après ton premier tag (le job pages du stage release ne tourne que sur tag — cf. Créer un tag de release).

Étape 5 — Créer la schedule cron 0 5 * * * sur main

Cette unique schedule déclenche tous les jobs périodiques du stage maintenance : security:composer-audit, dependencies:renovate, tools:version-check, container_scanning (kirexo-prod), container_scanning:builders (kirexo-base, kirexo-dev) et leurs jobs d'alerting (security:container-issue, security:container-issue:builders).

Suivre la procédure dans Configurer l'audit de sécurité quotidien — schedule unique 0 5 * * * sur main, sans variable additionnelle.

Tester immédiatement

Une fois la schedule créée, clique sur l'icône ▶ à droite. La pipeline se lance avec $CI_PIPELINE_SOURCE == "schedule" exactement comme à 5 h UTC. Tu peux ainsi valider en quelques minutes que GITLAB_TOKEN a les bons scopes (sinon security:composer-audit échoue sur 403 Forbidden au git push, et Renovate sur 401 à l'ouverture de MR).

Étape 6 — Bootstrap manuel des images kirexo-base et kirexo-dev

C'est la dernière étape — et la plus facile à oublier. Sans ces deux images dans le registry, tous les jobs PHP de la pipeline standard plantent immédiatement sur ErrImagePull (l'image qu'ils consomment n'existe pas). Le commentaire en tête de .gitlab-ci.yml rappelle ce prérequis.

  1. Dans le projet GitLab, aller dans Build → Pipelines.
  2. Cliquer sur Run pipeline (en haut à droite).
  3. Branche cible : main. Pas de variable à passer. Cliquer sur Run pipeline.
  4. Sur la page de la pipeline qui démarre, repérer le stage docker.
  5. Cliquer sur le bouton ▶ (manuel) du job docker:build-base. Attendre sa fin (vert).
  6. Cliquer sur le bouton ▶ du job docker:build-dev. Attendre sa fin (vert).

docker:build-dev dépend de docker:build-base (cf. .gitlab/ci/docker.yml) — joue-les dans cet ordre.

Pas besoin de bootstrapper kirexo-prod ni kirexo-docs

  • kirexo-prod est construite automatiquement au premier tag de release par docker:build-prod. Elle n'est consommée par aucun job de runner CI — uniquement par la prod via compose.prod.yaml.
  • kirexo-docs est construite automatiquement par docker:build-docs sur main (quand mkdocs/Dockerfile change) ou au tag de release, avant le job pages qui la consomme. Aucun bootstrap manuel requis.

Étape 7 — Activer la cleanup policy du Container Registry

À chaque tag de release, docker:build-prod pousse une nouvelle image kirexo-prod:<YYYYMMDDHHMM> (~150-300 Mo) en plus de réécrire le tag mobile :latest. Sans nettoyage, le registry accumule des dizaines de tags par mois. Autant configurer la politique de cleanup dès le bootstrap, avant la première release — elle s'appliquera au fur et à mesure que les tags arrivent, sans rien à modifier plus tard.

La procédure (paramètres UI exacts à saisir, choix de regex, comportement combiné Keep/Remove) est documentée séparément : Configurer la cleanup policy du registry.

Politique recommandée en résumé : garder les 10 derniers tags [0-9]{12} + :latest, cadence hebdomadaire. Les autres images (kirexo-base, kirexo-dev, kirexo-docs) ne sont pas affectées — leurs tags n'utilisent pas le format YYYYMMDDHHMM.

Vérification finale

À ce stade :

  • [ ] dig +short CNAME doc.kirexo.app renvoie la cible GitLab Pages.
  • [ ] Settings → CI/CD → Variables affiche GITLAB_TOKEN en Masked (et pas en Protected).
  • [ ] Settings → Pages affiche doc.kirexo.app en Verified avec certificat Let's Encrypt actif et Force HTTPS coché.
  • [ ] Build → Pipeline schedules affiche la schedule Audit sécurité quotidien (ou son équivalent) activée sur main.
  • [ ] Deploy → Container Registry liste au moins kirexo-base:php8.5 et kirexo-dev:php8.5.
  • [ ] Settings → Packages and registries → Container registry → Cleanup policy est Enabled avec la politique recommandée.

Une nouvelle MR pousser sur main doit maintenant déclencher une pipeline complète qui passe — toute la chaîne quality + test consomme les deux images bootstrappées à l'étape 6, l'audit Composer bloquant (quality:composer-audit) consomme le token de l'étape 3, et le rebuild de doc passera dès la prochaine release sur le domaine de l'étape 4.

Signature et SBOM : pas de variable CI/CD à provisionner

Les jobs docker:sign-prod (signature keyless cosign de kirexo-prod) et release:sbom (SBOM SPDX + CycloneDX via syft) tournent automatiquement sur la première release sans configuration supplémentaire :

  • Signature keyless : aucune clé privée à gérer. Le JWT OIDC est généré automatiquement par GitLab via id_tokens.SIGSTORE_ID_TOKEN, et Fulcio / Rekor sont des services publics. Cf. Signature keyless de kirexo-prod.
  • SBOM : syft réutilise CI_REGISTRY_USER / CI_REGISTRY_PASSWORD natifs pour scanner l'image directement dans le registry. Cf. Job release:sbom.

Signaux que tout fonctionne après la première release :

  • [ ] Build → Pipelines : docker:sign-prod est passé vert sur la pipeline du tag.
  • [ ] Deploy → Releases : le widget Assets de la release affiche les deux liens SBOM (SPDX JSON) et SBOM (CycloneDX JSON).

Et après ?