Front-end angularforall.com

- Nx Polygraph : conformance multi-repo

Angular Nx-Polygraph Nx-Cloud Monorepo Multi-Repo Conformance Governance Architecture Ci-Cd Audit Enterprise Eslint Compliance Devops
Nx Polygraph : conformance multi-repo

Gouvernez plusieurs repos Angular avec Nx Polygraph : audits multi-repos, regles centralisees, integration CI et dashboard Nx Cloud pour grandes organisations.

Le problème : harmoniser N repos Angular

Quand une organisation Angular dépasse les 5-10 développeurs, deux stratégies s'opposent : le monorepo (tout dans un seul Nx workspace) ou le multi-repo (chaque équipe gère son propre repo). Le monorepo simplifie l'harmonisation mais devient lourd au-delà de 200+ libraries. Le multi-repo offre l'autonomie mais introduit une dérive : chaque équipe utilise sa propre version d'Angular, sa propre config ESLint, ses propres conventions.

Résultat dans la pratique : sur 12 repos d'une banque, on trouve 4 versions d'Angular différentes (16, 17, 18, 19), 3 configs ESLint, 7 conventions de nommage de dossier, 5 stratégies de tests. Les développeurs qui changent d'équipe perdent une semaine à comprendre le contexte. Les audits sécurité explosent les délais. C'est exactement le problème que Nx Polygraph vient résoudre.

Étymologie : « Polygraph » signifie « qui mesure plusieurs (poly) signaux ». L'outil mesure la conformité de plusieurs repos en parallèle, comme un capteur multi-canal qui aurait un repo Angular au bout de chaque sonde.

Symptômes d'une organisation qui a besoin de Polygraph

  • 5+ repos Angular indépendants dans l'organisation
  • Versions d'Angular divergentes entre équipes (16 vs 20)
  • Politique de sécurité (CSP, secrets) appliquée inégalement
  • Audits trimestriels qui prennent 2 semaines à compiler
  • Nouveaux devs perdus quand ils changent d'équipe
  • Bugs récurrents dus à des configs ESLint absentes ou divergentes

Nx Polygraph : présentation

Nx Polygraph est un outil de gouvernance multi-repo lancé par Nrwl (l'équipe Nx) en 2025. Il s'appuie sur l'infrastructure Nx Cloud existante. Son rôle : scanner périodiquement tous les repos Nx d'une organisation et appliquer des règles de conformance communes — versions de dépendances, structure, sécurité, qualité.

Trois apports clés

Capacité Sans Polygraph Avec Polygraph
Audit de versions Angular Script manuel par repo Dashboard temps réel sur tous repos
Application de règles ESLint Copier la config dans chaque repo Règle centralisée, sync auto
Détection de dépendance interdite npm audit + grep manuel Règle Polygraph globale
Reporting compliance Spreadsheet à compiler Export PDF automatique
Blocage CI Par repo, à dupliquer Step CI unique partout
Polygraph ≠ monorepo : Polygraph NE FUSIONNE PAS vos repos. Chaque équipe garde son repo, son workflow Git, sa CI/CD. Polygraph se contente d'auditer les règles à travers ces repos via une lecture des fichiers depuis l'agent Nx Cloud installé.

Installation et premier audit

Polygraph s'installe en deux temps : un repo central qui définit les règles, et un plugin dans chaque repo cible qui exécute les vérifications.

Étape 1 : créer le repo central de conformance

// Créer un workspace Nx dédié à la gouvernance
npx create-nx-workspace@latest my-org-conformance --preset=npm

cd my-org-conformance

// Ajouter le plugin Polygraph (officiel Nrwl)
npm install --save-dev @nx/polygraph

// Initialiser la config Polygraph
nx g @nx/polygraph:init
// my-org-conformance/polygraph.config.ts
import { definePolygraphConfig } from '@nx/polygraph';

export default definePolygraphConfig({
    // Identité de l'organisation dans Nx Cloud
    organizationId: 'my-org',

    // Liste des repos Nx surveillés
    repos: [
        { id: 'frontend-app',  url: 'github.com/my-org/frontend-app',  branch: 'main' },
        { id: 'admin-portal',  url: 'github.com/my-org/admin-portal',  branch: 'main' },
        { id: 'mobile-shell',  url: 'github.com/my-org/mobile-shell',  branch: 'main' },
        { id: 'design-system', url: 'github.com/my-org/design-system', branch: 'develop' },
    ],

    // Règles appliquées globalement
    rules: [
        'angular-version-min',         // version Angular minimale
        'no-deprecated-rxjs',          // détection d'usages dépréciés
        'eslint-config-required',      // chaque repo doit avoir .eslintrc
        'no-public-api-keys',          // détecte les clés API en clair
    ],

    // Sévérité globale (peut être overridée par règle)
    severity: 'error',
});

Étape 2 : installer l'agent dans chaque repo cible

// Sur chaque repo Angular surveillé (frontend-app, admin-portal, etc.)
npm install --save-dev @nx/polygraph-agent

// Ajouter le step au CI (exemple GitHub Actions, voir section dédiée)
nx g @nx/polygraph-agent:register --organization=my-org

Étape 3 : lancer le premier audit

// Depuis my-org-conformance/
nx polygraph:audit

// Sortie console (extrait)
// 🟢 frontend-app    : angular-version-min ✓  (19.2)
// 🟢 frontend-app    : no-deprecated-rxjs  ✓
// 🔴 admin-portal    : angular-version-min ✗  (16.4 < required 19.0)
// 🟢 admin-portal    : eslint-config-required ✓
// 🟡 mobile-shell    : no-public-api-keys WARNING (clé Stripe en clair dans .env.example)
//
// 📊 Audit complet sur 4 repos en 47s
// 🔍 Total : 2 erreurs, 1 warning
// 📥 Rapport : https://nx-cloud.io/orgs/my-org/conformance/2026-05-28

En moins d'une minute, vous obtenez une vision exhaustive de l'état de conformité de toute votre organisation Angular. Cette information était auparavant inaccessible ou nécessitait des journées d'audit manuel.

Règles de conformance built-in

Polygraph fournit une bibliothèque de règles prêtes à l'emploi, couvrant les besoins les plus courants des organisations Angular. Voici les plus utiles.

Catégorie : versions et dépendances

// polygraph.config.ts — règles versions
rules: [
    {
        rule: 'angular-version-min',
        options: { minVersion: '19.0.0' },  // refuser tout repo < Angular 19
    },
    {
        rule: 'rxjs-version-aligned',
        options: { exactVersion: '7.8.x' }, // tous les repos sur la même version RxJS
    },
    {
        rule: 'no-deprecated-packages',
        options: {
            deprecated: [
                '@angular/flex-layout',     // remplacé par CSS Grid/Flexbox
                'tslint',                   // remplacé par ESLint
                'protractor',               // remplacé par Playwright
            ],
        },
    },
    {
        rule: 'allowed-licenses',
        options: { allow: ['MIT', 'Apache-2.0', 'BSD-3-Clause', 'ISC'] },
        // Détecte automatiquement les deps avec licences problématiques (GPL, AGPL...)
    },
],

Catégorie : structure et organisation

rules: [
    {
        rule: 'required-folder-structure',
        options: {
            required: ['src/', 'src/app/', 'src/environments/', 'e2e/'],
            forbidden: ['src/legacy/'],
        },
    },
    {
        rule: 'eslint-config-required',
        options: {
            // Doit étendre la config partagée de l'organisation
            mustExtend: ['@my-org/eslint-config'],
        },
    },
    {
        rule: 'naming-convention',
        options: {
            // Tous les composants doivent suffixer .component.ts
            componentSuffix: '.component.ts',
            // Tous les services doivent suffixer .service.ts ou .store.ts
            serviceSuffix:   ['.service.ts', '.store.ts'],
        },
    },
],

Catégorie : sécurité

rules: [
    {
        rule: 'no-public-api-keys',
        options: {
            // Regex de clés à détecter dans le code source
            patterns: [
                /sk-[a-zA-Z0-9]{20,}/,     // OpenAI
                /AIza[a-zA-Z0-9_-]{35}/,   // Google API keys
                /AKIA[A-Z0-9]{16}/,        // AWS access keys
            ],
        },
    },
    {
        rule: 'csp-required',
        options: {
            // Chaque index.html doit avoir une CSP meta
            requireMeta: 'Content-Security-Policy',
        },
    },
    {
        rule: 'commit-signed',
        options: {
            // Tous les commits doivent être signés GPG/SSH
            sinceDate: '2025-01-01',
        },
    },
],

Catégorie : qualité

rules: [
    {
        rule: 'test-coverage-min',
        options: {
            // Lecture du coverage report — fail si en dessous
            lines: 70, branches: 65, functions: 70,
        },
    },
    {
        rule: 'commit-conventional',
        options: {
            // Force le format Conventional Commits
            pattern: /^(feat|fix|chore|docs|refactor|test|perf|build|ci)(\(.+\))?: .+/,
        },
    },
    {
        rule: 'no-circular-deps',
        // Aucune dépendance circulaire entre libs/apps
    },
],

Écrire ses propres règles

Les règles built-in couvrent 80% des besoins. Pour les politiques spécifiques à votre organisation, Polygraph permet de définir des règles custom en TypeScript.

// my-org-conformance/rules/no-mock-data-in-prod.rule.ts
import { definePolygraphRule, type RuleContext } from '@nx/polygraph';

// Règle interne : interdire d'importer @my-org/mock-data ailleurs que dans les specs
export default definePolygraphRule({
    name: 'no-mock-data-in-prod',
    description: 'Mock data must only be imported in *.spec.ts and *.test.ts files',
    severity: 'error',

    async run(ctx: RuleContext) {
        // ctx fournit l'accès au repo cloné en lecture seule
        const tsFiles = await ctx.glob('**/*.ts', {
            ignore: ['**/*.spec.ts', '**/*.test.ts', 'node_modules/**'],
        });

        const violations: { file: string; line: number; message: string }[] = [];

        for (const file of tsFiles) {
            const content = await ctx.readFile(file);
            const lines = content.split('\n');

            lines.forEach((line, idx) => {
                // Détecte tout import depuis @my-org/mock-data dans un fichier prod
                if (/import .* from ['"]@my-org\/mock-data['"]/.test(line)) {
                    violations.push({
                        file,
                        line: idx + 1,
                        message: `Mock data imported in production file. Use real API or move to spec file.`,
                    });
                }
            });
        }

        return violations;
    },
});
// polygraph.config.ts — activer la règle custom
import noMockDataInProd from './rules/no-mock-data-in-prod.rule';

export default definePolygraphConfig({
    organizationId: 'my-org',
    repos: [ /* ... */ ],
    rules: [
        'angular-version-min',
        noMockDataInProd,  // règle custom importée
        // ... autres
    ],
});

Pattern courant : sync version Angular cross-repo

// my-org-conformance/rules/sync-angular-version.rule.ts
import { definePolygraphRule } from '@nx/polygraph';

// Compare tous les repos entre eux : tous doivent être sur la même major Angular
export default definePolygraphRule({
    name: 'sync-angular-version-cross-repo',

    async run(ctx) {
        // ctx.repos donne accès à TOUS les repos du scope Polygraph
        const versions = await Promise.all(
            ctx.repos.map(async r => ({
                repoId: r.id,
                version: await r.readPackageVersion('@angular/core'),
            })),
        );

        // Extrait juste la major (19.2.1 → 19)
        const majors = versions.map(v => ({
            ...v,
            major: parseInt(v.version.split('.')[0], 10),
        }));
        const uniqueMajors = [...new Set(majors.map(m => m.major))];

        if (uniqueMajors.length === 1) return []; // tous alignés, OK

        // Sinon : violation pour chaque repo non aligné sur la majority
        const dominantMajor = uniqueMajors.sort((a, b) => b - a)[0];
        return majors
            .filter(m => m.major !== dominantMajor)
            .map(m => ({
                file:    'package.json',
                line:    1,
                message: `Repo ${m.repoId} sur Angular ${m.major}, attendu ${dominantMajor}`,
            }));
    },
});
Cas réel observé : sur un groupe média avec 8 repos Angular, l'écart entre v16 et v20 entraînait des bugs d'interop sur le design system partagé. La règle sync-angular-version-cross-repo a été le déclencheur d'une migration coordonnée vers v20 en 6 semaines, là où le sujet traînait depuis 9 mois.

Dashboard Nx Cloud et reporting

Au-delà de la ligne de commande, Polygraph publie ses résultats sur le dashboard Nx Cloud. C'est ce qui le rend exploitable par les CTO, RSSI et équipes governance.

Vues principales du dashboard

  • Heatmap multi-repo : grille (repo × règle) avec rouge/vert immédiatement lisible
  • Tendance temporelle : évolution du score de conformance sur 30/90 jours
  • Top violations : règles enfreintes le plus souvent, classées par impact
  • Détail par repo : drill-down avec fichier + ligne + suggestion de correction

Export PDF pour les audits

// Génère un rapport PDF complet à partager avec le RSSI
nx polygraph:report --format=pdf --output=./audit-2026-05.pdf

// Le PDF contient :
// - Résumé exécutif (1 page)
// - Vue heatmap (2 pages)
// - Détail par repo (1 page par repo)
// - Plan d'action recommandé (1 page)

Webhook Slack pour alertes

// polygraph.config.ts — alerter Slack à chaque audit
import { definePolygraphConfig } from '@nx/polygraph';

export default definePolygraphConfig({
    /* ... */
    notifications: [
        {
            type: 'slack',
            webhookUrl: process.env.SLACK_GOVERNANCE_WEBHOOK!,
            // Notifier UNIQUEMENT si une nouvelle violation apparaît (pas les warnings stables)
            trigger: 'new-violation',
            severity: 'error',
        },
        {
            type: 'email',
            recipients: ['cto@my-org.com', 'security@my-org.com'],
            trigger: 'weekly-summary',
        },
    ],
});

Intégration CI : bloquer les merges non conformes

L'audit hebdomadaire est utile, mais le vrai gain vient quand Polygraph s'exécute à chaque PR pour bloquer le merge des changements qui dégraderaient la conformité.

GitHub Actions — workflow par repo

# .github/workflows/polygraph.yml dans CHAQUE repo cible
name: Polygraph conformance check

on:
  pull_request:
    branches: [main, develop]

jobs:
  check-conformance:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0  # historique complet pour règles git-aware

      - uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'

      - run: npm ci

      # Exécute les règles Polygraph définies dans le repo central
      - name: Run Polygraph agent
        env:
          NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_TOKEN }}
        run: npx polygraph-agent check --against=main

      # Si des violations sont détectées, le step échoue → PR rouge → merge bloqué

Mode "warning only" pour migration progressive

// polygraph.config.ts — désactiver le blocage pendant 30 jours pour onboarding
rules: [
    {
        rule: 'angular-version-min',
        options: { minVersion: '19.0.0' },
        // En warning jusqu'au 28 juin 2026 — laisse le temps de migrer
        severity: 'warning',
        becomesErrorOn: '2026-06-28',
    },
],
Stratégie d'introduction : commencez TOUJOURS en mode warning. Pendant 30 jours, le dashboard pointe les violations, les équipes corrigent au rythme. Au jour J, vous flippez en error et le CI bloque. Aucune surprise, adoption en douceur.

Stratégie d'adoption à l'échelle

Imposer Polygraph d'un coup à 20 repos crée plus de bruit que de valeur. Voici la séquence d'adoption éprouvée sur plusieurs grandes organisations.

Phase 1 (Semaine 1-2) — Pilote sur 2 repos volontaires

  • Choisir 2 repos avec équipes motivées par la gouvernance
  • Activer 3 règles simples : angular-version-min, eslint-config-required, no-public-api-keys
  • Toutes en mode warning
  • Présenter les résultats en revue interne pour démontrer la valeur

Phase 2 (Mois 1) — Étendre à 50% des repos

  • Ajouter 5 règles supplémentaires (structure, qualité)
  • Passer les règles initiales en error pour les 2 pilotes
  • Garder warning pour les nouveaux repos

Phase 3 (Mois 2-3) — Adoption généralisée

  • Tous les repos sous Polygraph
  • Toutes les règles consensuelles en error
  • Webhook Slack actif sur le canal #governance
  • Rapport mensuel automatique au CTO

Phase 4 (Mois 4+) — Règles custom métier

  • Ajouter les règles spécifiques à votre métier (compliance bancaire, RGPD spécifique, etc.)
  • Mesurer le ROI : temps d'audit divisé, vélocité onboarding nouveau dev
  • Étendre à d'autres équipes (mobile, backend) si pertinent
Checklist d'adoption Polygraph :
  • Repo central de conformance créé et versionné
  • Compte Nx Cloud avec organisation configurée
  • Agent installé dans tous les repos cibles
  • 3 règles initiales activées en warning
  • CI GitHub Actions configuré sur tous les repos
  • Webhook Slack pour notifications nouvelles violations
  • Page Notion/Confluence documentant les règles actives
  • Personne désignée comme « owner » des règles (rotation possible)

Conclusion et roadmap

Nx Polygraph répond à un manque criant dans l'écosystème Angular : la gouvernance multi-repo. Pour les organisations qui ont 5+ repos Angular indépendants, c'est la pièce manquante entre la liberté du multi-repo et la cohérence du monorepo. Le ROI est généralement visible en 2-3 mois : audits divisés par 5, onboarding accéléré, sécurité renforcée.

Les évolutions annoncées pour 2026-2027 :

  • Polygraph v2 (été 2026) — support Bun et Deno workspaces
  • Auto-fix — application automatique des règles correctibles (versions, imports)
  • AI suggestions — Claude / GPT propose des PR de correction des violations
  • Marketplace de règles — partager les règles custom entre organisations
Aller plus loin : consultez la documentation officielle sur nx.dev/concepts/polygraph . Les podcasts « The Nx Show » couvrent des cas concrets d'adoption Polygraph chez Salesforce, Capital One et la BBC.

Partager