3sky's notes

Minimalistyczny blog o TI.

Jenkins and submodules

2021-04-02 2 min czytania 3sky

Witaj

To będzie krótki post, raczej pełen mojego bólu i frustracji. Na szczęście z happy-endem i tematem na mały artykuł.

Problem

GitHub ma pewne problemy z kontami usług dla CI/CD. Przynajmniej w wersji Free Plan. Nie można dzielić siękluczami deploymentu jak np. w GitLabie. Mogę to zrozumieć w kontekście bezpieczeństwa, ale jeśli masz 4,5 lub 15 repozytoriów, musisz zarządzać taką samą liczbą par kluczy ssh. Jest to denerwujące, ale przyzwyczaiłem się do tego. Problem pojawia się, gdy musisz użyć sumbodules w procesach CICD z Jenkinsem. Powiedzmy, że Jenkins ma również probem z submodułami. Ogólnie rzecz biorąc, jeśli używasz multibranch sytuacja jest udokumentowana:

checkout([
   $class: 'GitSCM',
   branches: scm.branches,
   doGenerateSubmoduleConfigurations: scm.doGenerateSubmoduleConfigurations,
   extensions: scm.extensions,
   extensions: [
     [$class: 'RelativeTargetDirectory', relativeTargetDir: 'dir'],
     [
      $class: 'SubmoduleOption',
      disableSubmodules: false,
      parentCredentials: true,
      recursiveSubmodules: true,
      reference: '',
      trackingSubmodules: false
     ]
   ],
   userRemoteConfigs: scm.userRemoteConfigs
])

Ale kiedy używasz regularnego procesu typu pipeline, nie możesz po prostu użyć userRemoteConfigs. Rozwiązanie było proste, po zwykłym checkoucie dodać mały krok sh:

sh("""
    cd /dir && git submodule update --init --recursive
""")

Również co jest ważne Jenkins musi mieć odpowiednią konfigurację ~/.ssh/config z IdentityFile ustawionym na poprawny klucz prywatny. Ale to jest ok.

Wtedy…

Ale jak poradzić sobie z drugim prywatnym modułem? To nie jest takie banalne. Git nie działa jak zwykły ssh - nie sprawdza kluczy w określonej kolejności. Git sprawdza pierwszy i wyrzuca błąd… Najpopularniejszym rozwiązaniem jest:

  • zmień nazwę hosta w GitHub, a następnie zrób checkout z tą nową nazwą hosta

Jasne, że to świetne rozwiązanie, gdy jesteś developerem, ale gdy przychodzi do CI to… eh nie rób tego. Twoi programiści cię znienawidzą.

Rozwiązanie

Może nie jest to najlepsze rozwiązanie w historii, nie jest tak mądre i piękne, ale przynajmniej działa.

Implementacja

Po pierwsze - dodaj nowy klucz do katalogu .ssh/ - lokalizacja może być inna, ale profesjonaliści mają swoje standardy.

A potem przychodzi bash

sh("""
    cd /dir
    git submodule update --init external/module_a
    export GIT_SSH_COMMAND="/usr/bin/ssh -i /root/.ssh/id_rsa_b"
    git submodule update --init external/module_b
    git submodule update --init --recursive
    unset GIT_SSH_COMMAND
""")

I to jest to. Proste, czytelne i działające.

Podsumowanie

Co mogę dodać? Submoduły są trudne, Github jest trudny, Jenkins jest niesamowity, ale trudny. Życie jest ciężkie… Ogólnie rzecz biorąc, IT jest ciężkie, ale daje dużo frajdy. Nie mogę sobie wyobrazić lepszej pracy, nawet jeżeli ktoś doda nowy submoduł do stabilnej gałęzi i zniszczy Twój wspaniały piątkowy wieczór. Trzymaj się więc i może podrzuć mi jakąś wiadomość, teraz czuję się jakby nikt tego nie czytał…