Creating a Rust-Build-Pipeline on Gitlab
GitLab und GitHub bieten eine schöne Möglichkeit seine Projekte gleich zu testen, zu bauen und evtl für den Download zur Verfügung zu stellen.
Da Rust nativen Maschinencode produziert, ist es notwendig für jede unterstützte Plattform zu bauen, die man zum Download anbieten möchte.
In meinem Beispiel habe ich ein Rust Projekt, das ich gerne für X64-Windows und X64-Linux anbieten möchte. Linux ist in dem Fall einfach, da die Build-Container auf den Plattformen meist Linux-Plattformen sind - also man kann einfach mit Bordmitteln bauen.
Der Einfachheit halber habe ich hier mal ein Gitlab-Build-Ci Script:
image: "rust:latest"
before_script:
stages:
- test
- build
build-linux:
stage: build
script: cargo build --release
artifacts:
paths:
- "target/release/rust_kontoauszug_importer"
test-linux:
stage: test
script: cargo test
Das obige Script führt alle Tests (test Stage) aus und baut anschließend das binary. Leider gibt es hier 2 Probleme
- Tests werden zwar ausgeführt aber die Testergebnisse werden nicht veröffentlicht
- Wir bauen nur ein (Linux-)Binary
Tests
Die Test-Auswertung von GitLab liest im Normalfall JUnit-Testergebnisse. Daher müssen wir die Test-Reports von Rust/Cargo nach JUnit übersetzen. Bei mir hat cargo2junit am besten funktioniert. Die Testergebnisse werden dann als Artefakte veröffentlicht.
...
test-linux:
stage: test
script:
- cargo install cargo2junit
- cargo test -- -Z unstable-options --format json --report-time | cargo2junit > results.xml
artifacts:
reports:
junit: results.xml
Damit werden die Testergebnisse für GitLab lesbar und wir bekommen bessere Auswertungen nach einem Checkin
Windows als Plattform
Dummerweise sind die Anwender der Software meist Windows-Benutzer. Daher ist sogenanntes Cross-Compiling notwendig. Rust bietet von sich aus bereits einen Teil an. rustup target add <plattform>
erledigt schon mal einen Teil. Allerdings fehlt meist noch der entsprechende compiler. Für Windows wäre das gcc-mingw-w64-x86-64
.
...
build-windows:
stage: build
script:
- rustup target add x86_64-pc-windows-gnu
- rustup toolchain install stable-x86_64-pc-windows-gnu
- apt update
- apt install gcc-mingw-w64-x86-64 -y
- cargo build --release --target x86_64-pc-windows-gnu
artifacts:
paths:
- "target/x86_64-pc-windows-gnu/release/rust_kontoauszug_importer.exe"
Zusammenfassung
Das gesamte Build-Script sieht dann so aus:
Beispiele für weitere Plattformen wären (alle sieht man rustup target list
):
- aarch64-apple-darwin - MacOS für Apple M1 (geht momentan nicht direkt)
- x86_64-apple-darwin - MacOS intel (https://wapl.es/rust/2019/02/17/rust-cross-compile-linux-to-macos.html)
- armebv7r-none-eabi - Linux auf Raspberry
image: "rust:latest"
before_script:
stages:
- test
- build
build-linux:
stage: build
script: cargo build --release
artifacts:
paths:
- "target/release/rust_kontoauszug_importer"
build-windows:
stage: build
script:
- rustup target add x86_64-pc-windows-gnu
- rustup toolchain install stable-x86_64-pc-windows-gnu
- apt update
- apt install gcc-mingw-w64-x86-64 -y
- cargo build --release --target x86_64-pc-windows-gnu
artifacts:
paths:
- "target/x86_64-pc-windows-gnu/release/rust_kontoauszug_importer.exe"
test-linux:
stage: test
script:
- cargo install cargo2junit
- cargo test -- -Z unstable-options --format json --report-time | cargo2junit > results.xml
artifacts:
reports:
junit: results.xml