Pierwszy pipeline w organizacji powstaje w jednym repozytorium. Drugi projekt kopiuje plik i zmienia nazwę obrazu. Trzeci kopiuje od drugiego i dodaje krok. Po roku jest dwadzieścia plików o wspólnym przodku, a poprawka bezpieczeństwa w kroku budowania wymaga dwudziestu zmian, z których kilka nigdy nie zostanie zrobionych.

Zasada: logika w szablonie, różnice w zmiennych

Pipeline projektu powinien mieć kilkanaście linii: dołączenie szablonu z centralnego repozytorium i kilka zmiennych. Wszystko, co jest takie samo dla każdego projektu (sposób budowania obrazu, publikacja do rejestru, skanowanie, aktualizacja manifestów), żyje w jednym miejscu.

include:
  - project: platform/ci-templates
    ref: v2
    file: /templates/container-app.yml

variables:
  APP_NAME: orders-api
  APP_PATH: services/orders
  TEST_COMMAND: "npm test"

Projekt nie definiuje własnych zadań. Jeśli potrzebuje czegoś, czego szablon nie przewiduje, jest to sygnał do rozszerzenia szablonu, nie do nadpisania zadania lokalnie.

Struktura szablonu

Etapy są stałe i mają zawsze tę samą kolejność: sprawdzenie składni i stylu, testy, budowanie, publikacja, aktualizacja manifestów wdrożeniowych. Projekt może wyłączyć etap zmienną (na przykład SKIP_TESTS: "true" z uzasadnieniem w komentarzu), ale nie może zmienić jego treści.

Punkty rozszerzeń są jawne: zmienna z poleceniem testów, opcjonalny skrypt uruchamiany przed budowaniem, lista dodatkowych ścieżek do skanowania. Każdy punkt rozszerzenia jest udokumentowany w tabeli zmiennych w README szablonu. Punkt, którego nie ma w tabeli, nie istnieje.

Wersjonowanie

Szablon ma wersje oznaczone tagami. Projekty odwołują się do wersji głównej (v2), która jest ruchomym wskaźnikiem na najnowsze wydanie zgodne wstecz. Zmiana niezgodna wstecz oznacza nową wersję główną (v3) i migrację projektów w ich tempie. Odwołanie do gałęzi głównej szablonu jest zabronione: zmiana w szablonie nie może niespodziewanie zepsuć wszystkich pipeline’ów w organizacji.

Proces zmiany szablonu

  1. Zmiana w gałęzi szablonu, z opisem, co i dlaczego.
  2. Uruchomienie na projekcie referencyjnym: prostej aplikacji, która istnieje tylko po to, by testować szablon i całą ścieżkę do wdrożenia.
  3. Uruchomienie na dwóch lub trzech prawdziwych projektach wskazanych jako pilotażowe.
  4. Nowy tag i przesunięcie wskaźnika wersji głównej.
  5. Wpis w dzienniku zmian szablonu.

Projekt referencyjny jest najważniejszym elementem: bez niego każda zmiana szablonu jest testowana na produkcji kogoś innego.

Wykrywanie dryfu

Zadanie uruchamiane cyklicznie sprawdza wszystkie repozytoria: czy dołączają szablon, z jakiej wersji, czy definiują własne zadania. Wynik trafia na listę: projekty na przestarzałej wersji, projekty z lokalnymi nadpisaniami. Lista jest krótka, jeśli reguły są egzekwowane od początku, i bardzo długa, jeśli wprowadza się je po roku.

Co zostaje w projekcie

Rzeczy, które naprawdę różnią projekty: nazwa aplikacji, ścieżka w monorepozytorium, polecenie testów, wersja środowiska uruchomieniowego, lista środowisk docelowych. Wszystko to są wartości, nie logika. Jeśli w pliku projektu pojawia się script:, coś poszło nie tak.

Podsumowanie

Jeden szablon zamiast dwudziestu kopii oznacza, że poprawka jest jedna, audyt jest jeden, a nowy projekt dostaje działający pipeline w kwadrans. Warunki: logika wyłącznie w szablonie, jawne punkty rozszerzeń, wersje z tagami, projekt referencyjny do testów i zadanie, które wykrywa odstępstwa. Szablon, którego nie da się rozszerzyć bez kopiowania, będzie skopiowany.