diff --git a/.gitea/workflows/release.yaml b/.gitea/workflows/release.yaml index 7996415..e1a428f 100644 --- a/.gitea/workflows/release.yaml +++ b/.gitea/workflows/release.yaml @@ -13,10 +13,18 @@ jobs: # Standardmäßig 'ubuntu-latest'. Falls Ihr Runner unter einem anderen Label registriert ist # (z. B. 'linux', 'ubuntu-24.04' oder 'host'), passen Sie dieses Label an. runs-on: ubuntu-latest + # The APK from the android job goes into the release and its SHA256SUMS.txt + needs: android steps: - name: Checkout Repository uses: actions/checkout@v4.2.2 + - name: Fetch Android APK + uses: actions/download-artifact@v4.3.0 + with: + name: ink-notes-android-apk + path: target + - name: Install System Packaging Tools run: | export DEBIAN_FRONTEND=noninteractive @@ -63,13 +71,14 @@ jobs: cargo clippy --all-targets -- -D warnings cargo test - - name: Build Release Artifacts (.deb, .AppImage, .exe, SHA256SUMS.txt + .minisig) + - name: Build Release Artifacts (.deb, .AppImage, .exe, .apk, SHA256SUMS.txt + .minisig) run: | chmod +x scripts/*.sh ./scripts/build-release.sh env: MINISIGN_SECRET_KEY: ${{ secrets.MINISIGN_SECRET_KEY }} INK_NOTES_REQUIRE_SIGNATURE: "1" + INK_NOTES_REQUIRE_APK: "1" - name: Publish Release to Gitea run: | @@ -81,11 +90,9 @@ jobs: REPO_NAME: ${{ github.event.repository.name }} android: - # Experimental (Issue #45): builds the APK and keeps it as a workflow artifact. It is not - # part of the release yet, and a failure here does not stop the release above. - name: Android APK (experimental) + # Builds the signed APK (Issue #45) and hands it to the release job as a workflow artifact + name: Android APK runs-on: ubuntu-latest - continue-on-error: true steps: - name: Checkout Repository uses: actions/checkout@v4.2.2 @@ -131,7 +138,7 @@ jobs: ANDROID_KEYSTORE_PASS: ${{ secrets.ANDROID_KEYSTORE_PASS }} ANDROID_KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }} - - name: Keep APK as Artifact + - name: Hand APK to the Release Job uses: actions/upload-artifact@v4.6.2 with: name: ink-notes-android-apk diff --git a/README.de.md b/README.de.md index 96f68ca..6b94ec6 100644 --- a/README.de.md +++ b/README.de.md @@ -13,7 +13,7 @@ ink-notes speichert Handschrift als Vektoren, erkennt auf Wunsch Formen, kann PDFs zum Beschriften sowie Notizbücher aus Xournal++, Rnote und Saber importieren, Bilder und Textfelder einfügen und alles wieder als PDF, PNG oder SVG exportieren. Gespeichert wird automatisch im Hintergrund. -Getestet wird vor allem unter Zorin OS 18 / Ubuntu 24.04 (Wayland und X11). Eine Windows-Version gibt es als experimentelles portables Programm. +Getestet wird vor allem unter Zorin OS 18 / Ubuntu 24.04 (Wayland und X11). Eine Windows-Version gibt es als experimentelles portables Programm, eine Android-Version als APK. Die Oberfläche gibt es auf Deutsch und Englisch; ink-notes folgt der Systemsprache, umstellen lässt sie sich im ☰-Menü unter „Sprache / Language“. @@ -87,7 +87,7 @@ Die Oberfläche gibt es auf Deutsch und Englisch; ink-notes folgt der Systemspra ## Installation -Pakete gibt es unter [Releases](https://gitea.pansi.eu/harald/ink-notes/releases) als `.deb`, `.AppImage` und für Windows als `.exe` (x86_64). `` steht für die Versionsnummer, z. B. `0.11.0`. +Pakete gibt es unter [Releases](https://gitea.pansi.eu/harald/ink-notes/releases) als `.deb`, `.AppImage`, für Windows als `.exe` (x86_64) und für Android als `.apk` (arm64). `` steht für die Versionsnummer, z. B. `0.11.0`. ```bash # Debian-Paket (Zorin OS 18 / Ubuntu 24.04) @@ -104,6 +104,8 @@ Hinweise: **Windows (experimentell):** `ink-notes__x86_64.exe` ist ein portables Programm für Windows 10/11 – ohne Installation einfach starten (Windows SmartScreen fragt evtl. einmal nach, da das Programm nicht signiert ist). Stifteingabe mit Druck läuft über Windows Ink (noch nicht auf echter Hardware getestet). Notizbücher und Einstellungen liegen in `%APPDATA%\ink-notes`. Updates ersetzen die `.exe` an Ort und Stelle und gelten ab dem nächsten Start. +**Android:** `ink-notes__arm64.apk` läuft ab Android 8 (64-Bit-ARM). Auf dem Gerät herunterladen und öffnen; Android fragt einmal, ob Browser oder Dateimanager Apps installieren dürfen. Der Stift wird von Fingern unterschieden (Stifttasten, Radierer-Ende, Handballen-Erkennung), Import und „Bild einfügen“ nutzen den System-Dateidialog, und Exporte landen in `Download/ink-notes` (ab Android 10). Notizbücher liegen im eigenen Speicher der App und werden beim Deinstallieren gelöscht – vorher exportieren, was bleiben soll. Ein Update in der App gibt es nicht: die neue APK über die alte installieren, die Notizbücher bleiben erhalten. + --- ## Tastenkürzel @@ -156,7 +158,7 @@ Die CI prüft zusätzlich `cargo fmt --check` und `cargo clippy --all-targets -- Andere Systeme: - **Windows** wird unter Linux übersetzt: `scripts/package-windows.sh` (braucht `gcc-mingw-w64-x86-64`); die Tests laufen mit `wine` als Runner (`CARGO_TARGET_X86_64_PC_WINDOWS_GNU_RUNNER=wine cargo test --target x86_64-pc-windows-gnu`). -- **Android** (experimentell, Issue #42): `scripts/package-android.sh` baut `target/ink-notes__arm64.apk` ohne Gradle. Nötig sind das Android-SDK (build-tools, Plattform 34; `ANDROID_HOME`, Standard `~/android-sdk`) und das NDK; der Signierschlüssel kommt aus `ANDROID_KEYSTORE`, `ANDROID_KEYSTORE_PASS` und `ANDROID_KEY_ALIAS`, sonst wird der Debug-Schlüssel verwendet. Ohne SDK auf dem Rechner baut `scripts/build-apk-container.sh` sie in einem Container (podman oder docker, `packaging/android/Containerfile`); `scripts/setup-android-sdk.sh` installiert die festen SDK-/NDK-Versionen. Die CI baut die APK als Workflow-Artefakt (noch nicht im Release); ein Release-Schlüssel gehört in die Secrets `ANDROID_KEYSTORE_B64` (`base64 -w0 release.keystore`), `ANDROID_KEYSTORE_PASS` und `ANDROID_KEY_ALIAS`. Installieren mit `adb install -r target/ink-notes__arm64.apk`, Log-Ausgaben mit `adb logcat -s ink-notes`. Der Stift wird von Fingern unterschieden (Stifttasten, Radierer-Ende, Handballen-Erkennung), Textfelder öffnen die Bildschirmtastatur, Import und „Bild einfügen“ nutzen den System-Dateidialog, und Exporte landen in `Download/ink-notes` (ab Android 10). Tastaturtext und Dateidialog kommen von der kleinen Java-Activity `packaging/android/java/…/InkActivity.java` (zum Bauen ist ein JDK nötig). +- **Android** (Issue #42): `scripts/package-android.sh` baut `target/ink-notes__arm64.apk` ohne Gradle. Nötig sind das Android-SDK (build-tools, Plattform 34; `ANDROID_HOME`, Standard `~/android-sdk`) und das NDK; der Signierschlüssel kommt aus `ANDROID_KEYSTORE`, `ANDROID_KEYSTORE_PASS` und `ANDROID_KEY_ALIAS`, sonst wird der Debug-Schlüssel verwendet. Ohne SDK auf dem Rechner baut `scripts/build-apk-container.sh` sie in einem Container (podman oder docker, `packaging/android/Containerfile`); `scripts/setup-android-sdk.sh` installiert die festen SDK-/NDK-Versionen. Der CI-Job `android` baut die APK zu jedem Release und legt sie ins Release und in `SHA256SUMS.txt`; der Release-Schlüssel gehört in die Secrets `ANDROID_KEYSTORE_B64` (`base64 -w0 release.keystore`), `ANDROID_KEYSTORE_PASS` und `ANDROID_KEY_ALIAS`. Installieren mit `adb install -r target/ink-notes__arm64.apk`, Log-Ausgaben mit `adb logcat -s ink-notes`. Der Stift wird von Fingern unterschieden (Stifttasten, Radierer-Ende, Handballen-Erkennung), Textfelder öffnen die Bildschirmtastatur, Import und „Bild einfügen“ nutzen den System-Dateidialog, und Exporte landen in `Download/ink-notes` (ab Android 10). Tastaturtext und Dateidialog kommen von der kleinen Java-Activity `packaging/android/java/…/InkActivity.java` (zum Bauen ist ein JDK nötig). ### Projektstruktur diff --git a/README.md b/README.md index 9f2ae65..d7f9b1d 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ ink-notes stores handwriting as vectors, can recognize shapes, imports PDFs for annotation as well as Xournal++, Rnote and Saber notebooks, inserts images and text boxes, and exports everything again as PDF, PNG or SVG. Saving happens automatically in the background. -It is mainly tested on Zorin OS 18 / Ubuntu 24.04 (Wayland and X11). A Windows version is available as an experimental portable program. +It is mainly tested on Zorin OS 18 / Ubuntu 24.04 (Wayland and X11). A Windows version is available as an experimental portable program, and an Android version as an APK. The interface is available in English and German; ink-notes follows the system language, and you can switch it in the ☰ menu under "Sprache / Language". @@ -87,7 +87,7 @@ The interface is available in English and German; ink-notes follows the system l ## Installation -Packages are available under [Releases](https://gitea.pansi.eu/harald/ink-notes/releases) as `.deb`, `.AppImage` and for Windows as `.exe` (x86_64). `` stands for the version number, e.g. `0.30.2`. +Packages are available under [Releases](https://gitea.pansi.eu/harald/ink-notes/releases) as `.deb`, `.AppImage`, for Windows as `.exe` (x86_64) and for Android as `.apk` (arm64). `` stands for the version number, e.g. `0.30.2`. ```bash # Debian package (Zorin OS 18 / Ubuntu 24.04) @@ -104,6 +104,8 @@ Notes: **Windows (experimental):** `ink-notes__x86_64.exe` is a portable program for Windows 10/11 – no installation, just start it (Windows SmartScreen may ask once, as the program is not signed). Pen input with pressure uses Windows Ink (not yet tested on real hardware). Notebooks and settings are stored in `%APPDATA%\ink-notes`. Updates replace the `.exe` in place and take effect at the next start. +**Android:** `ink-notes__arm64.apk` runs on Android 8 and newer (64-bit ARM). Download it on the device and open it; Android asks once to allow installing apps from the browser or file manager. The pen is told apart from fingers (pen buttons, eraser end, palm rejection), import and inserting images use the system file dialog, and exports are saved to `Download/ink-notes` (Android 10 and newer). Notebooks are stored in the app's own storage and are removed when the app is uninstalled – export what you want to keep first. There is no in-app update: install the new APK over the old one, the notebooks stay. + --- ## Keyboard shortcuts @@ -156,7 +158,7 @@ CI additionally checks `cargo fmt --check` and `cargo clippy --all-targets -- -D Other systems: - **Windows** is cross-compiled on Linux: `scripts/package-windows.sh` (needs `gcc-mingw-w64-x86-64`); the tests run with `wine` as runner (`CARGO_TARGET_X86_64_PC_WINDOWS_GNU_RUNNER=wine cargo test --target x86_64-pc-windows-gnu`). -- **Android** (experimental, Issue #42): `scripts/package-android.sh` builds `target/ink-notes__arm64.apk` without Gradle. It needs the Android SDK (build-tools, platform 34; `ANDROID_HOME`, default `~/android-sdk`) and the NDK; the signing key comes from `ANDROID_KEYSTORE`, `ANDROID_KEYSTORE_PASS` and `ANDROID_KEY_ALIAS`, otherwise the debug key is used. Without SDK on the host, `scripts/build-apk-container.sh` builds it in a container (podman or docker, `packaging/android/Containerfile`); `scripts/setup-android-sdk.sh` installs the fixed SDK/NDK versions. The CI builds the APK as a workflow artifact (not yet part of the release); a release key goes into the secrets `ANDROID_KEYSTORE_B64` (`base64 -w0 release.keystore`), `ANDROID_KEYSTORE_PASS` and `ANDROID_KEY_ALIAS`. Install with `adb install -r target/ink-notes__arm64.apk`, log output with `adb logcat -s ink-notes`. The pen is told apart from fingers (pen buttons, eraser end, palm rejection), text fields open the soft keyboard, import and inserting images use the system file dialog, and exports are saved to `Download/ink-notes` (Android 10 and newer). The small Java activity `packaging/android/java/…/InkActivity.java` (needs a JDK to build) provides keyboard text and the file dialog. +- **Android** (Issue #42): `scripts/package-android.sh` builds `target/ink-notes__arm64.apk` without Gradle. It needs the Android SDK (build-tools, platform 34; `ANDROID_HOME`, default `~/android-sdk`) and the NDK; the signing key comes from `ANDROID_KEYSTORE`, `ANDROID_KEYSTORE_PASS` and `ANDROID_KEY_ALIAS`, otherwise the debug key is used. Without SDK on the host, `scripts/build-apk-container.sh` builds it in a container (podman or docker, `packaging/android/Containerfile`); `scripts/setup-android-sdk.sh` installs the fixed SDK/NDK versions. The CI job `android` builds the APK for every release and adds it to the release and to `SHA256SUMS.txt`; the release key goes into the secrets `ANDROID_KEYSTORE_B64` (`base64 -w0 release.keystore`), `ANDROID_KEYSTORE_PASS` and `ANDROID_KEY_ALIAS`. Install with `adb install -r target/ink-notes__arm64.apk`, log output with `adb logcat -s ink-notes`. The pen is told apart from fingers (pen buttons, eraser end, palm rejection), text fields open the soft keyboard, import and inserting images use the system file dialog, and exports are saved to `Download/ink-notes` (Android 10 and newer). The small Java activity `packaging/android/java/…/InkActivity.java` (needs a JDK to build) provides keyboard text and the file dialog. New code comments and commit messages are written in English; older code and history still contain German. diff --git a/scripts/build-release.sh b/scripts/build-release.sh index f63ac87..2ef66af 100755 --- a/scripts/build-release.sh +++ b/scripts/build-release.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash # ============================================================================== # Haupt-Release-Build-Skript für ink-notes (Zorin OS 18 / Linux) -# Erstellt .deb, .AppImage, Windows-.exe, SHA256-Prüfsummen und deren Minisign-Signatur in target/ +# Erstellt .deb, .AppImage, Windows-.exe, (mit vorhandener APK) SHA256-Prüfsummen und deren Minisign-Signatur in target/ # ============================================================================== set -euo pipefail @@ -14,6 +14,8 @@ VERSION=$(grep -m1 '^version = ' Cargo.toml | cut -d '"' -f2) DEB_NAME="ink-notes_${VERSION}_amd64.deb" APPIMAGE_NAME="ink-notes_${VERSION}_x86_64.AppImage" EXE_NAME="ink-notes_${VERSION}_x86_64.exe" +# Built separately (scripts/package-android.sh, CI job android); listed in the checksums if present +APK_NAME="ink-notes_${VERSION}_arm64.apk" CHECKSUM_FILE="SHA256SUMS.txt" echo "======================================================================" @@ -32,7 +34,14 @@ echo "======================================================================" # 4. Checksums berechnen echo "=== Berechne SHA256-Prüfsummen in target/${CHECKSUM_FILE} ===" cd "${ROOT_DIR}/target" -sha256sum "${DEB_NAME}" "${APPIMAGE_NAME}" "${EXE_NAME}" > "${CHECKSUM_FILE}" +RELEASE_FILES=("${DEB_NAME}" "${APPIMAGE_NAME}" "${EXE_NAME}") +if [ -f "${APK_NAME}" ]; then + RELEASE_FILES+=("${APK_NAME}") +elif [ "${INK_NOTES_REQUIRE_APK:-0}" = "1" ]; then + echo "FEHLER: target/${APK_NAME} fehlt (INK_NOTES_REQUIRE_APK=1)." + exit 1 +fi +sha256sum "${RELEASE_FILES[@]}" > "${CHECKSUM_FILE}" # 5. Prüfsummen signieren (Pflicht für In-App-Updates) # Signiert wird mit rsign2 (minisign-kompatibles Format): Der Schlüssel wurde mit @@ -77,7 +86,7 @@ fi echo "======================================================================" echo "Release-Artefakte für v${VERSION} erfolgreich erstellt:" echo "======================================================================" -ls -lh "${DEB_NAME}" "${APPIMAGE_NAME}" "${EXE_NAME}" "${CHECKSUM_FILE}" +ls -lh "${RELEASE_FILES[@]}" "${CHECKSUM_FILE}" if [ -f "${SIGNATURE_FILE}" ]; then ls -lh "${SIGNATURE_FILE}"; fi echo "" echo "Inhalt von target/${CHECKSUM_FILE}:" diff --git a/scripts/publish-gitea-release.sh b/scripts/publish-gitea-release.sh index a522ae8..c2e2bc7 100755 --- a/scripts/publish-gitea-release.sh +++ b/scripts/publish-gitea-release.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash # ============================================================================== # Veröffentlicht ein Release auf dem Gitea-Server (gitea.pansi.eu) -# Lädt .deb, .AppImage, .exe, SHA256SUMS.txt und SHA256SUMS.txt.minisig idempotent als Release-Assets hoch. +# Lädt .deb, .AppImage, .exe, .apk (falls gebaut), SHA256SUMS.txt und SHA256SUMS.txt.minisig idempotent als Release-Assets hoch. # ============================================================================== set -euo pipefail @@ -33,6 +33,7 @@ RELEASE_TITLE="ink-notes ${TAG_NAME}" DEB_FILE="${ROOT_DIR}/target/ink-notes_${VERSION}_amd64.deb" APPIMAGE_FILE="${ROOT_DIR}/target/ink-notes_${VERSION}_x86_64.AppImage" EXE_FILE="${ROOT_DIR}/target/ink-notes_${VERSION}_x86_64.exe" +APK_FILE="${ROOT_DIR}/target/ink-notes_${VERSION}_arm64.apk" CHECKSUMS_FILE="${ROOT_DIR}/target/SHA256SUMS.txt" SIGNATURE_FILE="${CHECKSUMS_FILE}.minisig" TEMPLATE_FILE="${ROOT_DIR}/packaging/release-notes.md.tmpl" @@ -238,6 +239,9 @@ except Exception: upload_asset "${DEB_FILE}" upload_asset "${APPIMAGE_FILE}" upload_asset "${EXE_FILE}" +if [ -f "${APK_FILE}" ]; then + upload_asset "${APK_FILE}" +fi upload_asset "${CHECKSUMS_FILE}" upload_asset "${SIGNATURE_FILE}"