diff --git a/.github/agents/code-reviewer.agent.md b/.github/agents/code-reviewer.agent.md index d40f342..1363c6b 100644 --- a/.github/agents/code-reviewer.agent.md +++ b/.github/agents/code-reviewer.agent.md @@ -150,11 +150,11 @@ Korrektur: #### Schweregrade -| Schwere | Bedeutung | -|---|---| -| **KRITISCH** | Falsches Verhalten, Crash-Potenzial, Sicherheitslücke – muss behoben werden | -| **WICHTIG** | Standard-Verletzung, Codedopplung, schlechte Lesbarkeit – sollte behoben werden | -| **OPTIONAL** | Vereinfachung ohne funktionalen Einfluss – kann behoben werden | +| Schwere | Bedeutung | +| ------------ | ------------------------------------------------------------------------------- | +| **KRITISCH** | Falsches Verhalten, Crash-Potenzial, Sicherheitslücke – muss behoben werden | +| **WICHTIG** | Standard-Verletzung, Codedopplung, schlechte Lesbarkeit – sollte behoben werden | +| **OPTIONAL** | Vereinfachung ohne funktionalen Einfluss – kann behoben werden | --- @@ -163,4 +163,4 @@ Korrektur: - **Sachlich, nicht persönlich**: Kritisiere Code, nicht den Autor. - **Konkret**: Jede Beanstandung nennt die betroffene Datei und den betroffenen Bereich. - **Konstruktiv**: Zu jeder Beanstandung gibt es eine klare Korrekturempfehlung. -- **Verhältnismäßig**: Unterscheide klar zwischen blockierenden Problemen und optionalen Verbesserungen. \ No newline at end of file +- **Verhältnismäßig**: Unterscheide klar zwischen blockierenden Problemen und optionalen Verbesserungen. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..73a8394 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,86 @@ +name: CI – Swift Tests (macOS) + +on: + workflow_dispatch: + +jobs: + test: + name: Swift Tests (macOS) + runs-on: macos-15 + + env: + FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true + + defaults: + run: + working-directory: Migration + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Select Xcode 16.3 + run: sudo xcode-select -s /Applications/Xcode_16.3.app/Contents/Developer + + - name: Show Swift version + run: swift --version + + - name: Install SwiftLint + run: brew install swiftlint + + - name: Run SwiftLint + run: swiftlint lint --reporter github-actions-logging + + - name: Build + run: swift build 2>&1 | tee build.log; exit ${PIPESTATUS[0]} + + - name: Run tests + run: swift test 2>&1 | tee test.log; exit ${PIPESTATUS[0]} + + - name: Start MockServer + run: | + cd "$GITHUB_WORKSPACE/MockServer" + npm install --silent + node server.js & + echo "MOCK_PID=$!" >> "$GITHUB_ENV" + sleep 2 + curl -sf http://localhost:3000/auth/login \ + -X POST -H 'Content-Type: application/json' \ + -d '{"username":"ci","password":"ci"}' > /dev/null + echo "MockServer running on :3000" + + - name: Run integration tests + env: + MOCKSERVER_INTEGRATION: "1" + run: swift test --filter MockServerIntegration 2>&1 | tee integration.log; exit ${PIPESTATUS[0]} + + - name: Stop MockServer + if: always() + run: kill $MOCK_PID 2>/dev/null || true + + demonstrator: + name: Demonstrator Build + Test (macOS) + runs-on: macos-15 + + env: + FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true + + defaults: + run: + working-directory: Demonstrator/App + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Select Xcode 16.3 + run: sudo xcode-select -s /Applications/Xcode_16.3.app/Contents/Developer + + - name: Show Swift version + run: swift --version + + - name: Build + run: swift build 2>&1 | tee build.log; exit ${PIPESTATUS[0]} + + - name: Run tests + run: swift test 2>&1 | tee test.log; exit ${PIPESTATUS[0]} diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 512fd86..0c830b9 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -19,7 +19,7 @@ android { versionName = "1.3" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - buildConfigField("boolean", "FEATURE_CAMERA_ENABLED", "true") + buildConfigField("boolean", "FEATURE_CAMERA_ENABLED", "false") } buildTypes { diff --git a/app/src/main/java/de/bollwerk/app/ui/MainScreen.kt b/app/src/main/java/de/bollwerk/app/ui/MainScreen.kt index 1201fea..ced67f1 100644 --- a/app/src/main/java/de/bollwerk/app/ui/MainScreen.kt +++ b/app/src/main/java/de/bollwerk/app/ui/MainScreen.kt @@ -9,6 +9,7 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.windowInsetsPadding import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.SwapHoriz +import androidx.compose.material3.AlertDialog import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton @@ -17,6 +18,7 @@ import androidx.compose.material3.NavigationBarDefaults import androidx.compose.material3.Scaffold import androidx.compose.material3.Surface import androidx.compose.material3.Text +import androidx.compose.material3.TextButton import androidx.compose.material3.TopAppBar import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue @@ -37,6 +39,7 @@ import de.bollwerk.app.ui.inventory.InventoryPickerViewModel import de.bollwerk.app.ui.navigation.BollwerkNavGraph import de.bollwerk.app.ui.navigation.TopLevelDestination import de.bollwerk.app.ui.update.UpdateBanner +import de.bollwerk.app.ui.update.UpdateStatus import de.bollwerk.app.ui.update.UpdateViewModel @OptIn(ExperimentalMaterial3Api::class) @@ -142,6 +145,25 @@ internal fun MainScreen() { } } + if (updateState.status is UpdateStatus.Available) { + val available = updateState.status as UpdateStatus.Available + AlertDialog( + onDismissRequest = updateViewModel::dismiss, + title = { Text("Update verf\u00fcgbar") }, + text = { Text("Version ${available.versionName} ist verf\u00fcgbar. Jetzt aktualisieren?") }, + confirmButton = { + TextButton(onClick = updateViewModel::startDownload) { + Text("Aktualisieren") + } + }, + dismissButton = { + TextButton(onClick = updateViewModel::dismiss) { + Text("Sp\u00e4ter") + } + } + ) + } + if (isInventoryPickerVisible) { InventoryPickerSheet( onDismiss = { isInventoryPickerVisible = false }, diff --git a/app/src/main/java/de/bollwerk/app/ui/update/UpdateBanner.kt b/app/src/main/java/de/bollwerk/app/ui/update/UpdateBanner.kt index 3829306..3664000 100644 --- a/app/src/main/java/de/bollwerk/app/ui/update/UpdateBanner.kt +++ b/app/src/main/java/de/bollwerk/app/ui/update/UpdateBanner.kt @@ -32,7 +32,7 @@ internal fun UpdateBanner( onDismiss: () -> Unit, modifier: Modifier = Modifier ) { - val isVisible = status !is UpdateStatus.Hidden && status !is UpdateStatus.Checking + val isVisible = status !is UpdateStatus.Hidden && status !is UpdateStatus.Checking && status !is UpdateStatus.Available AnimatedVisibility( visible = isVisible, diff --git a/server/src/main/kotlin/de/bollwerk/server/plugins/Routing.kt b/server/src/main/kotlin/de/bollwerk/server/plugins/Routing.kt index 6fd261e..9f069e5 100644 --- a/server/src/main/kotlin/de/bollwerk/server/plugins/Routing.kt +++ b/server/src/main/kotlin/de/bollwerk/server/plugins/Routing.kt @@ -93,5 +93,8 @@ internal fun Application.configureRouting( // Admin web UI (static) staticResources("/admin", "static/admin") + + // Classpath assets (logo etc.) + staticResources("/res", "static") } } diff --git a/server/src/main/kotlin/de/bollwerk/server/routes/VersionRoutes.kt b/server/src/main/kotlin/de/bollwerk/server/routes/VersionRoutes.kt index 13a20e5..85ea280 100644 --- a/server/src/main/kotlin/de/bollwerk/server/routes/VersionRoutes.kt +++ b/server/src/main/kotlin/de/bollwerk/server/routes/VersionRoutes.kt @@ -248,11 +248,11 @@ private fun buildHomepageHtml(versionName: String, versionCode: Int, apkUrl: Str
- +

Bollwerk

Inventar • Vorsorge • Sicherheit

-

V.$versionName // Build $versionCode

+

v$versionName

⬇ APK herunterladen

QR-Code scannen oder Link antippen, um die App zu installieren.

diff --git a/server/src/test/kotlin/de/bollwerk/server/VersionEndpointTest.kt b/server/src/test/kotlin/de/bollwerk/server/VersionEndpointTest.kt index 2045aff..63c79ac 100644 --- a/server/src/test/kotlin/de/bollwerk/server/VersionEndpointTest.kt +++ b/server/src/test/kotlin/de/bollwerk/server/VersionEndpointTest.kt @@ -110,7 +110,6 @@ class VersionEndpointTest { // Then assertTrue(body.contains("2.1.0")) - assertTrue(body.contains("42")) } @Test