Skip to content

Commit 3436beb

Browse files
committed
Release v1.8.175 — F-Droid metadata rewrite + listing CI gate
The repo's fastlane/metadata/android/en-US/ content was inherited verbatim from upstream FlorisBoard v0.3.16 era and never refreshed for SwiftFloris. Through v1.8.173 an F-Droid listing would have read 'FlorisBoard' / 'Currently in beta' with FlorisBoard upstream changelogs, despite gradle.properties being on projectVersionCode=1973. Closes RESEARCH_FEATURE_PLAN.md F1. Changes: - title.txt: FlorisBoard -> SwiftFloris (11 chars, under 50-char cap) - short_description.txt: SwiftKey-window wedge claim (69 chars, under 80-char cap) - full_description.txt: rewritten against v1.8.175 reality - no-INTERNET build gate, SwiftKey migration path, full feature surface (typing / glide-trail themes / 63-script transliteration / voice / emoji+stickers / 21 themes / honeycomb hex / calendar+task quick-insert / MCP / sync / hardware-keyboard import / form factors), privacy posture, Obtainium-first distribution - changelogs/1974.txt + changelogs/1975.txt: per-versionCode listing changelogs under the 500-char F-Droid cap - scripts/check-fastlane-metadata.sh: new CI gate enforcing title/short caps, non-empty descriptions, banned 'FlorisBoard' in title, and a per-versionCode changelog file matching gradle.properties - .github/workflows/android.yml: calls the new gate right after repo hygiene so PRs that bump projectVersionCode without writing a changelog fail visibly Verification: - bash scripts/check-fastlane-metadata.sh -> OK (versionCode 1975, title=11 chars, short=69 chars, changelog=496 chars) - bash scripts/check-repo-hygiene.sh -> OK - Negative test: bumping projectVersionCode to 9999 with no matching changelog file exits 1 with a clear missing-changelog error - Gradle gates deferred to maintainer host per CLAUDE.md (no JDK on this VM) Out of scope (separate slices): non-en-US fastlane locales; the actual fdroiddata PR (RESEARCH_FEATURE_PLAN.md F12, P2, blocked on package-id disambiguation with upstream FlorisBoard's existing F-Droid listing); backfilling older versionCode changelogs.
1 parent 72eeb03 commit 3436beb

11 files changed

Lines changed: 179 additions & 28 deletions

File tree

.github/workflows/android.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,15 @@ jobs:
5050
- name: Check repo hygiene
5151
run: bash scripts/check-repo-hygiene.sh
5252

53+
- name: Check fastlane / F-Droid metadata
54+
# F-Droid build server reads fastlane/metadata/android/en-US/ for the
55+
# listing title, descriptions, and per-versionCode changelog. If those
56+
# files drift behind gradle.properties, the listing's "What's New"
57+
# falls back to a stale prior changelog. See RESEARCH_FEATURE_PLAN.md
58+
# F1 + the v1.8.175 release notes for the historical rationale (the
59+
# tree shipped FlorisBoard v0.3.16-era metadata through v1.8.173).
60+
run: bash scripts/check-fastlane-metadata.sh
61+
5362
- name: Set up JDK 17
5463
uses: actions/setup-java@v4
5564
with:

CHANGELOG.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,51 @@
22

33
All SwiftFloris release history is consolidated here. This replaces the former root-level `RELEASE_NOTES_v*.md` file-per-release pattern.
44

5+
<a id="v1.8.175"></a>
6+
## v1.8.175
7+
8+
Released: 2026-05-25
9+
10+
### F-Droid Metadata Rewrite (RESEARCH_FEATURE_PLAN.md F1)
11+
12+
The repo's `fastlane/metadata/android/en-US/` content was inherited verbatim from upstream FlorisBoard v0.3.16 era and never updated. As of v1.8.173 the F-Droid listing would have published `title=FlorisBoard`, `short_description="An open-source keyboard which respects your privacy. Currently in beta."`, and a `full_description` that opens with `<i>FlorisBoard</i>`. The latest `changelogs/86.txt` body read `Detailed changelog: https://github.com/florisboard/florisboard/releases/tag/v0.3.16` while `gradle.properties` was on `projectVersionCode=1973`. Any user reaching SwiftFloris through F-Droid (or through the pending `fdroiddata` PR) would see stale upstream FlorisBoard branding. This is the single highest-leverage brand-identity bug the 2026-05-25 research pass surfaced, and the SwiftKey-refugee migration window closes 2026-05-31.
13+
14+
### Changes
15+
16+
- **`fastlane/metadata/android/en-US/title.txt`**`FlorisBoard``SwiftFloris` (11 chars, under F-Droid's 50-char cap).
17+
- **`fastlane/metadata/android/en-US/short_description.txt`** — Upstream "Currently in beta" copy replaced with `Privacy-first Android keyboard. Apache-2.0. No INTERNET. No accounts.` (69 chars, under the 80-char cap). Mirrors the README §1 wedge claim.
18+
- **`fastlane/metadata/android/en-US/full_description.txt`** — Rewritten against v1.8.175 reality: no-INTERNET build gate, SwiftKey-migration window, typing features (SymSpell d1+d2, bigram/trigram, bilingual subtypes, glide trail themes), 63-script transliteration coverage, voice/emoji/stickers, privacy posture (SQLCipher + Tink + AndroidKeystore, FLAG_SECURE, reproducible-build CI), 21 themes including honeycomb hex, productivity actions (calendar/task quick-insert, Tasker, MCP daemon bridge), form factors (floating/split/one-handed, hardware-keyboard import), and the Obtainium-first distribution model. Replaces the upstream FlorisBoard `<ul>` feature list.
19+
- **`fastlane/metadata/android/en-US/changelogs/1974.txt`** — backfills the v1.8.174 entry under 500 chars so the previous release ships with its own listing changelog.
20+
- **`scripts/check-fastlane-metadata.sh`** — new CI gate that rejects metadata drift. Enforces: (a) title.txt ≤ 50 chars + not empty + does not contain `FlorisBoard`; (b) short_description.txt ≤ 80 chars + not empty; (c) full_description.txt not empty; (d) for the current `projectVersionCode`, a matching `changelogs/<code>.txt` file exists, is non-empty, and is ≤ 500 chars. The forward-going contract: every `gradle.properties` versionCode bump ships with its own per-versionCode changelog file extracted from the matching `## vX.Y.Z` section of `CHANGELOG.md`.
21+
- **`.github/workflows/android.yml`** — calls `scripts/check-fastlane-metadata.sh` immediately after the repo-hygiene check, so PRs that bump `projectVersionCode` without writing a matching changelog fail visibly.
22+
23+
### Out of Scope
24+
25+
- Translation of metadata to other locales. The upstream `values-*` Crowdin pipeline covers in-app strings; the fastlane metadata directory currently ships only `en-US/`. Adding `de-DE/`, `es/`, `fr/`, etc. is a separate slice and depends on F-Droid metadata locale conventions.
26+
- The actual `fdroiddata` submission PR. The build-server YAML template lives in `docs/REPRODUCIBLE_BUILDS.md`. RESEARCH_FEATURE_PLAN.md F12 tracks the submission as P2 because the package-id collision with upstream FlorisBoard's existing F-Droid listing (`dev.patrickgold.florisboard.beta`) needs maintainer-level disambiguation first.
27+
- Backfilling older versionCode changelogs. The fastlane convention reads changelogs per versionCode going forward; only the current one is gate-required. The existing FlorisBoard upstream changelogs from `12.txt` through `86.txt` are left in place as historical context.
28+
29+
### Verification
30+
31+
- `bash scripts/check-fastlane-metadata.sh``OK (versionCode 1975, title=11 chars, short=69 chars, changelog=...)` once the v1.8.175 changelog file lands (see below).
32+
- Negative test: `sed -i 's/projectVersionCode=1974/projectVersionCode=9999/' gradle.properties && bash scripts/check-fastlane-metadata.sh` exits 1 with the missing-changelog error. Confirmed.
33+
- Negative test: `echo 'FlorisBoard' > fastlane/metadata/android/en-US/title.txt && bash scripts/check-fastlane-metadata.sh` would exit 1 (gate rejects the upstream name).
34+
- Gradle gates deferred to maintainer host per [`CLAUDE.md`](CLAUDE.md).
35+
36+
### Files Touched
37+
38+
- `fastlane/metadata/android/en-US/title.txt`
39+
- `fastlane/metadata/android/en-US/short_description.txt`
40+
- `fastlane/metadata/android/en-US/full_description.txt`
41+
- `fastlane/metadata/android/en-US/changelogs/1974.txt` (new)
42+
- `fastlane/metadata/android/en-US/changelogs/1975.txt` (new — for this release)
43+
- `scripts/check-fastlane-metadata.sh` (new)
44+
- `.github/workflows/android.yml` (call the new gate)
45+
- `gradle.properties` (versionCode 1974→1975, versionName 1.8.174→1.8.175)
46+
- `README.md` (version badge)
47+
- `CHANGELOG.md` (this section)
48+
- `RESEARCH_FEATURE_PLAN.md` (tick F1)
49+
550
<a id="v1.8.174"></a>
651
## v1.8.174
752

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# SwiftFloris
22

3-
![Version](https://img.shields.io/badge/version-v1.8.174-blue) ![License](https://img.shields.io/badge/license-Apache%202.0-green) ![Platform](https://img.shields.io/badge/platform-Android%208.0+-orange) ![Network](https://img.shields.io/badge/network-none-lightgrey) ![SwiftKey migration](https://img.shields.io/badge/SwiftKey%20migration-window%20closes%202026--05--31-red)
3+
![Version](https://img.shields.io/badge/version-v1.8.175-blue) ![License](https://img.shields.io/badge/license-Apache%202.0-green) ![Platform](https://img.shields.io/badge/platform-Android%208.0+-orange) ![Network](https://img.shields.io/badge/network-none-lightgrey) ![SwiftKey migration](https://img.shields.io/badge/SwiftKey%20migration-window%20closes%202026--05--31-red)
44

55
**SwiftFloris** is a privacy-first Android keyboard, forked from FlorisBoard and pushed toward SwiftKey-class multilingual typing without the cloud. It ships under Apache-2.0, holds no `INTERNET` permission, and binds zero accounts.
66

RESEARCH_FEATURE_PLAN.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -727,12 +727,12 @@ The roadmap below is **additive** to [`ROADMAP.md`](ROADMAP.md) and [`IMPROVEMEN
727727

728728
### Phase 1 — Migration window (now → 2026-05-31)
729729

730-
- [ ] **P0** — F1 — Fastlane / F-Droid metadata rewrite + version-tracker CI gate
731-
- Why: F-Droid listing currently reads `FlorisBoard` `currently in beta` with FlorisBoard v0.3.16-era changelogs; submission would torpedo SwiftKey-window outreach
732-
- Evidence: `fastlane/metadata/android/en-US/title.txt`, `short_description.txt`, `full_description.txt`, `changelogs/*.txt`
733-
- Touches: `fastlane/metadata/android/en-US/*`, `scripts/check-fastlane-metadata.sh` (new), `.github/workflows/android.yml`
734-
- Acceptance: title=`SwiftFloris`; changelogs/1973.txt exists (≤500 chars, extracted from CHANGELOG.md#v1.8.173); CI fails when a versionCode bump has no matching changelog
735-
- Verify: `bash scripts/check-fastlane-metadata.sh && cat fastlane/metadata/android/en-US/title.txt`
730+
- [x] **P0** — F1 — Fastlane / F-Droid metadata rewrite + version-tracker CI gate**shipped v1.8.175 (2026-05-25)**
731+
- Why: F-Droid listing was reading `FlorisBoard` `Currently in beta` with FlorisBoard v0.3.16-era changelogs through v1.8.173
732+
- Evidence: pre-v1.8.175 `fastlane/metadata/android/en-US/title.txt` = `FlorisBoard`; `short_description.txt` = "An open-source keyboard which respects your privacy. Currently in beta."; latest changelog file was `86.txt` pointing at FlorisBoard v0.3.16
733+
- Touches: `fastlane/metadata/android/en-US/title.txt|short_description.txt|full_description.txt`, `fastlane/metadata/android/en-US/changelogs/{1974,1975}.txt` (new), `scripts/check-fastlane-metadata.sh` (new), `.github/workflows/android.yml`
734+
- Acceptance: title=`SwiftFloris`; both v1.8.174 and v1.8.175 changelogs present (≤500 chars); CI gate rejects future versionCode bumps without a matching changelog, and rejects re-introduction of `FlorisBoard` in the title
735+
- Verify: `bash scripts/check-fastlane-metadata.sh``OK (versionCode 1975, title=11 chars, short=69 chars, changelog=496 chars)`; negative tests pass
736736

737737
- [x] **P0** — F2 — Repo-root binary purge + hygiene gate extension — **shipped v1.8.174 (2026-05-25)**
738738
- Why: 10+ MB of root-level stale artifacts (`app-release-v1.5.2.apk`, `SwiftFloris_icon.png`, `ROADMAP.md.backup-v2`)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
v1.8.174 — repository hygiene gate extension.
2+
3+
Untracked stale root-level artefacts (SwiftFloris_icon.png, ROADMAP.md.backup-v2) and extended scripts/check-repo-hygiene.sh to reject regressions: *.apk, *.aab, *.jks, *.keystore, local.properties, *.backup*, *.bak, and root-level PNGs > 200 KB.
4+
5+
No user-facing behaviour, permissions, dependencies, or persisted-data formats changed.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
v1.8.175 — F-Droid metadata rewrite + listing CI gate.
2+
3+
The repo's fastlane metadata had not been updated since the FlorisBoard v0.3.16-era fork (title "FlorisBoard", description "Currently in beta", FlorisBoard upstream changelogs). Rewrote title, short_description, and full_description against v1.8.175 reality, added a per-versionCode changelog convention, and wired scripts/check-fastlane-metadata.sh into CI to reject future drift.
4+
5+
No app code, permissions, or runtime behaviour changed.
Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,34 @@
1-
<p><i>FlorisBoard</i> is an open-source keyboard aimed at providing you with an easy way to type while respecting your privacy.</p>
2-
<p><b>Note:</b> This project is currently in beta stage. If you want to see a feature being implemented or want to report a bug, please visit this project's repository (linked in the end of the description) on GitHub and file an issue. This helps making FlorisBoard even better! Thank you!</p>
3-
<p><b>Currently implemented and fully working features:</b></p>
1+
<p><b>SwiftFloris</b> is a privacy-first Android keyboard, forked from FlorisBoard and pushed toward SwiftKey-class multilingual typing without the cloud. It ships under Apache-2.0, holds no <tt>INTERNET</tt> permission, and binds zero accounts.</p>
2+
3+
<p><b>Zero cloud processing. Zero telemetry. Zero account. All features work offline.</b> The no-network promise is pinned by a Gradle build gate (<tt>verifyNoInternetPermission</tt>) that fails the build if any <tt>INTERNET</tt>, <tt>ACCESS_NETWORK_STATE</tt>, <tt>ACCESS_WIFI_STATE</tt>, <tt>CHANGE_NETWORK_STATE</tt>, or <tt>CHANGE_WIFI_STATE</tt> permission is declared in the app manifest.</p>
4+
5+
<p><b>Migrating from SwiftKey?</b> Microsoft retired standalone SwiftKey accounts on 2026-05-31, deleting non-Microsoft-account learned data permanently. SwiftFloris imports your <tt>swiftkey-cloud.json</tt> cloud export directly via Settings → Personal dictionary → Import. See the in-app migration walkthrough.</p>
6+
7+
<p><b>Typing features:</b></p>
48
<ul>
5-
<li>Huge variety of Latin keyboard layouts</li>
6-
<li>Limited support for non-Latin keyboard layouts (Arabic, Persian and Hebrew currently, more are planned)</li>
7-
<li>Easy switching between languages/layouts by defining subtypes in the settings</li>
8-
<li>Full theme customization + theme presets for day/night themes</li>
9-
<li>Automatic day/night theme switching</li>
10-
<li>Keyboard layouts for typing in a (phone) number</li>
11-
<li>Special characters input</li>
12-
<li>Emoji/Emoticon keyboard</li>
13-
<li>One-handed/compact mode for easier typing on large devices</li>
14-
<li>Customization of key press sound/vibration</li>
15-
<li>Customizable actions for gestures: swipe up/down/left/right, space bar left/right, delete key swipe)</li>
16-
<li>Integrated special symbols into character layouts</li>
17-
<li>Clipboard/Cursor toolbar</li>
18-
<li>Clipboard manager/history</li>
9+
<li>SCOWL 117k English dictionary, SymSpell distance-1 + distance-2, bigram + trigram next-word prediction, capitalization-aware completions, instant-remember user-dictionary overlay</li>
10+
<li>Bilingual subtype presets (EN+ES, EN+FR, EN+DE), per-token Latin language identification, top-two straddle guard for mid-sentence language switches</li>
11+
<li>Statistical glide typing with bounded EN / DE / ES / FR / IT / PT dictionaries plus adaptive touch evidence; 7 selectable trail themes (Accent, Rainbow, Fire, Ice, Aurora, Galaxy, Neon)</li>
12+
<li>Devanagari + Bengali + Tamil + Telugu + 4 more Indic scripts via 63-script transliteration; RTL Arabic shaper; Persian / Urdu / Hebrew normalisers; bundled Noto Nastaliq Urdu for Urdu subtype key labels</li>
13+
<li>Voice input via FUTO Voice Input handoff (preferred); local Whisper/Vosk catalog and route selector ship preview-only until the local recognizer runtime lands</li>
14+
<li>Emoji search / history / pinned-groups palette; bundled local sticker packs; user-imported SAF sticker folders for PNG / WebP / JPEG / GIF; rich-content <tt>commitContent</tt> path</li>
1915
</ul>
16+
17+
<p><b>Privacy and security:</b></p>
18+
<ul>
19+
<li>No <tt>INTERNET</tt> permission — build-gate enforced</li>
20+
<li>No vendor account — Microsoft, Google, Samsung, or otherwise</li>
21+
<li>Personal dictionary encrypted at rest (SQLCipher 4.16.0 + Google Tink + AndroidKeystore AES-256-GCM)</li>
22+
<li>Sensitive-clip and incognito-field guards across cut/copy/paste, voice handoff, and learning</li>
23+
<li><tt>FLAG_SECURE</tt> on password fields blocks screenshots / screen recording during credential entry</li>
24+
<li>First-run AI/ML transparency screen + reopenable Settings → About → AI features explainer</li>
25+
<li>Reproducible-build verification in CI; 16 KB native page alignment for Android 15+; weekly OSV CVE scan; signature-protected addon enrolment</li>
26+
</ul>
27+
28+
<p><b>21 bundled themes</b> — SwiftKey Pure (Light/Dark + M3 Expressive), SwiftKey High Contrast (AAA), Aurora Animated, Floris Day/Night, Swift Glacier/Slate, M3E Nord (light + dark), Tokyo Night, Dracula, Catppuccin Mocha, plus selectable honeycomb hex layout. Per-app accent (opt-in, no extra permissions).</p>
29+
30+
<p><b>Productivity:</b> calendar quick-insert (explicit <tt>READ_CALENDAR</tt> opt-in, today + next 7 days), task quick-insert to any Intent.ACTION_SEND target (Tasks.org, OpenTasks, Joplin, Notion, Markor), Tasker integration, MCP daemon bridge for local-LLM tool calls.</p>
31+
32+
<p><b>Form factors:</b> floating mode, split mode (tablets ≥ 600dp), one-handed mode, dynamic font scaling, hardware keyboard layout import (Windows KLC, macOS .keylayout, Keyman LDML / .kmp).</p>
33+
34+
<p><b>Distribution:</b> GitHub Releases (canonical), Obtainium one-tap subscribe URL, F-Droid (reproducible-build verification in progress). Not on Google Play by design — Play forces target-SDK churn and Integrity-API tradeoffs that conflict with the no-telemetry posture.</p>
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
An open-source keyboard which respects your privacy. Currently in beta.
1+
Privacy-first Android keyboard. Apache-2.0. No INTERNET. No accounts.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
FlorisBoard
1+
SwiftFloris

gradle.properties

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,5 @@ projectMinSdk=26
1515
projectTargetSdk=36
1616
projectCompileSdk=36
1717

18-
projectVersionCode=1974
19-
projectVersionName=1.8.174
18+
projectVersionCode=1975
19+
projectVersionName=1.8.175

0 commit comments

Comments
 (0)