GITLAB, CONAN und LF vs CRLF
« | 04 Sep 2022 | »Seit langem quält mich eine Unschönheit in der CONAN Welt an meinem Arbeitsplatz:
MSVC und GCC Pakete des gleichen Projektes erzeugen unterschiedliche Recipe-Hashes, weshalb immer eine Variante als “outdated” markiert wird.
Lösung: Zeilenenden vereinheitlichen!
Hat man ein CONAN basiertes C++ Projekt auf einem Gitlab Server liegen, dann laufen mindestens zwei Build-Jobs:
- einer für Windows
- und einer für Linux
Doch beim Upload ins JFrog Artifactory kommt es dann zu einer Überlappung,
da beide Builds ihr grundsätzlich gleiches “Rezept” (Recipe) exportieren.
Folglich müssten beide Builds zwar unterschiedliche Paket-Hashes bekommen,
aber den gleichen Recipe-Hash herausbekommen.
Doch genau das trat in unserem Firmenprojekt nicht ein, Windows lieferte
einen anderen Recipe-Hash als Linux und so geschah es, dass der Build-Job,
der später fertig wurde, beim Upload den Recipe-Hash des früheren Jobs
überschrieb.
Und das wiederum führt dazu, dass beim Aufruf von
conan search my_project/1.0.0@user/channel -r my_remote
das frühere Build-Job-Ergebnis als “outdated” markiert wird.
Das ist zwar nicht schlimm und andere CONAN Kommandos können die “outdated” Pakete trotzdem laden, doch trotzdem störte mich diese Inkonsistenz.
GIT und Line-Endings
Als ursprüngliches Linux Produkt kennt GIT eigentlich nur LF
als Zeilenende.
GIT for Windows nutzt daher die default-Konfiguration:
core.autocrlf=true
Mit dieser Option wird beim clone
/ fetch
/ pull
jedes LF
in Sourcen
durch ein CRLF
ersetzt. Umgekehrt wird beim commit
/ push
wieder jedes
CRLF
zu LF
, damit am GIT Server alles einheitlich im Linux-Standard
gespeichert wird.
Compiler können mit Sourcen beider Konventionen umgehen, doch CONAN bildet
seine Hashes über die Sourcen genau so, wie sie lokal ausgecheckt sind.
Und damit sieht der Recipe-Hash auf Windows und Linux unterschiedlich aus.
Die Lösung ist also das Kommando
git config --global core.autocrlf false
auf der Windows Maschine, auf der der Build läuft, und alles ist gut.
GIT lädt dann die Sourcen genau so herunter und wieder hoch, wie sie sind,
und macht keine eigenmächtigen Anpassungen.
Gitlab Runners und GIT
Doch wie zum Teufel kann man jetzt GitLab dazu bringen, auf den Windows-Runnern ebenso diese Option zu setzen?
Nach langem Suchen blieb ich auf der
GitLab Seite zur Runner-Konfiguration
in config.toml
hängen, denn dort wird von der Konfigurationszeile
pre_clone_script
gesprochen.
Dieses “Script” wird ausgeführt, bevor der Gitlab-Runner die Sourcen
herunterlädt und genau hier kann man per git
Kommando Einstellungen verändern.
Diese Zeile wird tatsächlich als erstes im Docker Container ausgeführt und sorgt dafür, dass GIT unter Windows alles genau so auscheckt, wie es auch unter Linux passiert.
Und am Ende sind dann die Recipe-Hashes identisch und beide Builds werden als
Outdated from recipe: False
angezeigt
Fazit
Mission erfüllt!
Aber ich muss schon sagen, dass es sehr mühsam war, die Hintergründe
herauszufinden.
Ich dachte eigentlich, es gibt eine GitLab CI Variable, mit der man das steuern könnte, doch bisher habe ich keine solche gefunden.
Das Anpassen der GitLab-CI-Runner ist eine schöne Sache, wenn man die
Server selbst verwaltet (was hier zum Glück der Fall war).
Doch wenn man zentrale Serverfarmen nutzt, ist es fraglich, ob einem der
Admin einen separaten Runner-TAG mit eben diese Konfiguration anlegen
wird.
Eben deshalb wäre es notwendig, dieses Verhalten über die eigene
CI-Konfiguration steuern zu können, und nicht über config.toml
am
Server.
Wie auch immer, wieder ein Rätsel gelöst und ein Script
Sudoku vollgekritzelt
… das heißt, ich kann beruhigt schlafen gehen.