ci: add Gitea Actions workflow to build and upload APK artifacts
This commit is contained in:
@@ -0,0 +1,79 @@
|
|||||||
|
name: Build Android APK
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
- master
|
||||||
|
- 'refactor/**'
|
||||||
|
tags:
|
||||||
|
- 'v*'
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
- master
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-android:
|
||||||
|
name: Build Release APKs
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container:
|
||||||
|
image: ghcr.io/cirruslabs/flutter:3.19.3
|
||||||
|
steps:
|
||||||
|
- name: Checkout Repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Configure Git Safe Directory
|
||||||
|
run: |
|
||||||
|
git config --global --add safe.directory "$GITHUB_WORKSPACE"
|
||||||
|
git config --global --add safe.directory '*'
|
||||||
|
|
||||||
|
- name: Make Gradlew Executable
|
||||||
|
run: chmod +x android/gradlew
|
||||||
|
|
||||||
|
- name: Inspect Build Environment
|
||||||
|
run: |
|
||||||
|
flutter --version
|
||||||
|
java -version
|
||||||
|
|
||||||
|
- name: Fetch Flutter Dependencies
|
||||||
|
run: flutter pub get
|
||||||
|
|
||||||
|
- name: Run Code Analysis & Tests
|
||||||
|
run: |
|
||||||
|
flutter analyze
|
||||||
|
flutter test
|
||||||
|
|
||||||
|
- name: Build Universal Release APK
|
||||||
|
run: flutter build apk --release
|
||||||
|
|
||||||
|
- name: Build Split-per-ABI Release APKs
|
||||||
|
run: flutter build apk --release --split-per-abi
|
||||||
|
|
||||||
|
- name: Organize Artifacts
|
||||||
|
run: |
|
||||||
|
mkdir -p release-apks
|
||||||
|
# Copy universal APK
|
||||||
|
if [ -f build/app/outputs/flutter-apk/app-release.apk ]; then
|
||||||
|
cp build/app/outputs/flutter-apk/app-release.apk release-apks/oggauer-gemeindetrommler-universal-release.apk
|
||||||
|
fi
|
||||||
|
# Copy split APKs
|
||||||
|
if [ -f build/app/outputs/flutter-apk/app-arm64-v8a-release.apk ]; then
|
||||||
|
cp build/app/outputs/flutter-apk/app-arm64-v8a-release.apk release-apks/oggauer-gemeindetrommler-arm64-v8a.apk
|
||||||
|
fi
|
||||||
|
if [ -f build/app/outputs/flutter-apk/app-armeabi-v7a-release.apk ]; then
|
||||||
|
cp build/app/outputs/flutter-apk/app-armeabi-v7a-release.apk release-apks/oggauer-gemeindetrommler-armeabi-v7a.apk
|
||||||
|
fi
|
||||||
|
if [ -f build/app/outputs/flutter-apk/app-x86_64-release.apk ]; then
|
||||||
|
cp build/app/outputs/flutter-apk/app-x86_64-release.apk release-apks/oggauer-gemeindetrommler-x86_64.apk
|
||||||
|
fi
|
||||||
|
echo "=== Generated APK Artifacts ==="
|
||||||
|
ls -lah release-apks/
|
||||||
|
|
||||||
|
- name: Upload APKs to Gitea Artifacts
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: oggauer-gemeindetrommler-apks
|
||||||
|
path: release-apks/*.apk
|
||||||
|
retention-days: 30
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
name: Build Android APK
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
- master
|
||||||
|
- 'refactor/**'
|
||||||
|
tags:
|
||||||
|
- 'v*'
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
- master
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-android:
|
||||||
|
name: Build Release APKs
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container:
|
||||||
|
image: ghcr.io/cirruslabs/flutter:3.19.3
|
||||||
|
steps:
|
||||||
|
- name: Checkout Repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Configure Git Safe Directory
|
||||||
|
run: |
|
||||||
|
git config --global --add safe.directory "$GITHUB_WORKSPACE"
|
||||||
|
git config --global --add safe.directory '*'
|
||||||
|
|
||||||
|
- name: Make Gradlew Executable
|
||||||
|
run: chmod +x android/gradlew
|
||||||
|
|
||||||
|
- name: Inspect Build Environment
|
||||||
|
run: |
|
||||||
|
flutter --version
|
||||||
|
java -version
|
||||||
|
|
||||||
|
- name: Fetch Flutter Dependencies
|
||||||
|
run: flutter pub get
|
||||||
|
|
||||||
|
- name: Run Code Analysis & Tests
|
||||||
|
run: |
|
||||||
|
flutter analyze
|
||||||
|
flutter test
|
||||||
|
|
||||||
|
- name: Build Universal Release APK
|
||||||
|
run: flutter build apk --release
|
||||||
|
|
||||||
|
- name: Build Split-per-ABI Release APKs
|
||||||
|
run: flutter build apk --release --split-per-abi
|
||||||
|
|
||||||
|
- name: Organize Artifacts
|
||||||
|
run: |
|
||||||
|
mkdir -p release-apks
|
||||||
|
# Copy universal APK
|
||||||
|
if [ -f build/app/outputs/flutter-apk/app-release.apk ]; then
|
||||||
|
cp build/app/outputs/flutter-apk/app-release.apk release-apks/oggauer-gemeindetrommler-universal-release.apk
|
||||||
|
fi
|
||||||
|
# Copy split APKs
|
||||||
|
if [ -f build/app/outputs/flutter-apk/app-arm64-v8a-release.apk ]; then
|
||||||
|
cp build/app/outputs/flutter-apk/app-arm64-v8a-release.apk release-apks/oggauer-gemeindetrommler-arm64-v8a.apk
|
||||||
|
fi
|
||||||
|
if [ -f build/app/outputs/flutter-apk/app-armeabi-v7a-release.apk ]; then
|
||||||
|
cp build/app/outputs/flutter-apk/app-armeabi-v7a-release.apk release-apks/oggauer-gemeindetrommler-armeabi-v7a.apk
|
||||||
|
fi
|
||||||
|
if [ -f build/app/outputs/flutter-apk/app-x86_64-release.apk ]; then
|
||||||
|
cp build/app/outputs/flutter-apk/app-x86_64-release.apk release-apks/oggauer-gemeindetrommler-x86_64.apk
|
||||||
|
fi
|
||||||
|
echo "=== Generated APK Artifacts ==="
|
||||||
|
ls -lah release-apks/
|
||||||
|
|
||||||
|
- name: Upload APKs to Gitea Artifacts
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: oggauer-gemeindetrommler-apks
|
||||||
|
path: release-apks/*.apk
|
||||||
|
retention-days: 30
|
||||||
@@ -63,19 +63,50 @@ Basierend auf dem ursprünglichen Lastenheft von Thomas und den UI-Wireframes (`
|
|||||||
### Projektstruktur (`lib/`):
|
### Projektstruktur (`lib/`):
|
||||||
```text
|
```text
|
||||||
lib/
|
lib/
|
||||||
├── AddPage.dart # Erfassungsdialog für Beiträge, Mängel & Ideen (Upload, Crop)
|
├── firebase_options.dart # Firebase-Projektkonfiguration (Android & iOS)
|
||||||
├── DetailPage.dart # Detailansicht für einzelne Beiträge inkl. PDF-Export
|
├── main.dart # App-Einstiegspunkt, Firebase Init & MultiProvider
|
||||||
├── LoginPage.dart # (Fragment) E-Mail/Passwort-Loginmaske (nicht verdrahtet)
|
├── models/
|
||||||
├── register.dart # (Fragment) Registrierungsmaske (nicht verdrahtet)
|
│ └── post_item.dart # Typisiertes Datenmodell für News, Mängel & Ideen
|
||||||
├── UserDefinedList.dart # Universelle Listenanzeige, Firestore-Stream, Selektion & Sammel-PDF
|
├── screens/
|
||||||
├── anonym_aut.dart # AuthState Provider & einfacher anonymer Login-Screen
|
│ ├── add_issue_screen.dart # Mängelerfassung mit Straßenauswahl & bis zu 2 Fotos
|
||||||
├── firebase_options.dart # Firebase-Projektkonfiguration (Android & iOS)
|
│ ├── add_post_screen.dart # Universelle Erfassung für News & Bürgerideen
|
||||||
├── home.dart # Haupt-Scaffold mit BottomNavigationBar (4 Tabs)
|
│ ├── auth_dialog.dart # Anmelde-, Registrierungs- & Code-Freischaltungs-Dialog
|
||||||
└── main.dart # App-Einstiegspunkt, Firebase Init & MultiProvider
|
│ ├── contact_screen.dart # Bürgerforum-Kontaktformular & Anfragen
|
||||||
|
│ ├── detail_screen.dart # Detailansicht mit Metadaten & PDF-Einzelexport
|
||||||
|
│ ├── home_screen.dart # Haupt-Scaffold mit 5 Tabs (News, Mängel, Ideen, Kontakt, Info)
|
||||||
|
│ ├── info_screen.dart # Bürgerforum Leitbild, Notrufnummern & Account-Status
|
||||||
|
│ └── post_list_screen.dart # Universelle Listenansicht, Echtzeitsuche & PDF-Tabelle
|
||||||
|
└── services/
|
||||||
|
├── auth_service.dart # Hybrid-Auth (E-Mail/Passwort, Bürger-Code, Anonym)
|
||||||
|
├── firestore_service.dart# NoSQL CRUD & Kontaktanfragen
|
||||||
|
├── pdf_service.dart # PDF-Druckerzeugung (Listen & Einzelansichten)
|
||||||
|
└── storage_service.dart # Optimierter Bild-Upload (Querformat max 800x600)
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## 🤖 CI/CD Pipeline (Gitea Actions)
|
||||||
|
|
||||||
|
Die App verfügt über eine vollautomatische Build-Pipeline für **Gitea Actions** (`.gitea/workflows/build-apk.yaml`):
|
||||||
|
|
||||||
|
### Funktionen der Pipeline:
|
||||||
|
- **Automatische Trigger:** Wird bei jedem `push` auf `main`, `master`, `refactor/**`, bei Git-Tags (`v*`) oder manuell im Webinterface (`workflow_dispatch`) ausgelöst.
|
||||||
|
- **Isolierte Build-Umgebung:** Nutzt das offizielle `ghcr.io/cirruslabs/flutter:3.19.3` Docker-Image mit vorinstalliertem Android SDK, Java 17 und Flutter.
|
||||||
|
- **Qualitätssicherung:** Führt automatisch `flutter analyze` und `flutter test` aus, bevor der Build startet.
|
||||||
|
- **Vollständige APK-Generierung:**
|
||||||
|
- `oggauer-gemeindetrommler-universal-release.apk` (Universelle Release-APK für alle Android-Geräte)
|
||||||
|
- `oggauer-gemeindetrommler-arm64-v8a.apk` (Für moderne 64-Bit Smartphones)
|
||||||
|
- `oggauer-gemeindetrommler-armeabi-v7a.apk` (Für ältere 32-Bit Smartphones)
|
||||||
|
- `oggauer-gemeindetrommler-x86_64.apk` (Für Emulatoren & ChromeOS)
|
||||||
|
- **Artifact-Upload:** Speichert die fertigen APKs als herunterladbare ZIP-Datei (`oggauer-gemeindetrommler-apks`) direkt im Gitea Run-Dashboard.
|
||||||
|
|
||||||
|
### APKs in Gitea herunterladen:
|
||||||
|
1. Im Gitea-Repository auf den Reiter **Aktionen** (*Actions*) klicken.
|
||||||
|
2. Den gewünschten Pipeline-Durchlauf auswählen.
|
||||||
|
3. Im Abschnitt **Artefakte** (*Artifacts*) das Paket `oggauer-gemeindetrommler-apks` herunterladen.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## 🛠️ Einrichtung & Lokaler Start
|
## 🛠️ Einrichtung & Lokaler Start
|
||||||
|
|
||||||
### Voraussetzungen
|
### Voraussetzungen
|
||||||
@@ -92,31 +123,14 @@ flutter pub get
|
|||||||
# 2. Statische Code-Analyse ausführen
|
# 2. Statische Code-Analyse ausführen
|
||||||
flutter analyze
|
flutter analyze
|
||||||
|
|
||||||
# 3. App starten
|
# 3. Tests ausführen
|
||||||
|
flutter test
|
||||||
|
|
||||||
|
# 4. App lokal starten
|
||||||
flutter run
|
flutter run
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🚀 Empfohlene Verbesserungen & Roadmap
|
|
||||||
|
|
||||||
Die Erstellung durch frühe KI-Modelle hat zu funktionalen Proof-of-Concepts geführt, weist jedoch typischen Refactoring-Bedarf auf:
|
|
||||||
|
|
||||||
1. **Code-Hygiene & Best Practices:**
|
|
||||||
- Umbenennung der Dateien nach Dart-Konvention (`snake_case`, z. B. `add_page.dart`, `detail_page.dart`).
|
|
||||||
- Behebung der `flutter analyze` Warnungen (Deprecations wie `enablePersistence`, `BuildContext` across async gaps, ungenutzte Imports).
|
|
||||||
- Saubere Abhängigkeitsdeklaration (`http` direkt in `pubspec.yaml` aufnehmen).
|
|
||||||
2. **Architektur & Wartbarkeit:**
|
|
||||||
- Trennung von UI und Business-Logik (Einführung von Repositories / Services für Firestore und Firebase Storage).
|
|
||||||
- Auslagerung der CPU-intensiven Bildverarbeitung (`image.decodeImage`) in Isolate (`compute`), um UI-Ruckler zu vermeiden.
|
|
||||||
3. **Vervollständigung der Fachanforderungen:**
|
|
||||||
- **Kontakt-Formular:** Umsetzung mit Pflichtfeldern und Mail-Trigger (z. B. via Firebase Extension `Trigger Email` oder Cloud Function).
|
|
||||||
- **Informationen / Impressum / Veranstaltungen:** Fünfter Tab gemäß Anforderung.
|
|
||||||
- **Mängelmeldung:** Dropdown für Straßenverzeichnis Oggau und Grundlage; Unterstützung von bis zu 2 Fotos im Querformat.
|
|
||||||
- **Volltextsuche:** Suchleiste / Suchsymbol in den Listenansichten.
|
|
||||||
- **Zugangskonzept:** Echtes Bürger-Passwort bzw. PIN-Schutz statt reinem anonymen Login.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📄 Lizenz & Urheberschaft
|
## 📄 Lizenz & Urheberschaft
|
||||||
Erstellt für die Marktgemeinde Oggau am Neusiedler See. Private Verwendung.
|
Entwickelt für das **Bürgerforum Oggau**. Private & gemeinnützige Verwendung.
|
||||||
|
|||||||
Reference in New Issue
Block a user