Jak firma Microsoft rozwija się za pomocą metodyki DevOps

Firma Microsoft stara się używać systemu inżynieryjnego One Do tworzenia i wdrażania wszystkich produktów firmy Microsoft z solidnym procesem DevOps skoncentrowanym na rozgałęzieniu i przepływie wydania git. W tym artykule opisano praktyczną implementację, sposób skalowania systemu z małych usług do ogromnych potrzeb związanych z programowaniem platformy oraz wnioski wyciągnięte z korzystania z systemu w różnych zespołach firmy Microsoft.

Przyjęcie ustandaryzowanego procesu rozwoju jest ambitnym przedsięwzięciem. Wymagania różnych organizacji firmy Microsoft różnią się znacznie, a wymagania różnych zespołów w ramach organizacji są skalowane z rozmiarem i złożonością. Aby sprostać tym zróżnicowanym potrzebom, firma Microsoft używa strategii rozgałęziania opartej na magistrali, aby ułatwić szybkie opracowywanie produktów, regularne wdrażanie ich i bezpieczne dostarczanie zmian w środowisku produkcyjnym.

Firma Microsoft używa również zasad inżynierii platformy w ramach swojego systemu inżynieryjnego One Engineering.

Przepływ wydania firmy Microsoft

Każda organizacja powinna uregulować standardowy proces wydawania kodu, aby zapewnić spójność między zespołami. Przepływ wydania firmy Microsoft obejmuje procesy DevOps od programowania do wydania. Podstawowe kroki przepływu wydania składają się z gałęzi, wypychania, żądania ściągnięcia i scalania.

Oddział

Aby naprawić usterkę lub zaimplementować funkcję, deweloper tworzy nową gałąź poza główną gałęzią integracji. Uproszczony model rozgałęziania git tworzy te krótkotrwałe gałęzie tematów dla każdego współtworzenia kodu. Deweloperzy zatwierdzają wcześnie i unikaj długotrwałych gałęzi funkcji przy użyciu flag funkcji.

Wypychanie

Gdy deweloper jest gotowy do integracji i wysłania zmian do reszty zespołu, wypchnie swoją gałąź lokalną do gałęzi na serwerze i otworzy żądanie ściągnięcia. Repozytoria z kilkuset deweloperami pracującymi w wielu gałęziach używają konwencji nazewnictwa dla gałęzi serwerów, aby złagodzić zamieszanie i rozprzestrzenianie gałęzi. Deweloperzy zwykle tworzą gałęzie o nazwie users/<username>/feature, gdzie <username> to ich nazwa konta.

Żądanie ściągnięcia

Gałąź tematu sterowania żądaniami ściągnięcia scala się z gałęzią główną i upewnij się, że zasady gałęzi są spełnione. Proces żądania ściągnięcia kompiluje proponowane zmiany i uruchamia szybki test. Zestawy testów pierwszego i drugiego poziomu uruchamiają około 60 000 testów w mniej niż pięć minut. Nie jest to kompletna macierz testowa firmy Microsoft, ale wystarczy szybko dać pewność żądań ściągnięcia.

Następnie inni członkowie zespołu przejrzyją kod i zatwierdź zmiany. Przegląd kodu wybiera miejsce, w którym przerwano testy automatyczne i jest szczególnie przydatne w przypadku problemów z architekturą. Ręczne przeglądy kodu zapewniają, że inni inżynierowie w zespole mają wgląd w zmiany i że jakość kodu pozostaje wysoka.

Scal

Gdy żądanie ściągnięcia spełnia wszystkie zasady kompilacji i recenzentów zostało podpisane, gałąź tematu scala się z główną gałęzią integracji, a żądanie ściągnięcia zostanie ukończone.

Po scaleniu inne testy akceptacyjnych są uruchamiane, co zajmuje więcej czasu. Te tradycyjne testy po sprawdzeniu przeprowadzają dokładniejszą walidację. Ten proces testowania zapewnia dobrą równowagę między szybkimi testami podczas przeglądu żądania ściągnięcia a pełnym pokryciem testu przed wydaniem.

Różnice w usłudze GitHub Flow

Usługa GitHub Flow to popularny przepływ wydania deweloperskiego oparty na magistrali, który umożliwia organizacjom zaimplementowanie skalowalnego podejścia do usługi Git. Jednak niektóre organizacje uważają, że wraz ze wzrostem ich potrzeb muszą one odbiegać od części usługi GitHub Flow.

Na przykład często pomijana część usługi GitHub Flow polega na tym, że żądania ściągnięcia muszą zostać wdrożone w środowisku produkcyjnym na potrzeby testowania, zanim będą mogły zostać scalone z gałęzią główną. Ten proces oznacza, że wszystkie żądania ściągnięcia oczekują w kolejce wdrażania w celu scalenia.

Niektóre zespoły mają kilkaset deweloperów pracujących stale w jednym repozytorium, które może ukończyć ponad 200 żądań ściągnięcia do głównej gałęzi dziennie. Jeśli każde żądanie ściągnięcia wymaga wdrożenia w wielu centrach danych platformy Azure na całym świecie do testowania, deweloperzy spędzają czas na oczekiwaniu na scalenie gałęzi, zamiast pisać oprogramowanie.

Zamiast tego zespoły firmy Microsoft kontynuują opracowywanie w gałęzi głównej i wsadowe wdrożenia do wersji z czasem, zwykle zgodne z trzytygodniowym cyklem przebiegu .

Szczegóły implementacji

Poniżej przedstawiono niektóre kluczowe szczegóły implementacji przepływu wydania firmy Microsoft:

Strategia repozytorium Git

Różne zespoły mają różne strategie zarządzania repozytoriami Git. Niektóre zespoły przechowują większość kodu w jednym repozytorium Git. Kod jest podzielony na składniki, z których każdy znajduje się we własnym folderze na poziomie głównym. Duże składniki, zwłaszcza starsze składniki, mogą mieć wiele podskładników, które mają oddzielne podfoldery w składniku nadrzędnym.

Screenshot showing a Git repository structure.

Repozytoria adjunct

Niektóre zespoły zarządzają również repozytoriami adjunct. Na przykład kompilowanie i wydawanie agentów i zadań, rozszerzenie programu VS Code i projekty typu open source są opracowywane w usłudze GitHub. Zmiany konfiguracji są ewidencjonowane w osobnym repozytorium. Inne pakiety, od których zależy zespół, pochodzą z innych miejsc i są używane za pośrednictwem narzędzia NuGet.

Repozytorium Mono lub repozytorium z wieloma repozytoriami

Podczas gdy niektóre zespoły wybierają jedno monolityczne repozytorium, repozytorium monolityczne, inne produkty firmy Microsoft używają podejścia obejmującego wiele repozytoriów . Skype, na przykład, ma setki małych repozytoriów, które łączą się w różnych kombinacjach w celu utworzenia wielu różnych klientów, usług i narzędzi. Szczególnie w przypadku zespołów, które obejmują mikrousługi, multi-repo może być właściwym podejściem. Zazwyczaj starsze produkty, które rozpoczęły się jako monolityczne, uważają, że podejście mono-repozytorium jest najłatwiejszym przejściem do usługi Git, a ich organizacja kodu to odzwierciedla.

Gałęzie wydania

Przepływ wydania firmy Microsoft zapewnia możliwość kompilowania głównej gałęzi przez cały czas. Deweloperzy pracują w krótkich gałęziach tematów, które scalają się z main. Gdy zespół jest gotowy do wysłania, niezależnie od tego, czy na końcu przebiegu, czy na potrzeby aktualizacji głównej, uruchamiają nową gałąź wydania poza gałąź główną. Gałęzie wydania nigdy nie scalają z powrotem do gałęzi głównej, więc mogą wymagać wybierania ważnych zmian.

Na poniższym diagramie przedstawiono krótkotrwałe gałęzie w kolorze niebieskim i odgałęzienia w kolorze czarnym. Jedna gałąź z zatwierdzeniem, które wymaga wyboru wiśni, pojawia się na czerwono.

Diagram showing Git release branch structure.

Zasady i uprawnienia gałęzi

Zasady gałęzi Git pomagają wymusić strukturę gałęzi wydania i zachować czystą gałąź główną. Na przykład zasady gałęzi mogą uniemożliwiać bezpośrednie wypychanie do gałęzi głównej.

Aby zachować porządek hierarchii gałęzi, zespoły używają uprawnień do blokowania tworzenia gałęzi na poziomie głównym hierarchii. W poniższym przykładzie każdy może tworzyć gałęzie w folderach, takich jak użytkownicy/, funkcje/i zespoły/. Tylko menedżerowie wersji mają uprawnienia do tworzenia gałęzi w wersjach /, a niektóre narzędzia automatyzacji mają uprawnienia do integracji/ folderu.

Screenshot that shows branches.

Przepływ pracy repozytorium Git

W strukturze repozytorium i gałęzi deweloperzy wykonują swoją codzienną pracę. Środowiska robocze różnią się w dużym stopniu w zależności od zespołu i poszczególnych osób. Niektórzy deweloperzy wolą wiersz polecenia, inni, tacy jak Visual Studio, a inni pracują na różnych platformach. Struktury i zasady wprowadzone w repozytoriach firmy Microsoft zapewniają solidną i spójną podstawę.

Typowy przepływ pracy obejmuje następujące typowe zadania:

Tworzenie nowej funkcji

Tworzenie nowej funkcji jest podstawą zadania dewelopera oprogramowania. Części procesu inne niż Git obejmują przeglądanie danych telemetrycznych, tworzenie projektu i specyfikacji oraz pisanie rzeczywistego kodu. Następnie deweloper rozpoczyna pracę z repozytorium, synchronizując się z najnowszym zatwierdzeniem w witrynie main. Gałąź główna jest zawsze kompilowalna, więc gwarantuje to dobry punkt wyjścia. Deweloper wyewidencjonuje nową gałąź funkcji, wprowadza zmiany kodu, zatwierdza, wypycha na serwer i uruchamia nowe żądanie ściągnięcia.

Korzystanie z zasad gałęzi i kontroli

Po utworzeniu żądania ściągnięcia zautomatyzowane systemy sprawdzają, czy nowe kompilacje kodu nie przerywają żadnych działań i nie naruszają żadnych zasad zabezpieczeń ani zgodności. Ten proces nie blokuje równoległego wykonywania innych zadań.

Zasady gałęzi i kontrole mogą wymagać pomyślnej kompilacji , w tym zakończonych pomyślnie testów, wylogowania się przez właścicieli dowolnego kodu, a także kilku kontroli zewnętrznych w celu zweryfikowania zasad firmowych przed ukończeniem żądania ściągnięcia.

Screenshot showing the checks on a pull request.

Integracja z aplikacją Microsoft Teams

Wiele zespołów konfiguruje integrację z usługą Microsoft Teams, która ogłasza nowe żądanie ściągnięcia współpracownikom deweloperów. Właściciele każdego dotknięcia kodu są automatycznie dodawani jako recenzenci. Zespoły firmy Microsoft często używają opcjonalnych recenzentów w kodzie, którego wiele osób dotyka, takich jak generowanie klientów REST i współużytkowane kontrolki, aby uzyskać specjalistyczne oczy na te zmiany.

Screenshot showing Teams integration.

Screenshot showing Teams notification of a pull request.

Wdrażanie za pomocą flag funkcji

Gdy recenzenci, właściciele kodu i automatyzacja będą zadowoleni, deweloper może ukończyć żądanie ściągnięcia. Jeśli występuje konflikt scalania, deweloper otrzymuje instrukcje dotyczące synchronizowania z konfliktem, naprawiania go i ponownego wypychania zmian. Automatyzacja jest uruchamiana ponownie w stałym kodzie, ale ludzie nie muszą ponownie się wylogować.

Gałąź scala się z mainelementem , a nowy kod jest wdrażany w następnym przebiegu lub wersji głównej. Nie oznacza to, że nowa funkcja pojawi się od razu. Firma Microsoft rozdziela wdrażanie i ujawnienie nowych funkcji przy użyciu flag funkcji.

Nawet jeśli funkcja wymaga nieco więcej pracy, zanim będzie gotowa do pokazania, można bezpiecznie przejść do main sytuacji, w której produkt kompiluje i wdraża. Po przejściu do mainprogramu kod staje się częścią oficjalnej kompilacji, gdzie jest ponownie testowany, potwierdzony pod kątem spełnienia zasad i podpisany cyfrowo.

Przesunięcie w lewo w celu wczesnego wykrywania problemów

Ten przepływ pracy usługi Git zapewnia kilka korzyści. Po pierwsze, praca z jedną gałęzią główną praktycznie eliminuje dług scalania. Po drugie przepływ żądania ściągnięcia zapewnia wspólny punkt wymuszania testowania, przeglądu kodu i wykrywania błędów na wczesnym etapie potoku. Ta strategia zmiany w lewo pomaga skrócić cykl opinii do deweloperów, ponieważ może wykrywać błędy w minutach, a nie godzinach lub dniach. Ta strategia zapewnia również pewność refaktoryzacji, ponieważ wszystkie zmiany są stale testowane.

Obecnie produkt z ponad 200 żądaniami ściągnięcia może generować 300+ kompilacji ciągłej integracji dziennie, co stanowi 500+ przebiegów testów co 24 godziny. Ten poziom testowania byłby niemożliwy bez przepływu pracy rozgałęziania opartego na magistrali i wydania.

Wydawanie w punktach kontrolnych przebiegu

Na końcu każdego przebiegu zespół tworzy gałąź wydania z gałęzi głównej. Na przykład na końcu przebiegu 129 zespół tworzy nową gałąź releases/M129wydania . Następnie zespół umieszcza gałąź sprintu 129 w środowisku produkcyjnym.

Po gałęzi gałęzi wydania główna gałąź pozostaje otwarta dla deweloperów w celu scalenia zmian. Te zmiany zostaną wdrożone trzy tygodnie później we wdrożeniu następnego przebiegu.

Illustration of the release branch at sprint 129.

Wydania poprawek

Czasami zmiany muszą szybko przejść do środowiska produkcyjnego. Firma Microsoft zwykle nie dodaje nowych funkcji w trakcie przebiegu, ale czasami chce szybko wprowadzić poprawkę usterek, aby odblokować użytkowników. Problemy mogą być niewielkie, takie jak literówki lub wystarczająco duże, aby spowodować problem z dostępnością lub zdarzenie witryny na żywo.

Rozwiązywanie tych problemów rozpoczyna się od normalnego przepływu pracy. Deweloper tworzy gałąź na podstawie mainmetody , pobiera kod do przeglądu i kończy żądanie ściągnięcia, aby je scalić. Proces zawsze rozpoczyna się od wprowadzenia zmiany w main pierwszej kolejności. Umożliwia to szybkie tworzenie poprawki i weryfikowanie jej lokalnie bez konieczności przełączania się do gałęzi wydania.

Po wykonaniu tego procesu gwarantuje się również, że zmiana zostanie zmieniona na main, co jest krytyczne. Naprawienie usterki w gałęzi wydania bez powrotu main zmiany oznaczałoby, że usterka będzie powtarzać się podczas następnego wdrożenia, gdy przebieg 130 gałęzi wydania z programu main. Łatwo zapomnieć o aktualizacji main podczas zamieszania i stresu, które mogą wystąpić podczas awarii. Wprowadzenie zmian w pierwszej kolejności main oznacza, że zmiany są zawsze wprowadzane zarówno w gałęzi głównej, jak i w gałęzi wydania.

Funkcje usługi Git umożliwiają korzystanie z tego przepływu pracy. Aby natychmiast wprowadzić zmiany w środowisku produkcyjnym, gdy deweloper scali żądanie ściągnięcia z mainusługą , może użyć strony żądania ściągnięcia, aby wybrać zmiany w gałęzi wydania. Ten proces tworzy nowe żądanie ściągnięcia, które jest przeznaczone dla gałęzi wydania, co spowoduje przywrócenie zawartości, która właśnie została scalona z gałęzią main.

Illustration of cherry-picking a hotfix commit into branch 129.

Korzystanie z funkcji cherry-pick powoduje szybkie otwarcie żądania ściągnięcia, zapewniając możliwość śledzenia i niezawodność zasad gałęzi. Wybór wiśni może wystąpić na serwerze bez konieczności pobierania gałęzi wydania na komputer lokalny. Wprowadzanie zmian, naprawianie konfliktów scalania lub wprowadzanie drobnych zmian z powodu różnic między dwoma gałęziami może wystąpić na serwerze. Zespoły mogą edytować zmiany bezpośrednio z edytora tekstu opartego na przeglądarce lub za pośrednictwem rozszerzenia konfliktów scalania żądań ściągnięcia w celu uzyskania bardziej zaawansowanego środowiska.

Gdy żądanie ściągnięcia będzie dotyczyć gałęzi wydania, ponownie przejrzy kod zespołu, oceni zasady gałęzi, przetestuje żądanie ściągnięcia i scali go. Po scaleniu poprawka jest wdrażana w pierwszym pierścieniu serwerów w ciągu kilku minut. Z tego miejsca zespół stopniowo wdraża poprawkę na większej liczbie kont przy użyciu pierścieni wdrażania. W miarę wdrażania zmian dla większej liczby użytkowników zespół monitoruje powodzenie i sprawdza, czy zmiana naprawia usterkę, nie wprowadzając żadnych niedociągnięć ani spowolnień. Poprawka zostanie ostatecznie wdrożona we wszystkich centrach danych platformy Azure.

Przejdź do następnego przebiegu

W ciągu najbliższych trzech tygodni zespół kończy dodawanie funkcji do przebiegu 130 i przygotowuje się do wdrożenia tych zmian. Tworzą nową gałąź wydania z maingałęzi releases/M130 i wdrażają je.

W tym momencie istnieją faktycznie dwie gałęzie w środowisku produkcyjnym. Dzięki wdrożeniu opartemu na pierścieniu w celu bezpiecznego wprowadzenia zmian w środowisku produkcyjnym szybki pierścień pobiera zmiany przebiegu 130, a powolne serwery pierścieniowe pozostają w przebiegu 129, podczas gdy nowe zmiany są weryfikowane w środowisku produkcyjnym.

Poprawka zmiany w środku wdrożenia może wymagać poprawki dwóch różnych wersji, wersji przebiegu 129 i wersji przebiegu 130. Zespół portuje i wdraża poprawkę w obu gałęziach wydania. Gałąź 130 ponownie wdraża poprawkę do pierścieni, które zostały już uaktualnione. Gałąź 129 jest wdrażana ponownie z poprawką do pierścieni zewnętrznych, które nie zostały jeszcze uaktualnione do wersji następnego przebiegu.

Po wdrożeniu wszystkich pierścieni stara gałąź przebiegu 129 jest porzucona, ponieważ wszelkie zmiany wprowadzone do gałęzi sprint 129 zostały również wprowadzone w gałęzi .main W związku z tym te zmiany będą również znajdować się w releases/M130 gałęzi .

Illustration of a release branch at sprint 130.

Podsumowanie

Model przepływu wydania jest centrum tego, jak firma Microsoft opracowuje rozwiązania DevOps w celu dostarczania Usługi online. Ten model używa prostej, opartej na magistrali strategii rozgałęziania. Jednak zamiast utrzymywać, że deweloperzy utknęli w kolejce wdrażania, czekając na scalenie zmian, przepływ wydań firmy Microsoft umożliwia deweloperom pracę.

Ten model wydania umożliwia również wdrażanie nowych funkcji w centrach danych platformy Azure w regularnym tempie, pomimo rozmiaru baz kodu firmy Microsoft i liczby deweloperów pracujących w nich. Model umożliwia również szybkie i wydajne wprowadzanie poprawek do środowiska produkcyjnego.