Jak możemy śledzić, która wersja naszego kodu znajduje się w każdym środowisku?

14

Mój zespół obecnie stosuje dość prosty proces rozgałęziania / wdrażania, który wygląda następująco:

                ┌────────┐ ┌────┐ ┌──────┐
 Environments:  │  DEV   │ │ QA │ │ PROD │
                └────────┘ └────┘ └──────┘

                     ▲       ▲       ▲
                     │       │       │

                ┌────────┐ ┌────┐ ┌──────┐
 Builds:        │  DEV   │ │ QA │ │ PROD │
                └────────┘ └────┘ └──────┘

                     ▲       ▲       ▲
                     │       │       │

                ┌────────┐ ┌────┐ ┌──────┐
 Branches:      │ master │ │ qa │ │ prod │
                └────────┘ └────┘ └──────┘

Każde środowisko ma swoją gałąź (używamy git ) i własną kompilację, która korzysta z tej gałęzi. Kiedy chcemy awansować z jednego środowiska do drugiego, na przykład z DEV do QA, łączymy mastergałąź qai rozpoczynamy nową kompilację QA (która jest następnie automatycznie wdrażana w środowisku QA).

Zastanawiamy się nad przejściem na nowy proces, który wyeliminowałby tworzenie dedykowanego oddziału i kompilacji dla każdego środowiska. Zamiast tego kompilacja pojedynczego wydania stworzyłaby „pakiet wdrożeniowy”, który można by następnie wdrożyć w dowolnym środowisku. Wyobrażamy sobie, że typowy przepływ pracy wyglądałby mniej więcej tak:

                ┌────────┐     ┌────┐     ┌──────┐
 Environments:  │  DEV   │ ──► │ QA │ ──► │ PROD │
                └────────┘     └────┘     └──────┘

                      ▲ 
                       \ 

                        ┌───────────────┐
 Builds:                │ release build │
                        └───────────────┘

                                ▲
                                │

                ┌────────┐ ┌─────────┐
 Branches:      │ master │ │ release │
                └────────┘ └─────────┘

Promowanie z jednego środowiska do drugiego nie byłoby już obsługiwane w ramach kontroli źródła; raczej wzięlibyśmy już skompilowane pliki binarne („pakiet wdrożeniowy”) i upuściliśmy je w nowym środowisku.

Ten nowy system pozwoliłby nam wdrożyć dowolną kompilację w dowolnym środowisku, co ma kilka zalet. Na przykład testowanie poprawek błędów PROD w DEV i QA jest banalne. Nasz obecny system nie zapewnia łatwego sposobu na zrobienie tego bez wycofywania gałęzi, czego oczywiście chcielibyśmy uniknąć.

Największą wadą tego nowego systemu jest to, że nie mamy już automatycznego sposobu śledzenia kodu w jakim środowisku. Jeśli musimy wprowadzić poprawkę w PROD, nie mamy już dedykowanego oddziału zsynchronizowanego z obecną produkcyjną bazą kodu. To samo dotyczy kontroli jakości - jeśli chcemy wprowadzić szybką zmianę do kontroli jakości bez pogłębiania trwającej pracy master, nie mamy już gałęzi odzwierciedlającej bieżący stan środowiska kontroli jakości.

Jak możemy śledzić, jaki kod znajduje się w każdym środowisku?

Niektóre opcje, które rozważamy:

  • wykorzystanie tagów git do śledzenia, które zatwierdzenie znajduje się w danym środowisku
  • osadzanie zatwierdzenia git używanego przez kompilację w każdym pakiecie wdrażania
Nathan Friend
źródło
Czy masz system CI, taki jak Hudson lub Jenkins? Czy jest w stanie przesuwać tagi tego, co zbudował z powrotem do git? (Wiem, że istnieją wtyczki dla Hudsona i Jenkinsa, które mogą ... - nie tak pewni innych).
@MichaelT Używamy MSBuild do naszych kompilacji i Octopus Deploy do naszych wdrożeń. Jestem przekonany, że możemy zmusić Octopus do manipulowania naszym repozytorium git za pomocą niestandardowego skryptu wdrażania Powershell.
Nathan Friend,

Odpowiedzi:

14

Tagi Git są tym, czego naprawdę chcesz używać do oznaczania wydań. Powodem jest to, że mają one dla Ciebie znaczenie i mogą być użyte do szybkiego rozpoznania powiązania między kodem wdrożonym przez państwo a wszelkimi informacjami, które może mieć serwer kompilacji (takimi jak numer kompilacji).

Chociaż jest to odpowiedź, której szukasz, rozwiązuje ona tylko połowę problemu. Drugi to „hej, tutaj jest wdrożony .[wje]arna serwerze, z jakiej wersji pochodzi?” Wiemy, że nigdy nie będziesz mieć różnych wersji aplikacji wdrożonych na dev i qa lub prod. Dobrze?

Rozwiązaniem tej części pytania jest umieszczenie przez serwer kompilacji informacji w manifeście. Pochodzę z przykładu maven i svn, który mam przed sobą:

<manifestEntries>
    <Specification-Title>${project.name}</Specification-Title>
    <Specification-Version>${project.version}</Specification-Version>
    <Build-Number>${build.number}</Build-Number>
    <Build-Id>${build.id}</Build-Id>
    <Svn-Revison>${svn.revision}</Svn-Revison>
</manifestEntries>

To jest w konfiguracji archiwum maven-war-plugin. Ale można go również znaleźć w innych wtyczkach. W Hudson część wywołania kompilacji maven to:

-Dbuild.number=${BUILD_NUMBER}
-Dsvn.revision=${SVN_REVISION}
-Dbuild.id=${BUILD_ID}

który określa te definicje, które następnie podnosi maven. A potem wystarczy zajrzeć do pliku MANIFEST.MF, który został wdrożony na serwerze, aby zobaczyć, jaka to wersja.

Istnieje wtyczka git , która oferuje podobny zestaw zmiennych środowiskowych, w tym:

  • GIT_COMMIT - SHA prądu
  • GIT_BRANCH - Nazwa zdalnego repozytorium (domyślnie to origin), a następnie nazwa aktualnie używanego oddziału, np. „Origin / master” lub „origin / foo”

Połączenie tych dwóch praktyk pozwala łatwo zidentyfikować kompilację (ponieważ liczby kompilacji idą do przodu i mają znaczenie, w przeciwieństwie do sum kontrolnych sha) oraz konkretny zatwierdzenie git, z którego jest budowany.


źródło
3

Zupełnie innym podejściem byłoby całkowite odrzucenie idei versions. Masz tylko „jedną wersję”, która ma inne konfigurowalne zachowanie. Jedyna różnica polega na tym, że masz wspólną bazę kodu - nawet w produkcji wdrażasz prace w toku : ale nie aktywowane.

Różnica sprowadza się tylko do różnych zestawów funkcji włączanych w twoim produkcie.

De- / aktywacja odbywa się za pomocą przełączników funkcji .

Zaleta: cały proces wydawania jest uproszczony: zawsze dostarczasz zintegrowaną wersję swojego oprogramowania. Każda funkcja jest zawsze dostępna w master. Nie są potrzebne żadne dodatkowe oddziały.

Łączenie funkcji nie sprawia żadnego problemu, ponieważ: brak konieczności łączenia oddziałów. Nie ma wątpliwości co do tego, która funkcja jest zależna od gałęzi i może być zależna lub koliduje z funkcjami innych gałęzi. Każda część może być aktywowana do woli. Nawet cofnięcie nie jest już konieczne: jest to tylko naciśnięcie przełącznika .

Nie wiem, czy to działa na twoją bazę kodu: wymagania dotyczące jakości kodu i dyscypliny programistycznej są dość wysokie - musisz poradzić sobie z „czyszczeniem”, gdy funkcja stanie się podstawową funkcjonalnością i musisz zarządzać wieloma przełączeniami zapobieganie większemu bałaganowi .

Być może to działa dla ciebie.

Thomas Junk
źródło
Ale co z wdrożeniem różnych stanów repozytorium na różnych serwerach? Czy kod działający na polu kontroli jakości jest taki sam jak kod działający w środowisku produkcyjnym, aby móc odtworzyć błąd? Czy kod, który programiści wypchnęli na swoje pole programisty, jest taki sam, jak kod, na którym działa QA?
1
Pytanie należy zadać inaczej: czy błąd ze specjalną konfiguracją można odtworzyć „teraz”, jeśli tak, można go naprawić. Jeśli nie - czy błąd ma znaczenie? Zawsze wypychasz działający (i zintegrowany kod).
Thomas Junk
-1

Używamy maven do umieszczenia wersji w pliku manifestu. Następnie aplikacja powinna wyświetlić wersję, jeśli jest to aplikacja internetowa, lub mieć punkt końcowy / version dla usług internetowych.

Josh Chappelle
źródło