docs: refresh cycle 15 research queue #337
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: SwiftFloris CI | |
| on: | |
| push: | |
| branches: [ main, master ] | |
| paths-ignore: | |
| - ".github/ISSUE_TEMPLATE/**" | |
| - ".github/PULL_REQUEST_TEMPLATE.md" | |
| - ".github/FUNDING.yml" | |
| - ".dockerignore" | |
| - ".editorconfig" | |
| - "fastlane/**" | |
| - "AI_POLICY.md" | |
| - "CODE_OF_CONDUCT.md" | |
| - "CONTRIBUTING.md" | |
| - "LICENSE" | |
| - "README.md" | |
| - "ROADMAP.md" | |
| - "RELEASE_NOTES_*.md" | |
| pull_request: | |
| branches: [ main, master ] | |
| # ROADMAP §6 N6.1 — gate PRs on tests + lint + build (was: assembleDebug only). | |
| # verifyNoInternetPermission (N7.1) runs as a preBuild dependency on every variant, | |
| # so it is implicitly re-checked by both lintDebug and assembleDebug below; we also | |
| # call it explicitly first so a contract violation fails fast before slower tasks. | |
| # Lock the default GITHUB_TOKEN to read-only. Build jobs that only need to | |
| # upload artefacts and report status do not need write access to issues, | |
| # pull-requests, packages, or contents. A future supply-chain compromise of a | |
| # transitive action dependency cannot abuse the token to push commits or | |
| # comment on issues. | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: ci-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| build: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 | |
| with: | |
| submodules: recursive | |
| - uses: gradle/actions/wrapper-validation@48b5f213c81028ace310571dc5ec0fbbca0b2947 # v4 | |
| - name: Check root crash/replay logs | |
| run: bash scripts/check-no-root-crash-logs.sh | |
| - name: Check repo hygiene | |
| run: bash scripts/check-repo-hygiene.sh | |
| - name: Check fastlane / F-Droid metadata | |
| # F-Droid build server reads fastlane/metadata/android/en-US/ for the | |
| # listing title, descriptions, and per-versionCode changelog. If those | |
| # files drift behind gradle.properties, the listing's "What's New" | |
| # falls back to a stale prior changelog. See RESEARCH_FEATURE_PLAN.md | |
| # F1 + the v1.8.175 release notes for the historical rationale (the | |
| # tree shipped FlorisBoard v0.3.16-era metadata through v1.8.173). | |
| run: bash scripts/check-fastlane-metadata.sh | |
| - name: Set up JDK 17 | |
| uses: actions/setup-java@c1e323688fd81a25caa38c78aa6df2d33d3e20d9 # v4 | |
| with: | |
| java-version: 17 | |
| distribution: temurin | |
| - name: Set up CMake and Ninja | |
| uses: lukka/get-cmake@ea004816823209b8d1211e47b216185caee12cc5 # v4.0.2 | |
| - name: Cache Gradle | |
| uses: gradle/actions/setup-gradle@48b5f213c81028ace310571dc5ec0fbbca0b2947 # v4 | |
| - name: Verify no-network contract (N7.1) | |
| run: ./gradlew :app:verifyNoInternetPermission | |
| # ROADMAP §0 N12.5b — explicit verifyDataExtractionRules step. The | |
| # gate also fires transitively from preBuild (registered in | |
| # app/build.gradle.kts), but calling it directly here makes the | |
| # green/red signal legible in the workflow run summary and pins the | |
| # data_extraction_rules.xml excludes (personal-dictionary + clipboard | |
| # encrypted-stores) against accidental rewrite. | |
| - name: Verify data-extraction rules | |
| run: ./gradlew :app:verifyDataExtractionRules | |
| - name: Unit tests | |
| run: ./gradlew :app:testDebugUnitTest | |
| # ROADMAP §6 N14.1 — Roborazzi visual-regression verify (1.55.0 line ships | |
| # the AGP-9 plugin, so the plugin alias is now applied in app/build.gradle.kts). | |
| # `verifyRoborazziDebug` re-runs every Roborazzi-annotated JUnit test and | |
| # diff-compares the captured PNG against the baseline under | |
| # `app/src/test/snapshots/`. If a snapshot drifts beyond the default | |
| # change threshold (0.01), the task fails the PR. Baseline captures land | |
| # separately via `recordRoborazziDebug` on a maintainer push (run locally | |
| # and commit the resulting PNGs). | |
| - name: Roborazzi visual-regression verify (N14.1) | |
| run: ./gradlew :app:verifyRoborazziDebug | |
| - name: Lint (debug + baseline drift) | |
| run: bash scripts/run-lint-debug-with-baseline-check.sh | |
| - name: Build debug APK | |
| run: ./gradlew :app:assembleDebug | |
| # ROADMAP §7 Next-12.4 — 16 KB memory-page alignment guard. Per Google | |
| # Play's Nov 1 2025 cutoff [STD-A15-16KB], every native .so shipped on | |
| # a target-Android-15+ APK must be 16 KB ELF-segment aligned. SwiftFloris | |
| # currently ships zero native libs in :app (native runtimes for optional | |
| # capabilities live in out-of-tree signed addon APKs per the AddonContract | |
| # enrolment path), so this check is a forward-looking guard: as soon as | |
| # Next-2 (whisper.cpp), | |
| # N1.2 (CleverKeys ONNX), L1 (LiteRT-LM), or L7 (MCP bridge) bring native | |
| # code back in, the gate catches a 4 KB regression at PR time instead of | |
| # at Play upload time. If no .so files exist in the APK the check is a | |
| # no-op (zipalign exits 0 on a debug APK with no native libs). | |
| - name: 16 KB native-library alignment guard | |
| run: | | |
| set -euo pipefail | |
| ANDROID_HOME="${ANDROID_HOME:-/usr/local/lib/android/sdk}" | |
| BUILD_TOOLS=$(ls -1 "$ANDROID_HOME/build-tools" | sort -V | tail -1) | |
| ZIPALIGN="$ANDROID_HOME/build-tools/$BUILD_TOOLS/zipalign" | |
| APK="app/build/outputs/apk/debug/app-debug.apk" | |
| if [ ! -f "$APK" ]; then | |
| echo "No APK produced; skipping." | |
| exit 0 | |
| fi | |
| # zipalign -P 16 = require 16 KB alignment for *.so entries (page-size | |
| # in KB units). Exits non-zero if any .so is misaligned. | |
| "$ZIPALIGN" -c -P 16 -v 4 "$APK" || { | |
| echo "::error::APK contains a native library aligned to less than 16 KB. Rebuild against NDK r28+ (see ROADMAP §7 Next-12.4 + [STD-A15-16KB])." | |
| exit 1 | |
| } | |
| echo "All shipped native libraries (if any) are 16 KB aligned." | |
| - name: Upload debug APK | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 | |
| with: | |
| name: app-debug.apk | |
| path: app/build/outputs/apk/debug/app-debug.apk | |
| - name: Upload lint report | |
| if: always() | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 | |
| with: | |
| name: lint-debug-report | |
| path: | | |
| app/build/reports/lint-results-debug.html | |
| app/build/reports/lint-results-debug.xml | |
| app/build/reports/lintDebug-console.log | |
| - name: Upload unit-test report | |
| if: always() | |
| uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 | |
| with: | |
| name: unit-test-report | |
| path: app/build/reports/tests/testDebugUnitTest/ |