1 points par GN⁺ 2025-11-28 | 1 commentaires | Partager sur WhatsApp
  • Le projet .NET Unified Build introduit un nouveau système de build qui unifie l’ensemble du produit sous la forme d’un « dépôt monolithique virtuel » (Virtual Monolithic Repository, VMR) afin de réduire la complexité et l’inefficacité de l’ancienne structure de build fondée sur des dépôts distribués
  • L’ancienne organisation distribuée du produit offrait une grande indépendance et de la flexibilité, mais entraînait une lourde charge en matière de gestion des dépendances, cohérence des builds et vitesse
  • Unified Build étend les principes de Source Build pour les distributions Linux en introduisant une disposition unifiée des sources et une structure de « build vertical » (Vertical Build) afin de réduire les temps de build et d’améliorer la prévisibilité
  • Grâce au flux de code bidirectionnel (two-way code flow), aux tests de scénarios, ainsi qu’à l’amélioration de l’infrastructure de validation automatique et de signature, le système améliore à la fois l’efficacité des développeurs et la qualité du produit
  • Officiellement adopté dans .NET 10, ce système a obtenu des résultats concrets, notamment une réduction du temps de build (de 24 heures à moins de 7 heures), une baisse des coûts de maintenance et une meilleure fiabilité des livraisons

Contexte de l’évolution de l’architecture de build de .NET

  • Lors de son passage à l’open source en 2015-2016, .NET a été développé dans de nombreux dépôts distincts, notamment CoreCLR, CoreFX, ASP.NET Core et SDK
  • Chaque dépôt était buildé et publié indépendamment, l’ensemble du produit étant assemblé via un graphe de dépendances
  • Cette approche ressemble à l’écosystème OSS, mais en cas de correctif de sécurité ou de correction urgente, elle exige une coordination simultanée entre plusieurs équipes, rendant les délais imprévisibles
  • Malgré les avantages du développement distribué (layering, segmentation de la communauté, développement asynchrone, etc.), cette approche est inefficace pour garantir la cohérence du produit (coherency)

Complexité du produit et surcoût

  • Complexité (Complexity) : définie comme le nombre d’étapes nécessaires pour qu’une modification arrive jusqu’au client
    • Plus il y a de dépôts et de nœuds de dépendance, plus il faut de temps et de coordination humaine pour préserver la cohérence
  • Surcoût (Overhead) : temps qui ne produit pas directement un livrable pouvant être remis au client
    • Exemples : création de PR, attente d’approbation, mise en file d’attente, configuration de l’environnement
  • L’analyse du build du runtime .NET 8 a montré qu’environ 38,5 % du temps total de build correspondait à du surcoût
  • Lorsque complexité et surcoût se combinent, l’efficacité du build chute rapidement et le cycle global de release s’allonge

Origine de Source Build et de Unified Build

  • Source Build est un système conçu pour permettre aux distributions Linux de builder .NET hors ligne à partir d’une source unique
    • Principes : implémentation unique, plateforme unique, environnement de build unique
    • Un orchestrateur de build gère les dépendances entre composants et l’ordre de build
  • Source Build peut être réalisé en moins de 50 minutes grâce à une faible complexité et un faible surcoût
  • Microsoft a tenté d’appliquer ce concept à ses builds internes, mais s’est heurté à des difficultés liées au code source fermé, aux dépendances legacy et aux join entre plateformes
  • Pour y répondre, l’équipe a introduit des approches comme les paquets de référence uniquement (source-build-reference-packages), le principe d’implémentation unique et la suppression des join

Objectifs et conception de Unified Build

  • Permettre de builder l’ensemble du produit .NET à partir d’un seul commit
  • Générer toutes les distributions par plateforme dans un environnement unique
  • Permettre un build et une validation indépendants en dehors de Microsoft
  • Synchroniser automatiquement les modifications entre le VMR et les dépôts individuels via un flux de code bidirectionnel
  • Valider les fonctionnalités au niveau du produit complet grâce à des tests de scénarios
  • Paralléliser les builds par plateforme grâce à une architecture de build vertical (Vertical Build)
    • Avec environ 35 à 40 verticales de build (short/tall stack)

Étapes de mise en œuvre de Unified Build

  • .NET 7 : conception du concept et validation
  • .NET 8 : amélioration de l’infrastructure Source Build et mise en place des bases
  • .NET 9 : expérimentation du build vertical et du flux de code
  • .NET 10 : industrialisation complète et intégration dans la RTM
    • Introduction du nouveau processus de build dans la Preview 4, bascule complète à partir de la Preview 5

Principaux composants

Virtual Monolithic Repository (VMR)

  • Le dépôt dotnet/dotnet sert de disposition unifiée des sources pour l’ensemble des composants
  • Les développeurs peuvent travailler soit dans des dépôts individuels, soit dans le VMR, en combinant la flexibilité du distribué et la cohérence du monolithique

Vertical Build

  • Un build indépendant est exécuté pour chaque plateforme et runtime
  • Les résultats sont ensuite intégrés, certains join étant traités via des passes de build supplémentaires

Code Flow

  • Synchronisation bidirectionnelle du code : dépôt de composant → VMR, VMR → dépôt de composant
  • Le dernier état du flux de code est enregistré dans eng/Version.Details.xml
  • Les modifications sont générées sous forme de fichiers patch pour créer automatiquement des PR
  • Une logique de gestion des conflits et de reprise sur erreur est intégrée

Scenario Test Validation

  • En plus des tests unitaires existants, des tests de scénarios validant les fonctionnalités du produit dans son ensemble ont été ajoutés
  • Exécutés à partir des artefacts de build, ils renforcent la prévention des régressions et l’assurance qualité

Résultats et effets

  • Réduction du temps de build : plus de 24 heures → moins de 7 heures (signature comprise)
  • Gain de flexibilité : cycles de build et de déploiement plus courts, intégration facilitée des correctifs urgents
  • Meilleure prévisibilité : moment d’achèvement du build clairement identifiable après une modification
  • Amélioration de l’infrastructure : outils de signature, logs, builds parallèles, automatisation du flux de dépendances, etc.
  • Source Build pour les distributions Linux reste lui aussi en permanence dans un état propre avant build

Orientation future

  • Dans .NET 11, l’équipe prévoit d’introduire l’automatisation du flux de code et des agents de monitoring basés sur l’IA
    • Avec une automatisation du suivi des erreurs dans le processus PR → intégration au produit
  • À plus long terme, l’objectif est de supprimer les points de join pour simplifier le build et améliorer encore la vitesse
    • Objectif : un build complet en moins de 4 heures

Conclusion

  • En surmontant les limites du modèle de build distribué, Unified Build améliore en profondeur l’efficacité du build et du déploiement de .NET
  • Des progrès concrets ont été obtenus sur trois axes : réduction de la complexité et du surcoût, amélioration de la cohérence, de la vitesse et de la qualité
  • À partir de la RTM de .NET 10, ce système est appliqué à grande échelle et continuera d’être amélioré dans les versions à venir

1 commentaires

 
GN⁺ 2025-11-28
Avis Hacker News
  • J’admire vraiment l’équipe .NET
    Ils publient souvent des billets techniques très approfondis et ont une obsession impressionnante pour l’optimisation des performances (par ex. Kestrel, l’évolution d’Entity Framework)
    ASP.NET est l’un des rares grands projets à avoir survécu à un changement de l’ampleur de Python 2→3
    Avant, il s’appuyait sur des mécanismes presque magiques pour synchroniser les sessions, mais aujourd’hui il fonctionne d’une manière totalement différente
    C’est agréable de voir qu’une entreprise valorisée à 3 billions de dollars essaie sincèrement d’améliorer la stack que j’utilise

    • J’ai déjà utilisé Entity Framework, et c’était beaucoup trop lent
      Je l’ai donc remplacé par Dapper et un système de migrations maison, ce qui a fait passer le temps de validation et de seeding de la base au démarrage de 10 secondes à moins de 2 secondes (sur du matériel peu puissant avec SQLite)
      Les requêtes générées par Entity comportaient beaucoup trop de jointures multiples inutiles
      En ce moment, je migre vers un backend Go plus simple et je n’utilise .NET que pour d’autres solutions
      Des frameworks comme WPF avaient tellement de problèmes qu’il fallait presque bricoler du Win32
      Par exemple, ce n’est qu’avec .NET 9 qu’il renvoie correctement toutes les interfaces réseau. Les runtimes précédents n’exposaient que les NIC actives
      J’ai encore des projets qui doivent conserver le support de Windows 7
    • Je pense que beaucoup de projets sont restés sur le carreau sans pouvoir passer à .NET Core
      Même sur de nouveaux projets, il arrive encore qu’on doive utiliser .NET 4.8. Par exemple, lors de la génération de formules Excel, des problèmes de deadlock avec async/await surviennent
      En plus, des fonctionnalités d’intégration Windows sont cassées, si bien que le même appel réseau s’authentifie en 4.8 mais échoue sur Core
      L’effondrement de la rétrocompatibilité dans d’innombrables bibliothèques rend la migration difficile
      Les performances se sont améliorées, mais côté fonctionnalités, .NET Framework donne l’impression d’un fossile
      Il a fallu 15 ans avant qu’un sérialiseur JSON arrive dans la bibliothèque standard, et il n’y a toujours pas de prise en charge des formats d’image modernes comme webp ou heic
      Visual Studio affiche des messages de crash quasiment tous les jours
      J’étais autrefois un fan absolu de .NET, mais le leadership d’Anders me manque
  • Sur un projet perso récent, je développe un backend d’API REST en C# avec VSCode sur macOS, et je le déploie sur Linux depuis trois ans
    J’utilise SQLite, EFCore et Minimal API, et c’est bien plus agréable que le frontend (NextJS/React/MaterialUI, plus de 50 paquets npm)

    • Si l’API devient un peu complexe, je recommande la bibliothèque FastEndpoints
      C’est personnellement mon framework d’API préféré
      Le second choix serait une combinaison TS + Hono + Zod-OpenApi + SwaggerUI, mais la configuration du contexte de types est un peu fastidieuse
  • J’ai trouvé marquant que la base de l’ouverture en open source et du passage multiplateforme de .NET ait été le système de build des distributions Linux

    • Pour expliquer directement en tant qu’auteur de l’article, afin que les mainteneurs de distributions puissent inclure .NET dans les dépôts de paquets natifs, ils doivent pouvoir le compiler eux-mêmes
      Il fallait donc un système de build répondant à leurs exigences, et au final, s’aligner sur le modèle des distributions Linux était la seule voie possible
      Ce modèle est simple mais moins performant. Un système de build distribué avec cache serait plus rapide, mais il ne correspond pas au workflow des mainteneurs
      Nous avons estimé qu’optimiser pour la simplicité était préférable pour encourager la participation de la communauté
      L’objectif est de permettre à la communauté de construire et distribuer elle-même pour diverses plateformes comme BSD, S390x, etc.
    • Je pense que .NET a déjà largement dépassé le stade où il pourrait regretter son passage à l’open source
      La quantité de pull requests et de résultats positifs accumulés ces dix dernières années est stupéfiante
  • Je ne m’attendais pas à ce que l’un des articles de génie logiciel les plus marquants que j’ai lus cette année vienne de Microsoft
    J’aime les versions récentes de .NET, mais je pensais que leur robustesse relevait un peu du hasard
    Cet article montre pourtant un effort systématique pour améliorer la qualité (avec des diagrammes, et même des exemples d’usage des LLM)
    Même si ce type d’investissement devait diminuer à l’avenir, cela reste un excellent exemple de ce qu’il faut faire

  • Les personnes qui ont participé à ce projet ont dû vivre une expérience incroyable

  • L’article était bon, mais je pense que l’équipe .NET devrait abandonner Azure DevOps
    Le temps d’attente dans la file est le principal goulot d’étranglement. Il leur faut des serveurs de build bare metal

    • Azure DevOps n’est pas le problème en soi. Ça fonctionne aussi sur du bare metal
      Le matériel Mac se connecte et démarre rapidement
      De notre côté, nous lançons une VM propre pour chaque tâche afin de garantir conformité et stabilité
      Maintenir des machines chaudes prêtes à l’emploi éliminerait le temps d’attente, mais le coût serait trop élevé
      Comme il n’est pas réaliste de garder en permanence de multiples SKU en veille, nous faisons ce compromis
  • Je me demande pourquoi la Developer Division de Microsoft est de niveau mondial, alors que le reste de l’entreprise est devenu un symbole d’incompétence et de bureaucratie

    • Pour des raisons politiques et par suivisme vis-à-vis des leaders du secteur
      Depuis le départ de Bill, la culture d’introspection a disparu
  • Je pense que la racine du problème est une mentalité centrée sur l’abstraction qui cherche à simplifier des systèmes complexes
    Au lieu de vouloir tout résoudre au niveau supérieur, une approche qui construit depuis les couches basses peut éliminer bien plus de problèmes à la source

  • En voyant la phrase « nous construisons 3 à 4 versions majeures par mois et des dizaines de bandes SDK », je me suis demandé pourquoi il y avait autant de variantes

    • .NET 8 (LTS), .NET 9 (support standard) et .NET 10 (LTS) sont actuellement maintenus en parallèle
      Et pour chaque version, SDK/aspnet/runtime est compilé pour de nombreuses plateformes comme x64/arm32/arm64, Linux/macOS/Windows, etc.
  • Avant que Node ne devienne à la mode, .NET était une option solide pour les builds backend (avec de meilleures performances que Node)
    Après les récentes attaques sur la chaîne d’approvisionnement dans l’écosystème Node, j’espère que beaucoup de développeurs reviendront vers des plateformes stables

    • Je me demande ce que signifie « churn ». Cet article parle du système de build interne, donc je ne vois pas bien le lien avec l’instabilité
    • .NET reste excellent et s’améliore à chaque release
      Le grand changement, c’était la transition vers .NET Core, mais cela remonte déjà à presque dix ans
    • La combinaison C# + JetBrains Rider a été l’expérience de développement la plus satisfaisante de ma carrière
    • Depuis .NET Core 3, je n’ai presque pas rencontré de gros problèmes de compatibilité
      Les mises à jour du framework et des dépendances sont un peu pénibles, mais bien plus simples qu’une mise à jour de projet React
      Grâce au cycle LTS court, il n’est pas difficile de rester à jour. Dans des cycles de développement rapides, ce type de maintenance est normal
    • En tant que consultant multilingue, j’aimerais voir plus de RFP liés à .NET
      En réalité, on voit surtout du Node.js, du Java et du low-code (iPaaS)
      Cela dit, les problèmes de performances me donnent parfois l’occasion de proposer des add-ons C++