CI/CD con GitHub Actions en Flutter: ejercicio resuelto
CI/CD con GitHub Actions en Flutter: ejercicio resuelto
Sin CI/CD, la calidad del código depende de que cada desarrollador recuerde ejecutar los tests y el análisis antes de cada push. Con GitHub Actions, esas comprobaciones se ejecutan automáticamente en cada PR y cada merge a main, sin intervención manual.
Enunciado
Crea un pipeline de GitHub Actions para un proyecto Flutter que:
Análisis y tests: corre en cada push y PR a main.
Build de APK: genera un APK release al hacer merge a main.
Usa caché de pub: reduce el tiempo de setup de ~2 min a ~15 s.
Matrix de versiones: prueba en Flutter stable y beta.
# .github/workflows/ci.ymlname:CIon:push:branches:[main, develop]pull_request:branches:[main]jobs:analyze_and_test:name:Analyze & Test (Flutter ${{ matrix.flutter_channel }})runs-on:ubuntu-lateststrategy:matrix:flutter_channel:[stable, beta]fail-fast:false# no cancela el otro canal si uno fallasteps:- name:Checkout códigouses:actions/checkout@v4- name:Configurar Flutteruses:subosito/flutter-action@v2with:flutter-version:''# usa la última del canalchannel:${{ matrix.flutter_channel }}cache:true# cachea el SDK de Flutter- name:Caché de pub packagesuses:actions/cache@v4with:path:| ~/.pub-cache
.dart_toolkey:pub-${{ runner.os }}-${{ hashFiles('**/pubspec.lock') }}restore-keys:| pub-${{ runner.os }}-- name:Instalar dependenciasrun:flutter pub get- name:Verificar formatorun:dart format --set-exit-if-changed .- name:Análisis estáticorun:dart analyze --fatal-warnings- name:Tests unitarios y de widgetrun:flutter test --coverage- name:Subir cobertura a Codecovif:matrix.flutter_channel == 'stable'uses:codecov/codecov-action@v4with:token:${{ secrets.CODECOV_TOKEN }}files:coverage/lcov.info
dart analyze pasa local pero falla en CI: diferente versión de Dart. Fija la versión en flutter-action con flutter-version: '3.32.0' o usa el mismo canal que en local.
Tests fallan en CI pero no en local: suelen ser tests con DateTime.now() o que dependen del timezone. Usa fechas fijas en los tests.
APK demasiado grande: añade --split-debug-info=build/debug-info y --obfuscate para reducir tamaño y ofuscar código.
Aplicación práctica
Con este pipeline: cada PR pasa por análisis + tests automáticamente, los reviewers ven el resultado antes de aprobar, y cada merge a main genera un APK listo para distribución interna o subida a la Play Store.
¿Cuántos minutos de GitHub Actions tiene el plan gratuito?
2.000 minutos/mes en Linux para repositorios privados. Para repositorios públicos, los runners Linux son gratuitos e ilimitados. macOS consume 10× más minutos que Linux.
¿Puedo hacer deploy automático a la Play Store?
Sí, con fastlane o la acción r0adkll/upload-google-play. Necesitas una clave de API de Google Play y subir el AAB en lugar del APK.
¿Cómo evito que un PR pueda llegar a main sin pasar los tests?
En Settings → Branches → Branch protection rules, activa “Require status checks to pass before merging” y selecciona el job de CI como check requerido.