Delen via


Hoe Microsoft zich ontwikkelt met DevOps

Microsoft streeft ernaar om One Engineering System te gebruiken om alle Microsoft-producten te bouwen en implementeren met een solide DevOps-proces dat is gericht op een Git-vertakking en releasestroom. In dit artikel worden praktische implementaties beschreven, hoe het systeem wordt geschaald van kleine services tot enorme behoeften aan platformontwikkeling en lessen die zijn geleerd van het gebruik van het systeem in verschillende Microsoft-teams.

Het aannemen van een gestandaardiseerd ontwikkelingsproces is een ambitieuze onderneming. De vereisten van verschillende Microsoft-organisaties variëren sterk en de vereisten van verschillende teams binnen organisaties worden geschaald met grootte en complexiteit. Om aan deze uiteenlopende behoeften te voldoen, maakt Microsoft gebruik van een vertakkingsstrategie op basis van trunks om producten snel te ontwikkelen, ze regelmatig te implementeren en wijzigingen veilig in productie te brengen.

Microsoft maakt ook gebruik van platform engineeringprincipes als onderdeel van het One Engineering System.

Microsoft-releasedocumentatie

Elke organisatie moet zich vestigen op een standaard codereleaseproces om consistentie tussen teams te garanderen. De Microsoft-releasestroom bevat DevOps-processen van ontwikkeling tot release. De basisstappen van de releasestroom bestaan uit vertakking, push, pull-aanvraag en samenvoeging.

Branch

Een ontwikkelaar maakt een nieuwe vertakking van de hoofdintegratievertakking om een fout op te lossen of een functie te implementeren. Het lichtgewicht vertakkingsmodel van Git maakt deze korte topic-branches voor elke codebijdrage. Ontwikkelaars voeren vroeg door en voorkomen langlopende functievertakkingen met behulp van functievlagmen.

Duw

Wanneer de ontwikkelaar klaar is om wijzigingen in de rest van het team te integreren en door te voeren, pushen ze hun lokale branch naar een branch op de server en openen ze een pull request. Opslagplaatsen met honderden ontwikkelaars die in veel vertakkingen werken, gebruiken een naamconventie voor serververtakkingen om verwarring en vertakkingsproliferatie te verlichten. Ontwikkelaars maken meestal vertakkingen met de naam users/<username>/feature, waarbij <username> hun accountnaam is.

Pull-verzoek

Pull-verzoeken controleren de samenvoeging van topic branches in de hoofdbranch en zorgen ervoor dat aan het vertakkingsbeleid wordt voldaan. Het pull-aanvraagproces bouwt de voorgestelde wijzigingen op en voert een snelle testpas uit. De eerste en tweede testsuites voeren in minder dan vijf minuten ongeveer 60.000 tests uit. Dit is niet de volledige Microsoft-testmatrix, maar is voldoende om snel vertrouwen te geven in pull-aanvragen.

Vervolgens controleren andere leden van het team de code en keuren ze de wijzigingen goed. Codebeoordeling haalt op waar de geautomatiseerde tests zijn gebleven en is met name handig voor het opsporen van problemen met de architectuur. Handmatige codebeoordelingen zorgen ervoor dat andere technici in het team inzicht hebben in de wijzigingen en dat de codekwaliteit hoog blijft.

Merge

Zodra de pull-aanvraag voldoet aan alle buildbeleidsregels en revisoren die zijn afgemeld, wordt de onderwerpbranch samengevoegd in de hoofdintegratiebranch en is de pull-aanvraag voltooid.

Na het samenvoegen worden andere acceptatietests uitgevoerd die meer tijd in beslag nemen. Deze traditionele tests na controle voeren een grondigere validatie uit. Dit testproces biedt een goede balans tussen het hebben van snelle tests tijdens het beoordelen van pull-aanvragen en het hebben van een volledige testdekking vóór de release.

Verschillen met GitHub Flow

GitHub Flow is een populaire trunk-gebaseerde releasestroom voor organisaties om een schaalbare benadering van Git te implementeren. Sommige organisaties vinden echter dat ze naarmate hun behoeften toenemen, ze moeten afwijken van delen van de GitHub Flow.

Een vaak over het hoofd gezien deel van GitHub Flow is bijvoorbeeld dat pull-aanvragen moeten worden geïmplementeerd in productie voor testen voordat ze kunnen samenvoegen met de hoofdbranch. Dit proces betekent dat alle pull-aanvragen wachten in de implementatiewachtrij voor samenvoeging.

Sommige teams hebben honderden ontwikkelaars die voortdurend in één opslagplaats werken, die meer dan 200 pull-aanvragen naar de hoofdbranch per dag kunnen uitvoeren. Als voor elke pull-aanvraag een implementatie naar meerdere Azure-datacenters over de hele wereld nodig is om te testen, besteden ontwikkelaars tijd aan het wachten tot vertakkingen worden samengevoegd in plaats van software te schrijven.

In plaats daarvan blijven Microsoft-teams ontwikkelen in de hoofdbranch en implementaties in batches in getimede releases, meestal afgestemd op een sprintcyclus van drie weken.

Implementatiedetails

Hier volgen enkele belangrijke implementatiedetails van de Microsoft-releasestroom:

Strategie voor Git-opslagplaats

Verschillende teams hebben verschillende strategieën voor het beheren van hun Git-opslagplaatsen. Sommige teams behouden het merendeel van hun code in één Git-opslagplaats. Code wordt onderverdeeld in onderdelen, elk in een eigen map op hoofdniveau. Grote onderdelen, met name oudere onderdelen, kunnen meerdere subonderdelen hebben die afzonderlijke submappen hebben binnen het bovenliggende onderdeel.

Schermopname van een Structuur van een Git-opslagplaats.

Bijgevoegde opslagplaatsen

Sommige teams beheren ook adjunct-opslagplaatsen. Bijvoorbeeld, build- en release-agents en -taken, de VS Code-extensie en opensourceprojecten worden ontwikkeld op GitHub. Configuratiewijzigingen worden ingecheckt in een afzonderlijke opslagplaats. Andere pakketten waarvoor het team afhankelijk is, zijn afkomstig van andere locaties en worden gebruikt via NuGet.

Mono-repo of meerdere repos

Hoewel sommige teams ervoor kiezen om één monolithische opslagplaats te hebben, gebruiken de mono-opslagplaats, andere Microsoft-producten een benadering met meerdere opslagplaatsen . Skype heeft bijvoorbeeld honderden kleine opslagplaatsen die samenvoegen in verschillende combinaties om veel verschillende clients, services en hulpprogramma's te maken. Vooral voor teams die microservices omarmen, kan multi-repo de juiste aanpak zijn. Normaal gesproken ervaren oudere softwarepakketten die als monolithen zijn begonnen een mono-opslagplaatsbenadering als de gemakkelijkste manier om naar Git over te stappen, en hun codeorganisatie weerspiegelt dat.

Release-vertakkingen

De releaseflow van Microsoft zorgt ervoor dat de main branch te allen tijde bouwbaar is. Ontwikkelaars werken in tijdelijke onderwerpvertakkingen die worden samengevoegd met main. Wanneer een team klaar is om te verzenden, of het nu aan het einde van een sprint of voor een grote update is, starten ze een nieuwe releasebranch van de hoofdbranch. Release-vertakkingen worden nooit opnieuw samengevoegd naar de hoofdvertakking, zodat ze mogelijk belangrijke wijzigingen voor het kiezen van kersen vereisen.

In het volgende diagram ziet u kortstondige branches in blauw en release-branches in zwart. Eén vertakking met een commit die moet worden gecherry-picked, verschijnt in het rood.

Diagram met de structuur van de Git-releasebranch.

Vertakkingsbeleid en -machtigingen

Met Git-vertakkingsbeleid kunt u de structuur van de releasebranch afdwingen en de hoofdvertakking schoon houden. Branch policy kan bijvoorbeeld directe pushes naar de hoofdbranch voorkomen.

Om de vertakkingshiërarchie overzichtelijk te houden, gebruiken teams machtigingen om het maken van vertakkingen op het hoofdniveau van de hiërarchie te blokkeren. In het volgende voorbeeld kan iedereen vertakkingen maken in mappen zoals gebruikers/, functies/en teams/. Alleen releasebeheerders zijn gemachtigd om vertakkingen te maken onder releases/, en sommige automatiseringsprogramma's hebben machtigingen voor de integraties/ map.

Schermopname van vertakkingen.

Werkstroom voor Git-opslagplaats

Binnen de opslagplaats en vertakkingsstructuur doen ontwikkelaars hun dagelijkse werk. Werkomgevingen variëren sterk per team en per persoon. Sommige ontwikkelaars geven de voorkeur aan de opdrachtregel, andere zoals Visual Studio en anderen werken op verschillende platforms. De structuren en beleidsregels in Microsoft-opslagplaatsen zorgen voor een solide en consistente basis.

Een typische werkstroom omvat de volgende algemene taken:

Een nieuwe functie bouwen

Het bouwen van een nieuwe functie is de kern van de taak van een softwareontwikkelaar. Niet-Git-onderdelen van het proces omvatten het bekijken van telemetriegegevens, het bedenken van een ontwerp en een specificatie en het schrijven van de werkelijke code. Vervolgens begint de ontwikkelaar met de opslagplaats te werken door te synchroniseren met de meest recente commit op main. De hoofdbranch is altijd bouwbaar, dus het is gegarandeerd een goed uitgangspunt. De ontwikkelaar controleert een nieuwe functiebranch, brengt codewijzigingen aan, doorvoert, pusht naar de server en start een nieuwe pull-aanvraag.

Gebruik vertakkingsbeleid en verificaties

Bij het maken van een pull request controleren geautomatiseerde systemen of de nieuwe code juist wordt opgebouwd, niets stukmaakt en de beveiligings- of nalevingsregels niet schendt. Met dit proces wordt niet voorkomen dat andere werkzaamheden parallel worden uitgevoerd.

Vertakkingsbeleid en controles kunnen een geslaagde build vereisen, inclusief geslaagde tests, goedkeuring door de eigenaren van aangepaste code en verschillende externe controles om na te gaan of aan bedrijfsbeleid wordt voldaan voordat een pull-aanvraag kan worden voltooid.

Schermopname van de controles op een pull-aanvraag.

Integreren met Microsoft Teams

Veel teams configureren integratie met Microsoft Teams, waarmee de nieuwe pull-aanvraag wordt aangekondigd aan de teamleden van de ontwikkelaars. De eigenaren van code die wordt bewerkt, worden automatisch toegevoegd als reviewers. Microsoft-teams gebruiken vaak optionele revisoren voor code die veel mensen aanraken, zoals het genereren van REST-clients en gedeelde besturingselementen, om deskundige blik te krijgen op deze wijzigingen.

Schermopname die de integratie met Teams weergeeft.

Schermopname van Teams-melding van een pull-verzoek.

Implementeren met functievlagmen

Zodra de revisoren, code-eigenaren en automatisering tevreden zijn, kan de ontwikkelaar de pull-aanvraag voltooien. Als er een samenvoegingsconflict is, ontvangt de ontwikkelaar instructies voor het synchroniseren met het conflict, het oplossen ervan en het opnieuw pushen van de wijzigingen. De automatisering wordt opnieuw uitgevoerd op de vaste code, maar mensen hoeven zich niet opnieuw af te melden.

De vertakking wordt samengevoegd in main, en de nieuwe code wordt geïmplementeerd in de volgende sprint of grote release. Dat betekent niet dat de nieuwe functie meteen wordt weergegeven. Microsoft ontkoppelt de implementatie en blootstelling van nieuwe functies met behulp van feature flags.

Zelfs als de functie iets meer werk nodig heeft voordat deze klaar is om te demonstreren, is het veilig om naar main te gaan als het product succesvol wordt gebouwd en geïmplementeerd. Eenmaal in main, wordt de code onderdeel van een officiële build, waar deze opnieuw wordt getest, bevestigd om te voldoen aan het beleid en digitaal ondertekend.

Naar links schuiven om problemen vroeg te detecteren

Deze Git-werkstroom biedt verschillende voordelen. Ten eerste elimineert het uitwerken van één hoofdbranch vrijwel de samenvoegschuld. Ten tweede biedt de pull-aanvraagstroom een veelvoorkomend punt voor het afdwingen van testen, codebeoordeling en foutdetectie vroeg in de pijplijn. Deze shift left strategie helpt de feedbackcyclus te verkorten naar ontwikkelaars, omdat het fouten in minuten, niet uren of dagen kan detecteren. Deze strategie geeft ook vertrouwen voor herstructurering, omdat alle wijzigingen voortdurend worden getest.

Op dit moment kan een product met 200+ pull-aanvragen 300+ continue integratie-builds per dag genereren, wat neerkomt op 500+ testuitvoeringen elke 24 uur. Dit testniveau zou onmogelijk zijn zonder de trunk-based branching en releaseworkflow.

Release bij sprint mijlpalen

Aan het einde van elke sprint maakt het team een releasebranch van de hoofdbranch. Aan het einde van sprint 129 maakt het team bijvoorbeeld een nieuwe releasebranch releases/M129. Vervolgens brengt het team de sprint 129-branch in productie.

Na de aftakking van de release branch blijft de main branch geopend voor ontwikkelaars om wijzigingen te integreren. Deze wijzigingen worden drie weken later geïmplementeerd in de volgende sprintimplementatie.

Afbeelding van de releasebranch op sprint 129.

Hotfixes vrijgeven

Soms moeten wijzigingen snel naar productie gaan. Microsoft voegt meestal geen nieuwe functies toe in het midden van een sprint, maar wil soms snel een bugoplossing inbrengen om gebruikers te deblokkeren. Problemen kunnen klein zijn, zoals typefouten of groot genoeg om een beschikbaarheidsprobleem of livesite-incident te veroorzaken.

Het oplossen van deze problemen begint met de normale werkstroom. Een ontwikkelaar maakt een vertakking van main, haalt deze code op en voltooit de pull-aanvraag om deze samen te voegen. Het proces begint altijd door eerst de wijziging aan main te brengen. Hierdoor kunt u de oplossing snel en lokaal valideren zonder over te schakelen naar de releasebranch.

Als u dit proces volgt, garandeert u ook dat de wijziging in main terechtkomt, wat essentieel is. Het oplossen van een fout in de releasevertakking zonder dat de wijziging wordt teruggezet naar main, betekent dat de fout opnieuw optreedt tijdens de volgende implementatie, wanneer de sprint 130-release zich vertakt vanaf main. Het is gemakkelijk om te vergeten bij te werken main tijdens de verwarring en stress die zich tijdens een storing kan voordoen. Eerst wijzigingen aanbrengen in main betekent dat u altijd de wijzigingen in zowel de hoofdbranch als de releasebranch moet hebben.

Git-functionaliteit maakt deze werkstroom mogelijk. Zodra een ontwikkelaar een pull-aanvraag samenvoegt in main, kan hij/zij de pull-aanvraagpagina gebruiken om wijzigingen te cherry-picken naar de releasevertakking en deze direct in productie te brengen. Met dit proces wordt een nieuwe pull request aangemaakt die de releasevertakking als doel heeft, waarbij de zojuist samengevoegde inhoud naar main wordt overgezet.

Afbeelding van het kiezen van een hotfix in vertakking 129.

Het gebruik van de cherry-pickfunctionaliteit opent snel een pull-aanvraag en biedt de traceerbaarheid en betrouwbaarheid van branch-beleid. Cherry-picking kan op de server plaatsvinden, zonder dat u de release-branch naar een lokale computer hoeft te downloaden. Wijzigingen aanbrengen, samenvoegingsconflicten oplossen of kleine wijzigingen aanbrengen vanwege verschillen tussen de twee vertakkingen, kunnen allemaal op de server plaatsvinden. Teams kunnen wijzigingen rechtstreeks bewerken vanuit de teksteditor in de browser of via de Pull Request Merge Conflict Extension voor een meer geavanceerde ervaring.

Zodra een pull-aanvraag is gericht op de releasebranch, controleert de teamcode deze opnieuw, evalueert het vertakkingsbeleid, test de pull-aanvraag en voegt deze samen. Na het samenvoegen wordt de oplossing in enkele minuten geïmplementeerd op de eerste ring van servers. Van daaruit implementeert het team de oplossing geleidelijk aan meer accounts met behulp van implementatieringen. Naarmate de wijzigingen voor meer gebruikers worden geïmplementeerd, controleert het team of de wijziging de fout oplost terwijl er geen tekortkomingen of vertragingen optreden. De oplossing wordt uiteindelijk geïmplementeerd in alle Azure-datacenters.

Naar de volgende sprint gaan

In de komende drie weken is het team klaar met het toevoegen van functies aan sprint 130 en krijgt het de tijd om deze wijzigingen te implementeren. Ze maken de nieuwe releasebranch, releases/M130 van main, en rollen die branch uit.

Op dit moment zijn er eigenlijk twee branches in productie. Met een ring-gebaseerde implementatie om wijzigingen veilig naar productie te brengen, krijgt de snelle ring de wijzigingen van sprint 130, en blijven de langzame ringservers op sprint 129 terwijl de nieuwe wijzigingen in productie worden gevalideerd.

Voor het oplossen van een wijziging in het midden van een implementatie zijn mogelijk hotfixes vereist voor twee verschillende releases, de sprint 129-release en de sprint 130-release. Het team voert en implementeert de hotfix naar beide release branches. De 130-vertakking wordt opnieuw geïmplementeerd met de hotfix voor de ringen die al zijn bijgewerkt. De 129-branch herimplementeert met de hotfix naar de buitenringen die nog niet zijn bijgewerkt naar de versie van de volgende sprint.

Zodra alle ringen zijn geïmplementeerd, wordt de oude sprint 129-vertakking opgegeven, omdat eventuele wijzigingen die als hotfix in de sprint 129-vertakking zijn aangebracht, ook in main zijn doorgevoerd. Deze wijzigingen worden dus ook in de releases/M130 tak weergegeven.

Afbeelding van een release-branch op sprint 130.

Samenvatting

Het releasestroommodel vormt het hart van de ontwikkeling van Microsoft met DevOps om onlineservices te leveren. Dit model maakt gebruik van een eenvoudige, trunk-gebaseerde vertakkingsstrategie. Maar in plaats van ontwikkelaars vast te houden in een implementatiewachtrij, wachtend om hun wijzigingen samen te voegen, kunnen ontwikkelaars met de Microsoft-releasestroom blijven werken.

Met dit releasemodel kunnen ook nieuwe functies in Azure-datacenters regelmatig worden geïmplementeerd, ondanks de grootte van de Microsoft-codebases en het aantal ontwikkelaars dat erin werkt. Het model maakt het ook mogelijk om snel en efficiënt hotfixes in productie te brengen.