CI/CD avancé pour projets Kotlin sur GitHub Actions
L'automatisation du build, des tests et du déploiement est une étape cruciale dans le développement d'applications Kotlin modernes. Si la configuration de base du CI/CD est déjà maîtrisée, il est temps de passer aux techniques avancées. Dans cet article, nous verrons comment tirer le meilleur parti de GitHub Actions pour les projets Kotlin : builds matriciels, mise en cache intelligente, tests parallèles et déploiement flexible.
1. Builds matriciels : tester sur plusieurs versions et systèmes d'exploitation
L'une des fonctionnalités les plus puissantes de GitHub Actions est la stratégie matricielle (strategy.matrix). Elle permet d'exécuter le même workflow avec différents paramètres. Pour Kotlin, c'est indispensable si vous prenez en charge plusieurs versions de la JVM ou des plateformes cibles (par exemple, JVM + Native).
Exemple de build matriciel pour un projet Kotlin Multiplatform :
name: Matrix Build Kotlinon: [push, pull_request]
jobs: build: runs-on: ${{ matrix.os }} strategy: matrix: os: [ubuntu-latest, macos-latest, windows-latest] java: [11, 17, 21] kotlin-version: [1.9.22, 2.0.0] fail-fast: false # ne pas arrêter les autres builds en cas d'erreur sur l'un d'eux
steps: - uses: actions/checkout@v4
- name: Set up JDK ${{ matrix.java }} uses: actions/setup-java@v4 with: java-version: ${{ matrix.java }} distribution: 'temurin'
- name: Validate Gradle wrapper uses: gradle/wrapper-validation-action@v2
- name: Build with Gradle run: ./gradlew build -Dkotlin.version=${{ matrix.kotlin-version }}Recommandations :
- Utilisez
fail-fast: falsepour ne pas perdre les résultats des autres combinaisons si l'une d'elles échoue. - Limitez la matrice aux versions pertinentes uniquement pour ne pas gaspiller les minutes Actions.
- Pour Windows, configurez correctement les chemins vers Gradle et vérifiez les sauts de ligne (CRLF).
2. Mise en cache intelligente de Gradle et des dépendances
Les projets Kotlin avec Gradle peuvent télécharger des dizaines de mégaoctets de dépendances à chaque exécution du CI. Sans mise en cache, le build prendra 5 à 10 minutes, et avec elle, 30 à 40 secondes. Utilisez les actions intégrées pour la mise en cache.
steps: - uses: actions/cache@v4 with: path: | ~/.gradle/caches ~/.gradle/wrapper build/ key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} restore-keys: | ${{ runner.os }}-gradle-
- name: Build with Gradle run: ./gradlew build --build-cache --no-daemonAstuces avancées :
- Ajoutez à la clé de cache le hash de
gradle.lockfile(si vous utilisez--write-locks) — cela garantit l'invalidation du cache lors du changement des versions des dépendances. - Utilisez
gradle-build-actionde Gradle (action :gradle/gradle-build-action@v3) — il gère automatiquement la mise en cache et inclut le support de--build-cache. - Ne mettez pas en cache
~/.gradle/daemon— cela pourrait entraîner des conflits entre différentes versions du démon.
3. Tests parallèles et répartition dynamique (sharding)
Pour les grands projets avec des centaines de tests, le temps d'exécution peut être un goulot d'étranglement. GitHub Actions permet d'exécuter les tests en parallèle en les répartissant en shards. Cela est particulièrement utile pour Kotlin + JUnit 5.
Exemple de répartition des tests en shards :
jobs: test: runs-on: ubuntu-latest strategy: matrix: shard: [1, 2, 3, 4] # 4 shards parallèles steps: - uses: actions/checkout@v4 - name: Set up JDK 17 uses: actions/setup-java@v4 with: java-version: '17' distribution: 'temurin'