W moim przypadku mowa o Kotlin DSL dla TeamCity.

Generalnie nie ma w tym niby żadnej czarnej magii, kod jak kod - jak sobie wyrzeźbisz, tak masz. Cała konfiguracja CICD pod kontrolą wersji, także spoko. Co może pójść źle?

No, ja widzę parę bolączek, ewentualnie zastrzeżeń do pipeline as code w wydaniu TeamCity - część pewnie ma źródło gdzieś między krzesłem a monitorem (moim)

(Nie)wsparcie IDE

TeamCity jest od Jetbrains, IntelliJ jest od Jetbrains, Kotlin jest od Jetbrains - ok, jest plugin IJ do gmerania w TC z poziomu IDE, ale jeszcze nie uświadczyłem wsparcia (wbudowanego lub przez pluginy, najlepiej oficjalne) IDE dla tych Kotlinowych skrypcików. Generalnie ostatnio chyba w końcu przestało mi podkreślać na czerwono absolutnie wszystko, i zamiast tego podkreśla tylko importy. Przyjemnie.

Na takie zbytki jak podpowiadanie / autouzupełnianie / podkreślenie jak się walniesz i zamiast template wstukasz tempalte nawet nie ma co liczyć...

Dokumentacja-widmo

Dokumentacja online do tego Kotlin DSL jest zwyczajnie upierdliwa - chyba słabo wypozycjonowana, wpisywanie haseł pokroju teamcity dsl documentation zwraca naprawdę ciekawe wyniki, ale akurat nie to, co trzeba. Jak nie zapominam, to googluję hasłem teamcity buildtype i wtedy dopiero na pierwszym miejscu pokazuje się dokumentacja dla BuildType.

No i generalnie znalezienie tam czegokolwiek można by już uznać za e-sport. Zresztą zobaczcie sami, nagroda pocieszenia dla tego, kto pierwszy odnajdzie w tej dokumentacji szukajkę - ja po prostu scrolluję, robię ctrl+F i klikam po klasach, metodach i atrybutach, aż się doklikam do tego co mi potrzebne. O przejściu z package x.y.z do x.y lub x.y.z.q można zapomnieć, można co najwyżej wystukać w URLu:
https://teamcity.jetbrains.com/app/dsl-documentation/jetbrains.build-server.configs.kotlin.v2018_1/index.html

Developer-unfriendliness

Gdy np. eksportujesz sobie istniejący projekt do skryptów, domyślnie wszystko jest władowane w jeden plik. Oczywiście można go sobie pociąć na mniejsze, albo doklikać się do opcji gdzieś-tam w konfiguracji serwera, żeby wygenerował konfigurację podzieloną na mniejsze pliki.

Ale na tym nie kończą się problemy - bo np. możesz mieć sytuację, gdy w jednym root project masz wiele pod-projektów, każdy pod własnym repo (jeśli nie chcesz mieć jednego turbo-repo na turbo-konfigurację absolutnie wszystkiego dla CICD iluś aplikacji). Siłą rzeczy ten projekt-rodzic może mieć zdefiniowane np. pewne wspólne parametry, albo połączenia do firmowego docker registry tam i siam, właściwie cokolwiek. No i zgadnijcie co - pół biedy z parametrami, ale odwołanie się w swoim skrypcie do takiego np. docker connection z projektu-rodzica, który jest poza VCS, sprowadza się do przeklikiwania się przez UI aż się znajdzie ten właściwy i... wygenerowanie dla niego Kotlin DSLa lub przeglądanie narzędziami deweloperskimi, by wydłubać sobie jego ID, który to możesz sobie wreszcie użyć. W przeciwieństwie do np. ID builda - tutaj nie da się go zgadnąć na podstawie drzewka projektów, bo ma format mniej-więcej EXT_1234 i tylko cyferki się zmieniają.

Idąc dalej, pokonałeś w końcu problemy z eksportowaniem kuli błota, posprzątałeś wstępnie kod, zgadnąłeś IDki z pomocą wróżbity Macieja - zostaje ogarnięcie samych buildów. I znowu - eksportując np. build stepy ze swoimi skrypcikami, dostaniesz je pięknie wepchnięte w kod jako multi-line stringi. Oczywiście, możesz je sobie ręcznie przenieść do osobnych plików jako skrypty i tylko odpalać one-linerami... ale niesmak pozostaje. Tym bardziej, że wymagają wtedy przepisania, by pozbyć się dziwnego escapowania (bo choćby $ jest escapowany np. tak: ${'$'}) i tym podobnych smaczków.

Widoczność i rozwiązywalność błędów

W TC zwyczajnie łatwo jest przeoczyć, że coś poszło nie tak - niby rzuci warning, ale łatwo nie zauważyć. Niby pokoloruje etykietę builda na bledszy kolor, jeśli branch w TC rozjeżdża się z branchem w VCS.

Wystarczy też, że ktoś zmieni cokolwiek w projekcie (cokolwiek może oznaczać np. domyślną wartość parametru) i TC nie zassie więcej konfiguracji z VCS - wywali się na tym, że są jakieś zmiany zrobione lokalnie i do widzenia. Mimo że w versioned settings jest wyraźne zaznaczone, że konfiguracje z VCS mają mieć pierwszeństwo nad lokalnymi. Nie mają. Ale oczywiście da się to naprawić - nie, nie klikając przycisku reload lub coś w ten deseń. Trzeba sobie wyłączyć wersjonowanie ustawień, zapisać zmiany, włączyć z powrotem - i dopiero wtedy przy zapisie można zmusić TC, by zaorało lokalne ustawienia i zassało z VCS.

Testowalność

Tak, fajnie byłoby móc sobie przetestować ten kod. W końcu mogłem się pomylić, prawda? No, nie. Teoretycznie Jetbrains nawet pokazują, jak te DSLe testować: https://blog.jetbrains.com/teamcity/2019/05/configuration-as-code-part-6-testing-configuration-scripts/ W praktyce jednak nie widzę innego sposobu na przetestowanie tego, jak manualne przeklikanie tych buildów i sprawdzenie, czy działa - bo i jak tu w miarę łatwo testować build, który robi deploya na produkcję bez zdeployowania jakiegoś syfu na produkcję?

Tak naprawdę jedyne, co do tej pory udało się osiągnąć w kwestii testowania pipeline as code, to skompilowanie tego paskudztwa i upewnienie się, że nie ma żadnego tempalte, brakującego importu i tym podobnych.

Wszystko to prowadzi do tego, że o ile same aplikacje idzie rozwijać normalnie, tak historię commitów w pipeline as code TeamCity można zobrazować tak:

  • zmień to i tamto
  • fix
  • fix fix
  • revert fix
  • final fix
  • ...

PS Nie zapomnijcie wspomnieć, jakiego serwera CI używacie ;)