1 Punkte von GN⁺ 2025-11-28 | 1 Kommentare | Auf WhatsApp teilen
  • Das .NET Unified Build-Projekt ist ein neues Build-System, das das gesamte Produkt in Form eines „Virtual Monolithic Repository“ (VMR) zusammenführt, um die Komplexität und Ineffizienz der bisherigen Build-Struktur auf Basis verteilter Repositories zu reduzieren
  • Die bisherige verteilte Produktstruktur bietet zwar hohe Unabhängigkeit und Flexibilität, verursacht aber erhebliche Belastungen bei Abhängigkeitsmanagement, Build-Konsistenz und Geschwindigkeit
  • Unified Build erweitert die Prinzipien von Source Build für Linux-Distributionen und führt ein einheitliches Source-Layout sowie eine „Vertical Build“-Struktur ein, um Build-Zeiten zu verkürzen und Vorhersehbarkeit zu schaffen
  • Durch bidirektionalen Code-Flow (two-way code flow), Szenario-Tests sowie Verbesserungen bei automatischer Validierung und Signatur-Infrastruktur werden sowohl die Effizienz der Entwickler als auch die Produktqualität gesteigert
  • Das mit .NET 10 offiziell eingeführte System hat konkrete Ergebnisse erzielt, darunter verkürzte Build-Zeiten (24 Stunden → unter 7 Stunden), geringere Wartungskosten und höhere Zuverlässigkeit bei der Auslieferung

Hintergrund des Wandels in der .NET-Build-Struktur

  • Im Zuge der Open-Source-Umstellung von .NET in den Jahren 2015–2016 wurde die Entwicklung auf zahlreiche Repositories wie CoreCLR, CoreFX, ASP.NET Core und SDK aufgeteilt
  • Jedes Repository wurde unabhängig gebaut und ausgeliefert, während das Gesamtprodukt über einen Abhängigkeitsgraphen zusammengesetzt wurde
  • Dieser Ansatz ähnelt dem OSS-Ökosystem, führt aber bei Sicherheits-Patches oder dringenden Fixes dazu, dass mehrere Teams gleichzeitig koordiniert werden müssen, wodurch der Zeitaufwand unvorhersehbar wird
  • Trotz der Vorteile verteilter Entwicklung (Layering, Aufspaltung der Community, asynchrone Entwicklung usw.) ist sie bei der Sicherstellung von Produktkohärenz ineffizient

Komplexität der Produktzusammensetzung und Overhead

  • Komplexität (Complexity): definiert als die Anzahl der Schritte, die nötig sind, bis eine Änderung beim Kunden ankommt
    • Je mehr Repositories und Abhängigkeitsknoten es gibt, desto mehr Zeit und personelle Abstimmung sind nötig, um Konsistenz sicherzustellen
  • Overhead: Zeit, die nicht direkt für die Erstellung von Ergebnissen aufgewendet wird, die an Kunden ausgeliefert werden können
    • Beispiele: Erstellen von PRs, Warten auf Genehmigungen, Queueing, Umgebungssetup
  • Die Analyse des Runtime-Builds von .NET 8 zeigte, dass rund 38,5 % der gesamten Build-Zeit auf Overhead entfielen
  • Wenn Komplexität und Overhead zusammenkommen, sinkt die Build-Effizienz stark, und der gesamte Release-Zyklus verlängert sich

Ursprung von Source Build und Unified Build

  • Source Build ist ein System, das dafür entwickelt wurde, dass Linux-Distributionen .NET offline aus einer einzigen Quelle bauen können
    • Prinzipien: eine Implementierung, eine Plattform, eine Build-Umgebung
    • Ein Build-Orchestrator verwaltet die Abhängigkeiten und die Build-Reihenfolge der einzelnen Komponenten
  • Source Build kann aufgrund geringer Komplexität und geringen Overheads in unter 50 Minuten gebaut werden
  • Microsoft wollte dieses Konzept auch auf interne Builds anwenden, stieß jedoch auf Schwierigkeiten durch Closed Source, Legacy-Abhängigkeiten und plattformübergreifende Joins
  • Um diese Probleme zu lösen, wurden Ansätze wie reference-only packages (source-build-reference-packages), das Prinzip einer einzigen Implementierung und die Eliminierung von Joins eingeführt

Ziele und Design von Unified Build

  • Das gesamte .NET-Produkt soll mit einem einzigen Commit gebaut werden können
  • Alle plattformspezifischen Distributionen sollen in einer einzigen Umgebung erzeugt werden
  • Unabhängiger Build und unabhängige Validierung sollen auch außerhalb von Microsoft möglich sein
  • Bidirektionaler Code-Flow sorgt für die automatische Synchronisierung von Änderungen zwischen VMR und einzelnen Repositories
  • Über Szenario-Tests wird die Funktionalität auf Ebene des Gesamtprodukts validiert
  • Die Vertical Build-Struktur parallelisiert plattformspezifische Builds
    • Sie besteht aus etwa 35–40 Build-Vertikalen (short/tall stack)

Umsetzungsphasen von Unified Build

  • .NET 7: Konzeption und Freigabe
  • .NET 8: Verbesserung der Source-Build-Infrastruktur und Aufbau der Grundlagen
  • .NET 9: Experimente mit Vertical Build und Code-Flow
  • .NET 10: Offizielle Produktivsetzung und Übernahme in RTM
    • In Preview 4 wurde der neue Build-Prozess eingeführt, ab Preview 5 erfolgte die vollständige Umstellung

Zentrale Komponenten

Virtual Monolithic Repository (VMR)

  • Das Repository dotnet/dotnet dient als einheitliches Source-Layout für alle Komponenten
  • Entwickler können entweder in einzelnen Repositories oder im VMR arbeiten und erhalten so die Flexibilität verteilter Entwicklung und die Konsistenz eines Monorepos zugleich

Vertical Build

  • Für jede Plattform und jede Runtime wird ein unabhängiger Build ausgeführt
  • Nach parallelen Builds werden die Ergebnisse zusammengeführt; einige Joins werden in zusätzlichen Build-Pässen verarbeitet

Code Flow

  • Bidirektionale Code-Synchronisierung: Komponenten-Repository → VMR, VMR → Komponenten-Repository
  • Der letzte Status des Code-Flows wird in eng/Version.Details.xml festgehalten
  • Änderungen werden als Patch-Dateien erzeugt, um automatisch PRs zu erstellen
  • Logik zur Behandlung von Konflikten und zur Fehlerbehebung ist integriert

Scenario Test Validation

  • Zusätzlich zu bestehenden Unit-Tests werden Szenario-Tests hinzugefügt, die die Gesamtfunktionalität des Produkts validieren
  • Sie laufen auf Basis der Build-Artefakte und stärken so Regressionsschutz und Qualitätssicherung

Ergebnisse und Auswirkungen

  • Verkürzte Build-Zeiten: mehr als 24 Stunden → unter 7 Stunden (einschließlich Signierung)
  • Höhere Flexibilität: kürzere Build- und Auslieferungszyklen, einfachere Umsetzung dringender Fixes
  • Mehr Vorhersehbarkeit: klarer Zeitpunkt, wann der Build nach einer Änderung abgeschlossen ist
  • Verbesserte Infrastruktur: Signierungs-Tools, Logs, parallele Builds, Automatisierung des Abhängigkeitsflusses usw.
  • Auch Source Build für Linux-Distributionen bleibt jederzeit in einem sauberen Zustand vor dem Build

Ausblick

  • Mit .NET 11 ist die Einführung von automatisiertem Code-Flow und AI-basierten Monitoring-Agenten geplant
    • Die Verfolgung von Fehlern im Prozess von PR bis zur Produktübernahme soll automatisiert werden
  • Langfristig soll durch die Beseitigung von Join-Punkten der Build weiter vereinfacht und beschleunigt werden
    • Ziel: vollständiger Build in unter 4 Stunden

Fazit

  • Das Unified Build, das die Grenzen des verteilten Build-Modells überwindet, verbessert die Effizienz von Build und Auslieferung bei .NET grundlegend
  • Es wurden konkrete Fortschritte in drei Bereichen erzielt: weniger Komplexität und Overhead, mehr Konsistenz, Geschwindigkeit und Qualität
  • Seit .NET 10 RTM wird dieses System vollständig eingesetzt und soll in künftigen Versionen kontinuierlich weiter verbessert werden

1 Kommentare

 
GN⁺ 2025-11-28
Hacker-News-Kommentare
  • Ich habe wirklich großen Respekt vor dem .NET-Team
    Sie veröffentlichen regelmäßig tiefgehende technische Artikel, und ihre Besessenheit von Performance-Optimierung ist beeindruckend (z. B. Kestrel, die Entwicklung von Entity Framework)
    ASP.NET ist eines der wenigen großen Projekte, das selbst einen Umbruch in der Größenordnung von Python 2→3 überlebt hat
    Früher war man für die Sitzungssynchronisierung auf magisch wirkende Funktionen angewiesen, heute funktioniert das auf eine völlig andere Weise
    Es fühlt sich gut an, dass ein 3-Billionen-Dollar-Unternehmen den von mir genutzten Stack ernsthaft verbessern will

    • Ich habe früher einmal Entity Framework verwendet, aber es war viel zu langsam
      Also habe ich es durch Dapper und ein selbst gebautes Migrationssystem ersetzt, und dadurch sank die Zeit für DB-Validierung und Seeding beim Start von 10 Sekunden auf unter 2 Sekunden (auf schwacher Hardware + mit SQLite)
      Die von Entity erzeugten Queries enthielten viele unnötige mehrfache Joins
      In letzter Zeit steige ich auf ein einfaches Go-Backend um und nutze .NET nur noch für andere Lösungen
      Frameworks wie WPF hatten so viele Probleme, dass man Win32-Hacks brauchte
      Zum Beispiel liefert erst .NET 9 endlich alle Netzwerkschnittstellen korrekt zurück. Frühere Runtimes zeigten nur aktive NICs an
      Es gibt immer noch Projekte, die Windows-7-Unterstützung beibehalten müssen
    • Ich denke, viele Projekte sind zurückgeblieben und konnten nicht auf .NET Core wechseln
      Selbst bei neuen Projekten muss man manchmal noch .NET 4.8 verwenden. Zum Beispiel tritt beim Erstellen von Excel-Formeln ein async/await-Deadlock-Problem auf
      Außerdem ist die Windows-Integration kaputt, sodass derselbe Netzwerkaufruf unter 4.8 authentifiziert wird, unter Core aber fehlschlägt
      Wegen des Zusammenbruchs der Abwärtskompatibilität in zahllosen Bibliotheken ist eine Migration nicht einfach
      Die Performance wurde besser, aber funktional wirkt .NET Framework wie ein Fossil
      Es hat 15 Jahre gedauert, bis ein JSON-Serializer in die Standardbibliothek aufgenommen wurde, und Unterstützung für moderne Bildformate wie webp oder heic gibt es ebenfalls nicht
      Visual Studio zeigt praktisch jeden Tag Absturzmeldungen an
      Früher war ich ein glühender .NET-Fan, aber ich vermisse Anders' Führung
  • In einem Side-Project habe ich vor Kurzem ein C#-REST-API-Backend in VSCode auf macOS entwickelt und deploye es nun seit drei Jahren unter Linux
    Ich nutze SQLite, EFCore und Minimal API, und es ist deutlich angenehmer als das Frontend (NextJS/React/MaterialUI, mehr als 50 npm-Pakete)

    • Wenn die API etwas komplexer wird, empfehle ich die FastEndpoints-Bibliothek
      Das ist persönlich mein Lieblings-API-Framework
      Die zweitbeste Wahl wäre für mich die Kombination aus TS + Hono + Zod-OpenApi + SwaggerUI, aber das Einrichten des Typkontexts ist etwas umständlich
  • Beeindruckend fand ich, dass die Grundlage für die Open-Source- und Cross-Platform-Ausrichtung von .NET das Build-System von Linux-Distributionen war

    • Um es als Autor des Artikels direkt zu erklären: Damit Distribution-Maintainer .NET in native Package-Feeds aufnehmen können, müssen sie es selbst bauen können
      Deshalb brauchten wir ein Build-System, das ihre Anforderungen erfüllt, und am Ende war die Integration in das Modell der Linux-Distributionen der einzige gangbare Weg
      Dieses Modell ist simpel, aber in der Performance schwächer. Ein verteiltes Build-System mit Caching wäre schneller, passt aber nicht zum Workflow der Maintainer
      Wir kamen zu dem Schluss, dass die Optimierung auf Einfachheit besser geeignet ist, um Beiträge aus der Community zu fördern
      Ziel ist es, dass die Community selbst Builds und Auslieferung für verschiedene Plattformen wie BSD, S390x usw. übernehmen kann
    • Ich denke, .NET ist längst an dem Punkt vorbei, an dem man den Wechsel zu Open Source noch bereuen könnte
      Die Menge an Pull Requests und positiven Ergebnissen der letzten zehn Jahre ist wirklich erstaunlich
  • Ich hätte nicht gedacht, dass der beeindruckendste Software-Engineering-Artikel dieses Jahres von Microsoft kommen würde
    Ich mag die neueren Versionen von .NET, hatte ihre Robustheit aber eher für ein Zufallsprodukt gehalten
    Dieser Artikel zeigt jedoch systematische Bemühungen zur Qualitätsverbesserung (einschließlich Diagrammen und Beispielen für den Einsatz von LLMs)
    Selbst wenn solche Investitionen künftig zurückgehen sollten, ist das ein gutes Beispiel dafür, „wie man es machen sollte“

  • Die Leute, die an diesem Projekt beteiligt waren, müssen wirklich eine großartige Erfahrung gemacht haben

  • Der Artikel war gut, aber ich finde, das .NET-Team sollte Azure DevOps aufgeben
    Wartezeiten in der Queue sind der größte Engpass. Sie sollten Bare-Metal-Build-Server betreiben

    • Azure DevOps selbst ist nicht das Problem. Es läuft auch auf Bare Metal
      Mac-Hardware wird schnell verbunden und gestartet
      Wir starten für jeden Job eine neue saubere VM, um Compliance und Stabilität sicherzustellen
      Man könnte vorbereitete Hot-Machines vorhalten, um Wartezeiten zu beseitigen, aber die Kosten wären zu hoch
      Da es praktisch kaum möglich ist, verschiedene SKUs ständig in Bereitschaft zu halten, gehen wir diesen Kompromiss ein
  • Ich frage mich, warum Microsofts Developer Division zur absoluten Spitze der Branche gehört, während der Rest des Unternehmens zum Symbol für Inkompetenz und Bürokratie geworden ist

    • Aus politischen Gründen und wegen des Hinterherlaufens hinter Branchenführern
      Seit Bill weg ist, gibt es keine Kultur der Selbstreflexion mehr
  • Ich denke, die abstraktionszentrierte Denkweise, die komplexe Systeme vereinfachen will, ist die Wurzel des Problems
    Statt alles auf höherer Ebene lösen zu wollen, kann ein Ansatz, der von den unteren Ebenen aus aufgebaut wird, viel mehr Probleme grundlegend beseitigen

  • Als ich den Satz las „Wir bauen pro Monat 3 bis 4 Major-Versionen und Dutzende SDK-Bänder“, fragte ich mich, warum es so viele Varianten gibt

    • Aktuell werden .NET 8 (LTS), .NET 9 (Standard Support) und .NET 10 (LTS) parallel gepflegt
      Außerdem werden für jede Version SDK/aspnet/runtime für verschiedene Plattformen wie x64/arm32/arm64 und Linux/macOS/Windows gebaut
  • Bevor Node populär wurde, war .NET eine solide Wahl für Backend-Builds (auch performanter als Node)
    Nach den jüngsten Supply-Chain-Angriffen im Node-Ökosystem hoffe ich, dass viele Entwickler wieder auf stabile Plattformen zurückkommen

    • Ich frage mich, was mit „churn“ gemeint ist. Dieser Artikel handelt doch vom internen Build-System; ich sehe nicht, was das mit Instabilität zu tun haben soll
    • .NET ist immer noch großartig und wird mit jedem Release besser
      Der große Umbruch war der Wechsel zu .NET Core, aber das ist fast zehn Jahre her
    • Die Kombination aus C# + JetBrains Rider war die zufriedenstellendste Entwicklungserfahrung meiner Karriere
    • Seit .NET Core 3 hatte ich kaum noch ernsthafte Kompatibilitätsprobleme
      Updates des Frameworks und der Abhängigkeiten sind etwas lästig, aber im Vergleich zu React-Projekt-Updates deutlich einfacher
      Dank des kurzen LTS-Zyklus ist es nicht schwer, auf dem neuesten Stand zu bleiben. In schnellen Entwicklungszyklen ist solche Wartung ganz normal
    • Als mehrsprachiger Berater hoffe ich auf mehr RFPs rund um .NET
      In der Realität dreht sich aber vieles um Node.js, Java und Low-Code (iPaaS)
      Trotzdem bietet sich dank Performance-Problemen gelegentlich die Chance, C++-Add-ons vorzuschlagen