Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
193 commits
Select commit Hold shift + click to select a range
40677e7
fix: make nine-key pinyin paths directly selectable
Slacker-LLC Sep 28, 2026
77e81b1
style: distinguish selected nine-key pinyin path
Slacker-LLC Sep 28, 2026
b826a61
feat: expand candidates with a downward strip gesture
Slacker-LLC Sep 28, 2026
e596ef6
style: deepen default keyboard surface hierarchy
Slacker-LLC Sep 28, 2026
166c749
style: restore restrained key surface depth
Slacker-LLC Sep 28, 2026
f54facf
feat: add space-drag cursor movement
Slacker-LLC Sep 28, 2026
2f1fcb5
feat: route horizontal space gestures to cursor mode
Slacker-LLC Sep 28, 2026
ac193a3
feat: wire space cursor gestures to editor movement
Slacker-LLC Sep 28, 2026
3380f54
feat: expose Rime candidate deletion through JNI
Slacker-LLC Sep 28, 2026
1729928
feat: delete learned Rime candidates by absolute index
Slacker-LLC Sep 28, 2026
e60e793
feat: delete learned Rime candidates off the IME thread
Slacker-LLC Sep 28, 2026
b6a5e0d
feat: forget fallback learned phrases
Slacker-LLC Sep 28, 2026
d2b8274
feat: expose long-press candidate management
Slacker-LLC Sep 28, 2026
3464002
feat: wire candidate long-press management
Slacker-LLC Sep 28, 2026
81728a4
feat: delete learned candidates on long press
Slacker-LLC Sep 28, 2026
59163a7
feat: add conservative adjacent-key pinyin correction
Slacker-LLC Sep 28, 2026
7b19f8d
feat: merge adjacent-key corrections behind normal pinyin
Slacker-LLC Sep 28, 2026
eb5e877
feat: keep a safe one-shot snapshot for clear undo
Slacker-LLC Sep 28, 2026
05f171c
feat: add guarded downward restore after clear gesture
Slacker-LLC Sep 28, 2026
932652c
feat: wire guarded clear restore into backspace gesture
Slacker-LLC Sep 28, 2026
5e61529
a11y: describe backspace clear restore gesture
Slacker-LLC Sep 28, 2026
71655e6
feat: restore last cleared editor snapshot
Slacker-LLC Sep 28, 2026
b501ec7
perf: keep adjacent-key correction off full candidate pipeline
Slacker-LLC Sep 28, 2026
5a0ab2a
fix: invalidate clear restore on all text mutations
Slacker-LLC Sep 28, 2026
81b7ba1
perf: retain nine-key rail state and theme dynamic choices
Slacker-LLC Sep 28, 2026
79b092f
style: theme dynamic nine-key rail content
Slacker-LLC Sep 28, 2026
466c5e6
fix: retain typo recovery when native pinyin is sparse
Slacker-LLC Sep 28, 2026
53eee81
feat: forget removed candidate personalization
Slacker-LLC Sep 28, 2026
1155b0c
fix: remove deleted candidates from personalization bias
Slacker-LLC Sep 28, 2026
ca5f496
feat: persist one-hand and keyboard height preferences
Slacker-LLC Sep 28, 2026
bcf8090
feat: make keyboard row geometry height-adjustable
Slacker-LLC Sep 28, 2026
4a8ef4b
feat: apply one-hand width and adjustable keyboard height
Slacker-LLC Sep 28, 2026
8e67250
feat: expose one-hand and keyboard height controls
Slacker-LLC Sep 28, 2026
3168ebe
feat: wire keyboard layout preferences into live IME
Slacker-LLC Sep 28, 2026
ba881be
fix: derive one-hand geometry from narrowed keyboard width
Slacker-LLC Sep 28, 2026
14b8641
fix: scale total IME height with row height preference
Slacker-LLC Sep 28, 2026
a892016
feat: add stable input-code editor id
Slacker-LLC Sep 28, 2026
4200693
feat: add backward-compatible quick phrase input codes
Slacker-LLC Sep 28, 2026
43564cb
feat: edit quick phrase input codes
Slacker-LLC Sep 28, 2026
f1dcca4
feat: pass quick phrase input code to editor
Slacker-LLC Sep 28, 2026
a175985
feat: surface quick phrases from user-defined input codes
Slacker-LLC Sep 28, 2026
7ec21f3
a11y: expose quick phrase input codes
Slacker-LLC Sep 28, 2026
3d08418
fix: keep quick phrases out of Rime deletion flow
Slacker-LLC Sep 28, 2026
4f949fc
fix: rebuild keys after height changes made inside settings
Slacker-LLC Sep 28, 2026
a0c1627
perf: cache parsed quick phrases on candidate hot path
Slacker-LLC Sep 28, 2026
9c33065
feat: notify hosts of keyboard layout preference changes
Slacker-LLC Sep 28, 2026
0b9dc76
feat: sync layout preferences from settings activity
Slacker-LLC Sep 28, 2026
f2abe54
feat: persist floating keyboard size and opacity
Slacker-LLC Sep 28, 2026
ca3d10e
feat: apply floating keyboard size and window opacity
Slacker-LLC Sep 28, 2026
c96e0c2
feat: expose floating keyboard size and opacity controls
Slacker-LLC Sep 28, 2026
7c8011a
feat: wire floating style preferences through keyboard settings
Slacker-LLC Sep 28, 2026
afd448b
feat: reapply live floating window style changes
Slacker-LLC Sep 28, 2026
28c10da
feat: sync floating style from settings activity
Slacker-LLC Sep 28, 2026
50acdab
fix: preserve floating window edge margin on small displays
Slacker-LLC Sep 28, 2026
9eee552
style: add shared semantic color blending primitive
Slacker-LLC Sep 28, 2026
c51d87a
style: establish semantic surface hierarchy for light and dark modes
Slacker-LLC Sep 28, 2026
d45230f
style: unify selected pressed and layered surface states
Slacker-LLC Sep 28, 2026
99b06f1
style: derive consistent primary pressed state
Slacker-LLC Sep 28, 2026
c42e9a0
style: remove ad hoc dim states from themed controls
Slacker-LLC Sep 28, 2026
a876bd8
style: finish semantic pressed states in theme applier
Slacker-LLC Sep 28, 2026
7e79723
style: align candidate emphasis and disabled state with semantic palette
Slacker-LLC Sep 28, 2026
5b6b245
style: give key popups elevated bordered surfaces
Slacker-LLC Sep 28, 2026
79c79cb
style: reinforce selected chips without relying on color alone
Slacker-LLC Sep 28, 2026
0687946
style: reinforce selected nine-key path without relying on color alone
Slacker-LLC Sep 28, 2026
655aa7f
style: tag settings text by semantic hierarchy
Slacker-LLC Sep 28, 2026
eb742ec
style: add hairline card boundaries and text hierarchy
Slacker-LLC Sep 28, 2026
080b64c
style: unify toolbar and settings icon color roles
Slacker-LLC Sep 28, 2026
18cdc3b
style: remove hardcoded switch knob color
Slacker-LLC Sep 28, 2026
1e3b73b
style: theme switch knob from track contrast
Slacker-LLC Sep 28, 2026
573228e
style: keep docked keyboard deck on one background plane
Slacker-LLC Sep 28, 2026
78d6619
style: restore keyboard deck color when leaving floating mode
Slacker-LLC Sep 28, 2026
d692f22
style: derive restrained destructive color roles
Slacker-LLC Sep 28, 2026
a4489e7
style: distinguish destructive actions with restrained semantic color
Slacker-LLC Sep 28, 2026
872f435
fix: correct IME gesture and input path regressions
Slacker-LLC Sep 28, 2026
694fbba
test: cover space cursor drag gesture
Slacker-LLC Sep 28, 2026
d5491e5
fix: preserve voice tail after release
Slacker-LLC Sep 29, 2026
6bcfd2c
chore: log sherpa final fallback
Slacker-LLC Sep 29, 2026
87abd86
fix: add voice cancel hysteresis
Slacker-LLC Sep 29, 2026
8e510b2
docs: align voice hold timing with Android
Slacker-LLC Sep 29, 2026
8b3df93
feat: define canonical IME visual tokens
Slacker-LLC Sep 29, 2026
b2417eb
style: align light setup colors with IME tokens
Slacker-LLC Sep 29, 2026
ec976d3
style: align dark setup colors with IME tokens
Slacker-LLC Sep 29, 2026
e6d57ae
refactor: remove unused keyboard themes
Slacker-LLC Sep 29, 2026
2cddaf3
fix: fall back from legacy theme values
Slacker-LLC Sep 29, 2026
712911e
test: cover legacy theme fallback
Slacker-LLC Sep 29, 2026
f8e1dac
test: align theme selector with IOS-only policy
Slacker-LLC Sep 29, 2026
3541be8
style: normalize typography in ImeKeyView
Slacker-LLC Sep 29, 2026
e509314
style: normalize typography in SymbolManagerActivity
Slacker-LLC Sep 29, 2026
5cc8db5
style: normalize typography in ImeTopZone
Slacker-LLC Sep 29, 2026
a647f12
style: normalize typography in SetupUi
Slacker-LLC Sep 29, 2026
56b266d
style: normalize typography in VoicePanelView
Slacker-LLC Sep 29, 2026
4edfd0d
style: normalize typography in QuickPhraseEditActivity
Slacker-LLC Sep 29, 2026
b6af835
style: normalize typography in KeyPopupController
Slacker-LLC Sep 29, 2026
90073bc
style: normalize typography in SettingsPanelController
Slacker-LLC Sep 29, 2026
9b86053
style: normalize typography in SymbolRailRenderer
Slacker-LLC Sep 29, 2026
a3f15c0
style: normalize typography in EmojiCellFactory
Slacker-LLC Sep 29, 2026
4860a1f
style: normalize typography in BackspaceKeyFactory
Slacker-LLC Sep 29, 2026
3dc8228
style: normalize typography in CandidateBarController
Slacker-LLC Sep 29, 2026
fe37165
style: normalize typography in ImeKeyboardView
Slacker-LLC Sep 29, 2026
8293687
style: normalize typography in NineKeySymbolRailController
Slacker-LLC Sep 29, 2026
80d3e31
refactor: move accent palette into design tokens
Slacker-LLC Sep 29, 2026
aaad8c0
feat: centralize accent palette colors
Slacker-LLC Sep 29, 2026
0e44918
refactor: make setup colors token-driven
Slacker-LLC Sep 29, 2026
e054363
style: normalize ic_mic.xml vector size
Slacker-LLC Sep 29, 2026
b5505ba
style: normalize ic_edit.xml vector size
Slacker-LLC Sep 29, 2026
7a7b958
style: normalize ic_game.xml vector size
Slacker-LLC Sep 29, 2026
d4ffcfc
style: normalize ic_shift.xml vector size
Slacker-LLC Sep 29, 2026
1d82937
style: normalize ic_emoji.xml vector size
Slacker-LLC Sep 29, 2026
4c5f402
style: normalize ic_symbols.xml vector size
Slacker-LLC Sep 29, 2026
77e7279
style: normalize ic_settings.xml vector size
Slacker-LLC Sep 29, 2026
d56274c
style: normalize ic_keyboard.xml vector size
Slacker-LLC Sep 29, 2026
3fa2aee
style: normalize ic_caps_lock.xml vector size
Slacker-LLC Sep 29, 2026
c697af3
style: normalize ic_backspace.xml vector size
Slacker-LLC Sep 29, 2026
ff02711
style: normalize ic_clipboard.xml vector size
Slacker-LLC Sep 29, 2026
eed916d
style: normalize ic_handwriting.xml vector size
Slacker-LLC Sep 29, 2026
3c7b4ae
style: standardize ic_more.xml icon
Slacker-LLC Sep 29, 2026
188de31
style: standardize ic_grid.xml icon
Slacker-LLC Sep 29, 2026
43e5f09
style: standardize ic_keyboard_hide.xml icon
Slacker-LLC Sep 29, 2026
21663bd
style: add ic_chevron_down.xml vector icon
Slacker-LLC Sep 29, 2026
d62dc2a
style: add ic_stop.xml vector icon
Slacker-LLC Sep 29, 2026
295ac49
style: add ic_check.xml vector icon
Slacker-LLC Sep 29, 2026
6af6c90
style: add ic_close.xml vector icon
Slacker-LLC Sep 29, 2026
04a04d4
style: replace candidate glyphs with vector icons
Slacker-LLC Sep 29, 2026
f472018
refactor: use vector expand control
Slacker-LLC Sep 29, 2026
7bf6750
fix: tint candidate vector controls
Slacker-LLC Sep 29, 2026
8cb09e0
style: theme candidate vector controls
Slacker-LLC Sep 29, 2026
5ab8d38
style: replace voice glyph with vector icon
Slacker-LLC Sep 29, 2026
b6cf273
refactor: drive voice state with vector resources
Slacker-LLC Sep 29, 2026
e5bf032
style: tint voice vector icon with accent contrast
Slacker-LLC Sep 29, 2026
6d4c916
style: replace text-editor glyph arrows with labels
Slacker-LLC Sep 29, 2026
77e7414
style: remove decorative backspace glyph
Slacker-LLC Sep 29, 2026
d566403
style: replace settings glyphs with vector icons
Slacker-LLC Sep 29, 2026
76239d1
style: use vector check for completed setup step
Slacker-LLC Sep 29, 2026
17319b9
feat: add XML typography tokens
Slacker-LLC Sep 29, 2026
300bc67
style: tokenize setup typography and chevrons
Slacker-LLC Sep 29, 2026
a168d52
fix: update setup chevrons to ImageView
Slacker-LLC Sep 29, 2026
24d2aad
style: tokenize voice control typography
Slacker-LLC Sep 29, 2026
1debd56
style: tokenize settings row typography
Slacker-LLC Sep 29, 2026
ecc44d0
style: tokenize panel action typography
Slacker-LLC Sep 29, 2026
2556433
fix: rotate candidate chevron instead of swapping glyphs
Slacker-LLC Sep 29, 2026
f4169d7
style: tokenize voice language typography
Slacker-LLC Sep 29, 2026
c54c002
style: tokenize text-editor typography
Slacker-LLC Sep 29, 2026
073ca9c
style: tokenize panel key typography
Slacker-LLC Sep 29, 2026
2f61db7
fix: raise light secondary text contrast
Slacker-LLC Sep 29, 2026
bf44b1d
style: sync light secondary text color
Slacker-LLC Sep 29, 2026
2d2235f
test: lock canonical visual tokens
Slacker-LLC Sep 29, 2026
306cdc3
test: forbid raw production colors
Slacker-LLC Sep 29, 2026
142dca7
test: forbid raw production text sizes
Slacker-LLC Sep 29, 2026
b9fa201
test: enforce visual contrast budget
Slacker-LLC Sep 29, 2026
51b58dd
test: forbid decorative unicode icons
Slacker-LLC Sep 29, 2026
85ba4ac
test: enforce vector icon contract
Slacker-LLC Sep 29, 2026
f32fd67
style: rename primary setup background
Slacker-LLC Sep 29, 2026
ab63371
style: rename muted setup background
Slacker-LLC Sep 29, 2026
08e22e4
style: use renamed setup backgrounds
Slacker-LLC Sep 29, 2026
9b559ae
chore: remove legacy bg_setup_primary_pill.xml name
Slacker-LLC Sep 29, 2026
7edc4d0
chore: remove legacy bg_setup_muted_pill.xml name
Slacker-LLC Sep 29, 2026
a1c0655
refactor: remove duplicate setup shape API
Slacker-LLC Sep 29, 2026
6b42db4
refactor: remove legacy setup pill helpers
Slacker-LLC Sep 29, 2026
e376b9e
fix: preserve keyboard secondary color while meeting page contrast
Slacker-LLC Sep 29, 2026
33198a5
style: sync light accent pressed token
Slacker-LLC Sep 29, 2026
313fff0
style: sync dark accent pressed token
Slacker-LLC Sep 29, 2026
0259809
docs: record visual language implementation decisions
Slacker-LLC Sep 29, 2026
173d4db
fix: remove keyboard key dead zones
Slacker-LLC Sep 29, 2026
414871c
style: replace key shadows with bottom edge
Slacker-LLC Sep 29, 2026
5301e89
style: unify keyboard typography and digit hints
Slacker-LLC Sep 29, 2026
ffdf7cb
perf: reuse instant key preview popup
Slacker-LLC Sep 29, 2026
f122e20
feat: add timed clear undo affordance
Slacker-LLC Sep 29, 2026
794a183
fix: gate candidate deletion to learned words
Slacker-LLC Sep 29, 2026
6929cb0
fix: stabilize and instrument nine-key input
Slacker-LLC Sep 29, 2026
956b088
feat: add adaptive openIME brand assets
Slacker-LLC Sep 29, 2026
8c3f5d6
feat: rebuild setup flow and unify activity headers
Slacker-LLC Sep 29, 2026
ce1ee90
feat: add local user data import and export
Slacker-LLC Sep 29, 2026
bff922a
build: add signed arm64 release pipeline
Slacker-LLC Sep 29, 2026
dd72096
docs: align distribution branding and notices
Slacker-LLC Sep 29, 2026
c2fcc34
docs: complete release compliance and distribution notes
Slacker-LLC Sep 29, 2026
c94ff21
docs: fix social preview release path
Slacker-LLC Sep 29, 2026
6524fbe
fix: marshal imported settings refresh to main thread
Slacker-LLC Sep 29, 2026
4186d5f
fix: validate imported Rime dictionary names
Slacker-LLC Sep 29, 2026
a597a55
fix: reject unsafe native user dictionary names
Slacker-LLC Sep 29, 2026
4db4546
test: cover unsafe Rime dictionary names
Slacker-LLC Sep 29, 2026
3c4aa4c
fix: make Rime data archive fail closed
Slacker-LLC Sep 29, 2026
d09325e
feat: switch local voice runtime to INT8 streaming Paraformer
Slacker-LLC Sep 29, 2026
ef1db2d
chore: replace voice model with INT8 Paraformer
Slacker-LLC Sep 29, 2026
33e8bfa
chore: remove completed voice model migration workflow
Slacker-LLC Sep 29, 2026
8b4cb12
fix: restore archive build after data export changes
Slacker-LLC Sep 29, 2026
0d5704d
fix: clear remaining CI regressions
Slacker-LLC Sep 29, 2026
0004c58
fix: clear lint indentation regression
Slacker-LLC Sep 29, 2026
a7360f5
fix: complete English UI resources
Slacker-LLC Sep 29, 2026
69ca70a
ci: reuse prebuilt APKs for compatibility tests
Slacker-LLC Sep 29, 2026
37ddd63
ci: harden prebuilt APK reuse
Slacker-LLC Sep 29, 2026
e268945
ci: fix instrumentation shell and enable KVM
Slacker-LLC Sep 29, 2026
5e4817e
ci: run instrumentation in one bash process
Slacker-LLC Sep 29, 2026
7f324ee
chore: remove completed voice model migration script
Slacker-LLC Sep 29, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 52 additions & 41 deletions .github/workflows/android.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,16 +68,31 @@ jobs:
run: chmod +x gradlew

- name: Run unit tests, lint, and assemble
run: ./gradlew :app:testDebugUnitTest :app:lintDebug :app:assembleDebug --no-daemon --console=plain
shell: bash
run: |
set +e
./gradlew :app:testDebugUnitTest :app:lintDebug :app:assembleDebug :app:assembleDebugAndroidTest --build-cache --parallel --no-daemon --console=plain
status=$?
if [[ $status -ne 0 && -f app/build/reports/lint-results-debug.txt ]]; then
echo "::group::Full Android Lint report"
cat app/build/reports/lint-results-debug.txt
echo "::endgroup::"
fi
exit $status

- name: Upload debug APK
- name: Upload test APKs
uses: actions/upload-artifact@v7
with:
name: openIME-debug
path: app/build/outputs/apk/debug/app-debug.apk
name: openIME-test-apks
path: |
app/build/outputs/apk/debug/app-debug.apk
app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk
if-no-files-found: error
compression-level: 0
retention-days: 1

compatibility:
needs: verify
name: Compatibility API ${{ matrix.api-level }}
runs-on: ubuntu-latest
timeout-minutes: 45
Expand All @@ -87,47 +102,43 @@ jobs:
api-level: [29, 31]

steps:
- name: Checkout source and LFS files
uses: actions/checkout@v7
with:
lfs: true

- name: Set up JDK 17
uses: actions/setup-java@v6
with:
distribution: temurin
java-version: '17'
cache: gradle
- name: Enable KVM group perms
shell: bash
run: |
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
sudo udevadm control --reload-rules
sudo udevadm trigger --name-match=kvm

- name: Set up Android SDK
uses: android-actions/setup-android@v4
with:
packages: 'platform-tools'

- name: Install Android build components
shell: bash
run: |
sdkmanager "platforms;android-36" \
"build-tools;35.0.0" \
"ndk;27.0.12077973" \
"cmake;3.22.1"
- name: Download prebuilt test APKs
uses: actions/download-artifact@v7
with:
name: openIME-test-apks
path: ci-apks

- name: Verify LFS objects
- name: Prepare instrumentation runner
shell: bash
run: |
git lfs checkout
if grep -RIl --exclude-dir=.git "version https://git-lfs.github.com/spec/v1" app/libs app/src/main/assets/models; then
echo "A Git LFS pointer was left unresolved" >&2
exit 1
fi

- name: Fetch pinned librime dependencies
shell: bash
run: bash scripts/fetch_rime_deps.sh

- name: Ensure Gradle wrapper is executable
shell: bash
run: chmod +x gradlew
cat > ci-run-instrumentation.sh <<'EOF'
#!/usr/bin/env bash
set -euo pipefail
api_level="$1"
mkdir -p ci-reports
app_apk="$(find ci-apks -type f -name 'app-debug.apk' -print -quit)"
test_apk="$(find ci-apks -type f -name 'app-debug-androidTest.apk' -print -quit)"
test -n "$app_apk"
test -n "$test_apk"
adb install -r "$app_apk"
adb install -r "$test_apk"
adb shell am instrument -w -r \
llc.slacker.openime.test/androidx.test.runner.AndroidJUnitRunner \
| tee "ci-reports/instrumentation-api-${api_level}.txt"
EOF
chmod +x ci-run-instrumentation.sh

- name: Run compatibility instrumentation
uses: reactivecircus/android-emulator-runner@v2
Expand All @@ -138,14 +149,14 @@ jobs:
profile: pixel_2
disable-animations: true
emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
script: ./gradlew :app:connectedDebugAndroidTest --no-daemon --console=plain
script: bash ci-run-instrumentation.sh ${{ matrix.api-level }}

- name: Upload compatibility test reports
- name: Upload compatibility test report
if: always()
uses: actions/upload-artifact@v7
with:
name: compatibility-api-${{ matrix.api-level }}
path: |
app/build/reports/androidTests/connected
app/build/outputs/androidTest-results/connected
path: ci-reports
if-no-files-found: warn
compression-level: 0
retention-days: 7
179 changes: 179 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
name: Android Release

on:
push:
tags:
- 'v*'

permissions:
contents: write

jobs:
release:
name: Build signed arm64 release
runs-on: ubuntu-latest
timeout-minutes: 60

steps:
- name: Checkout source and LFS files
uses: actions/checkout@v7
with:
lfs: true

- name: Set up JDK 17
uses: actions/setup-java@v6
with:
distribution: temurin
java-version: '17'
cache: gradle

- name: Set up Android SDK
uses: android-actions/setup-android@v4
with:
packages: 'platform-tools'

- name: Install Android build components
shell: bash
run: |
sdkmanager "platforms;android-36" \
"build-tools;35.0.0" \
"ndk;27.0.12077973" \
"cmake;3.22.1"

- name: Verify LFS objects
shell: bash
run: |
git lfs checkout
if grep -RIl --exclude-dir=.git "version https://git-lfs.github.com/spec/v1" app/libs app/src/main/assets/models; then
echo "A Git LFS pointer was left unresolved" >&2
exit 1
fi

- name: Fetch pinned librime dependencies
shell: bash
run: bash scripts/fetch_rime_deps.sh

- name: Ensure Gradle wrapper is executable
shell: bash
run: chmod +x gradlew

- name: Validate signing secrets
shell: bash
env:
OPENIME_KEYSTORE_B64: ${{ secrets.OPENIME_KEYSTORE_B64 }}
OPENIME_KEYSTORE_PASSWORD: ${{ secrets.OPENIME_KEYSTORE_PASSWORD }}
OPENIME_KEY_ALIAS: ${{ secrets.OPENIME_KEY_ALIAS }}
OPENIME_KEY_PASSWORD: ${{ secrets.OPENIME_KEY_PASSWORD }}
run: |
for name in \
OPENIME_KEYSTORE_B64 \
OPENIME_KEYSTORE_PASSWORD \
OPENIME_KEY_ALIAS \
OPENIME_KEY_PASSWORD
do
if [[ -z "${!name}" ]]; then
echo "Missing required release signing secret: ${name}" >&2
exit 1
fi
done

- name: Decode release keystore
shell: bash
env:
OPENIME_KEYSTORE_B64: ${{ secrets.OPENIME_KEYSTORE_B64 }}
run: |
printf '%s' "$OPENIME_KEYSTORE_B64" \
| base64 --decode \
> "$RUNNER_TEMP/openime-release.jks"
chmod 600 "$RUNNER_TEMP/openime-release.jks"

- name: Run tests, lint, and release build
shell: bash
env:
OPENIME_KEYSTORE_PATH: ${{ runner.temp }}/openime-release.jks
OPENIME_KEYSTORE_PASSWORD: ${{ secrets.OPENIME_KEYSTORE_PASSWORD }}
OPENIME_KEY_ALIAS: ${{ secrets.OPENIME_KEY_ALIAS }}
OPENIME_KEY_PASSWORD: ${{ secrets.OPENIME_KEY_PASSWORD }}
run: |
./gradlew \
:app:testDebugUnitTest \
:app:lintRelease \
:app:assembleRelease \
--no-daemon \
--console=plain

- name: Verify signed arm64 artifact
id: artifact
shell: bash
run: |
APK="$(find app/build/outputs/apk/release -maxdepth 1 -type f -name 'app-release*.apk' | head -n 1)"
if [[ -z "$APK" || ! -f "$APK" ]]; then
echo "Release APK not found" >&2
exit 1
fi

"$ANDROID_HOME/build-tools/35.0.0/apksigner" verify --verbose "$APK"

mapfile -t ABIS < <(
unzip -Z1 "$APK" \
| awk -F/ '/^lib\/[^/]+\/[^/]+$/ {print $2}' \
| sort -u
)
if [[ "${#ABIS[@]}" -ne 1 || "${ABIS[0]}" != "arm64-v8a" ]]; then
echo "Release APK must contain only arm64-v8a; found: ${ABIS[*]:-none}" >&2
exit 1
fi

VERSION_NAME="$(
sed -n 's/^[[:space:]]*versionName = "\(.*\)"/\1/p' app/build.gradle.kts \
| head -n 1
)"
if [[ -z "$VERSION_NAME" ]]; then
echo "Unable to read versionName" >&2
exit 1
fi
if [[ "$GITHUB_REF_NAME" != "v$VERSION_NAME" ]]; then
echo "Tag $GITHUB_REF_NAME does not match versionName $VERSION_NAME" >&2
exit 1
fi

OUTPUT="openIME-v${VERSION_NAME}-arm64-release.apk"
cp "$APK" "$OUTPUT"
sha256sum "$OUTPUT" > SHA256SUMS.txt
cp THIRD_PARTY_NOTICES.md THIRD_PARTY_NOTICES.release.md
echo "apk=$OUTPUT" >> "$GITHUB_OUTPUT"
echo "version=$VERSION_NAME" >> "$GITHUB_OUTPUT"

- name: Create release notes
shell: bash
run: |
cat > RELEASE_NOTES.md <<'EOF'
## 更新内容
- 此版本包含标签所对应提交中的 openIME 功能、稳定性与界面更新。

## 已知问题
- 首次安装时,完整 Rime 词典可能需要完成首次部署后才达到稳定候选表现。
- 发布 APK 仅包含 arm64-v8a;模拟器继续使用 Debug 构建。

## 校验方式
下载 APK 后,在同一目录执行:

```bash
sha256sum -c SHA256SUMS.txt
```

校验通过后再安装。
EOF

- name: Publish GitHub Release
shell: bash
env:
GH_TOKEN: ${{ github.token }}
run: |
gh release create "$GITHUB_REF_NAME" \
"${{ steps.artifact.outputs.apk }}" \
SHA256SUMS.txt \
THIRD_PARTY_NOTICES.release.md \
--verify-tag \
--title "openIME $GITHUB_REF_NAME" \
--notes-file RELEASE_NOTES.md
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ artifacts/

# Local screenshots and UI dumps kept outside the source tree
*.png
!docs/images/
!docs/images/*.png
*.xml
!app/src/**/*.xml
!app/src/main/assets/
Expand Down
Loading
Loading