diff --git a/.github/workflows/api-verification.yml b/.github/workflows/api-verification.yml index 8bdddcec6c..68499a67d2 100644 --- a/.github/workflows/api-verification.yml +++ b/.github/workflows/api-verification.yml @@ -25,11 +25,11 @@ jobs: steps: - name: Restore artifacts - uses: actions/cache/restore@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4.0.0 + uses: actions/cache/restore@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 with: path: | artifacts - key: artifacts-key-${GITHUB_RUN_ID} + key: artifacts-key-${{ github.event.workflow_run.id }} restore-keys: artifacts-key- - name: Read environment diff --git a/.github/workflows/deb-packaging.yml b/.github/workflows/deb-packaging.yml index 7c05528878..1876be35b7 100644 --- a/.github/workflows/deb-packaging.yml +++ b/.github/workflows/deb-packaging.yml @@ -315,11 +315,11 @@ jobs: echo "GIT_USER=${{ github.event.client_payload.user }}" >> artifacts/env - name: Cache artifacts - uses: actions/cache/save@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4.0.0 + uses: actions/cache/save@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 with: path: | artifacts - key: artifacts-key-${GITHUB_RUN_ID} + key: artifacts-key-${{ github.run_id }} # We intentionally ignore the results of binary_packages_unreleased set_status: diff --git a/HISTORY.md b/HISTORY.md index 046aeb014e..c6c3b88505 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,20 @@ # Keyman Version History +## 18.0.44 alpha 2024-05-24 + +* fix(linux): Pass artifacts key to API verification GHA (#11517) +* fix(web): properly pass test-runner verbose-logging flag (#11509) +* chore(developer): add context/key-test (#11512) +* fix(android/engine): Ignore updating invalid selections (#11510) +* docs(common): update min emscripten version in docs to 3.1.46 (#11530) +* fix(linux): Properly use and pass run_id (#11533) + +## 18.0.43 alpha 2024-05-24 + +* fix(android): Revert Sentry version for FV Android (#11522) +* chore(windows): remove schedule task clean up introduced in 15.0 Alpha (#11521) +* fix(windows): add FirstVoices Keyboards build to Windows release build (#11524) + ## 18.0.42 alpha 2024-05-23 * chore(web): conversion of Web's browser-integration auto-tests for @web/test-runner use (#11455) diff --git a/VERSION.md b/VERSION.md index 65ef51766b..175c4213bd 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -18.0.43 \ No newline at end of file +18.0.45 \ No newline at end of file diff --git a/android/KMEA/app/src/main/java/com/keyman/engine/KMKeyboard.java b/android/KMEA/app/src/main/java/com/keyman/engine/KMKeyboard.java index bc7dfc5cc6..d45937fe73 100644 --- a/android/KMEA/app/src/main/java/com/keyman/engine/KMKeyboard.java +++ b/android/KMEA/app/src/main/java/com/keyman/engine/KMKeyboard.java @@ -194,10 +194,16 @@ final class KMKeyboard extends WebView { int selMin = icText.selectionStart, selMax = icText.selectionEnd; + int textLength = rawText.length(); + if (selMin < 0 || selMax < 0) { // There is no selection or cursor // Reference https://developer.android.com/reference/android/text/Selection#getSelectionEnd(java.lang.CharSequence) return false; + } else if (selMin > textLength || selMax > textLength) { + // Selection is past end of existing text -- should not be possible but we + // are seeing it happen; #11506 + return false; } if (selMin > selMax) { diff --git a/core/tests/unit/ldml/meson.build b/core/tests/unit/ldml/meson.build index 7379341fdf..f67178dbe9 100644 --- a/core/tests/unit/ldml/meson.build +++ b/core/tests/unit/ldml/meson.build @@ -37,14 +37,14 @@ endif # Build ldml test executable -keyboard_build_path = join_paths(meson.current_build_dir(),'keyboards') +keyboard_build_path = meson.current_build_dir() / 'keyboards' if cpp_compiler.get_id() == 'emscripten' - tests_flags = ['--embed-file', join_paths(meson.current_build_dir(),'keyboards','@')] - tests_flags += ['--embed-file', join_paths(meson.current_build_dir(),'invalid-keyboards','@')] - tests_flags += ['--embed-file', join_paths(meson.current_build_dir(),'nodeversions.json') + '@nodeversions.json'] - tests_flags += ['--embed-file', join_paths(meson.current_build_dir(),'package.json') + '@package.json'] - tests_flags += ['--embed-file', join_paths(meson.current_build_dir(),'Blocks.txt') + '@Blocks.txt'] + tests_flags = ['--embed-file', meson.current_build_dir() / 'keyboards' / '@'] + tests_flags += ['--embed-file', meson.current_build_dir() / 'invalid-keyboards' / '@'] + tests_flags += ['--embed-file', meson.current_build_dir() / 'nodeversions.json' + '@nodeversions.json'] + tests_flags += ['--embed-file', meson.current_build_dir() / 'package.json' + '@package.json'] + tests_flags += ['--embed-file', meson.current_build_dir() / 'Blocks.txt' + '@Blocks.txt'] test_path = '/' test_unicode_path = '/' invalid_test_path = '/' @@ -53,9 +53,9 @@ if cpp_compiler.get_id() == 'emscripten' '-sEXPORTED_RUNTIME_METHODS=[\'UTF8ToString\']'] else tests_flags = [] - test_path = join_paths(meson.current_build_dir(),'keyboards') - test_unicode_path = join_paths(meson.current_build_dir()) - invalid_test_path = join_paths(meson.current_build_dir(),'invalid-keyboards') + test_path = meson.current_build_dir() / 'keyboards' + test_unicode_path = meson.current_build_dir() + invalid_test_path = meson.current_build_dir() / 'invalid-keyboards' endif # copy package.json into build dir for test use @@ -71,7 +71,7 @@ configure_file( ) configure_file( - command: [node, join_paths(meson.current_source_dir(), 'write_node_versions.js'),'@OUTPUT@'], + command: [node, meson.current_source_dir() / 'write_node_versions.js','@OUTPUT@'], output: 'nodeversions.json', ) @@ -120,18 +120,18 @@ if cpp_compiler.get_id() == 'emscripten' normalization_tests_flags += ['-lnodefs.js', '-sEXPORTED_RUNTIME_METHODS=[\'UTF8ToString\']'] endif -tc = executable('test_context_normalization', +test_context_normalization = executable('test_context_normalization', ['test_context_normalization.cpp', common_test_files], cpp_args: defns + warns, include_directories: [inc, libsrc, '../../../../developer/src/ext/json'], link_args: links + normalization_tests_flags, dependencies: [icu_uc, icu_i18n], objects: lib.extract_all_objects(recursive: false)) -test('test_context_normalization', tc, suite: 'ldml') +test('test_context_normalization', test_context_normalization, suite: 'ldml') # Build and run additional test_unicode test -u = executable('test_unicode', 'test_unicode.cpp', +test_unicode = executable('test_unicode', 'test_unicode.cpp', ['test_unicode.cpp', common_test_files], cpp_args: defns + warns, include_directories: [inc, libsrc, '../../../../developer/src/ext/json'], @@ -141,27 +141,27 @@ u = executable('test_unicode', 'test_unicode.cpp', ) -test('test_unicode', u, suite: 'ldml', +test('test_unicode', test_unicode, suite: 'ldml', args: [ - join_paths(test_unicode_path, 'nodeversions.json'), - join_paths(test_unicode_path, 'package.json'), - join_paths(test_unicode_path, 'Blocks.txt'), + test_unicode_path / 'nodeversions.json', + test_unicode_path / 'package.json', + test_unicode_path / 'Blocks.txt', ], ) # Run tests on all keyboards (`tests` defined in keyboards/meson.build) foreach kbd : tests - kbd_src = join_paths(test_path, kbd) + '.xml' - kbd_obj = join_paths(test_path, kbd) + '.kmx' + kbd_src = test_path / kbd + '.xml' + kbd_obj = test_path / kbd + '.kmx' test(kbd, ldml, args: [kbd_src, kbd_obj], suite: 'ldml-keyboards') endforeach # Run tests on all invalid keyboards (`invalid_tests` defined in invalid-keyboards/meson.build) foreach kbd : invalid_tests - kbd_src = join_paths(invalid_test_path, kbd) + '.xml' - kbd_obj = join_paths(invalid_test_path, kbd) + '.kmx' + kbd_src = invalid_test_path / kbd + '.xml' + kbd_obj = invalid_test_path / kbd + '.kmx' test(kbd, ldml, args: [kbd_src, kbd_obj], suite: 'ldml-invalid-keyboards') # todo: consider if we should use `should_fail: true`? endforeach diff --git a/developer/src/tike/xml/help/contexthelp.xml b/developer/src/tike/xml/help/contexthelp.xml index 76820ba929..3f071d11c3 100644 --- a/developer/src/tike/xml/help/contexthelp.xml +++ b/developer/src/tike/xml/help/contexthelp.xml @@ -386,4 +386,19 @@
The Project Manager allows you to manage all the files related to a keyboard layout in a single location.
+ + \ No newline at end of file diff --git a/docs/build/macos.md b/docs/build/macos.md index aa1eea34bf..673739379e 100644 --- a/docs/build/macos.md +++ b/docs/build/macos.md @@ -77,7 +77,7 @@ PATH="$HOMEBREW_PREFIX/opt/coreutils/libexec/gnubin:$PATH" ## KeymanWeb Dependencies -* node.js 18+, emscripten, openjdk 8 +* node.js 18+, emscripten 3.1.46 or later, openjdk 8 ```shell brew install node emscripten openjdk@8 diff --git a/docs/build/windows.md b/docs/build/windows.md index da320f244e..99f1b44e28 100644 --- a/docs/build/windows.md +++ b/docs/build/windows.md @@ -181,7 +181,7 @@ You can use Windows Settings to add these environment variables permanently: * KeymanWeb **Requirements**: -* emscripten 3.1.40 +* emscripten 3.1.46 or later * node.js 18+ * [openjdk 11](https://learn.microsoft.com/en-us/java/openjdk/download#openjdk-11)+ @@ -191,7 +191,7 @@ You can use Windows Settings to add these environment variables permanently: # for *much* faster download, hide progress bar (PowerShell/PowerShell#2138) $ProgressPreference = 'SilentlyContinue' -choco install emscripten --version 3.1.40 +choco install emscripten --version 3.1.46 ``` Note: emscripten very unhelpfully overwrites JAVA_HOME, and adds its own diff --git a/oem/firstvoices/android/app/build.gradle b/oem/firstvoices/android/app/build.gradle index a0ccc01571..0837c381ad 100644 --- a/oem/firstvoices/android/app/build.gradle +++ b/oem/firstvoices/android/app/build.gradle @@ -121,7 +121,7 @@ dependencies { implementation 'androidx.appcompat:appcompat:1.6.1' implementation 'com.google.android.material:material:1.12.0' api(name: 'keyman-engine', ext: 'aar') - implementation 'io.sentry:sentry-android:7.8.0' + implementation 'io.sentry:sentry-android:6.9.2' implementation 'androidx.preference:preference:1.2.1' } diff --git a/oem/firstvoices/android/build.gradle b/oem/firstvoices/android/build.gradle index 36949506de..4e544b7663 100644 --- a/oem/firstvoices/android/build.gradle +++ b/oem/firstvoices/android/build.gradle @@ -7,7 +7,7 @@ buildscript { dependencies { classpath 'com.android.tools.build:gradle:7.4.2' - classpath 'io.sentry:sentry-android-gradle-plugin:4.6.0' + classpath 'io.sentry:sentry-android-gradle-plugin:2.1.2' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } diff --git a/oem/firstvoices/windows/src/inst/build.sh b/oem/firstvoices/windows/src/inst/build.sh index b0c7b50a80..bf33b4046c 100755 --- a/oem/firstvoices/windows/src/inst/build.sh +++ b/oem/firstvoices/windows/src/inst/build.sh @@ -2,10 +2,11 @@ ## START STANDARD BUILD SCRIPT INCLUDE # adjust relative paths as necessary THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")" -. "${THIS_SCRIPT%/*}/../../..../../resources/build/builder.inc.sh" +. "${THIS_SCRIPT%/*}/../../../../../resources/build/builder.inc.sh" ## END STANDARD BUILD SCRIPT INCLUDE source "$KEYMAN_ROOT/resources/shellHelperFunctions.sh" +source "$KEYMAN_ROOT/resources/build/build-download-resources.sh" builder_describe "Installation files for FirstVoices Keyboards" \ @/common/windows/data \ @@ -63,7 +64,17 @@ function do_publish() { -dVERSION=$VERSION_WIN -dRELEASE=$VERSION_RELEASE \ -dPRODUCTID=$GUID1 -dDESKTOPUISOURCE=../xml \ firstvoices.wxs desktopui.wxs - "$WIXLIGHT" -dWixUILicenseRtf=License.rtf -out firstvoices.msi -ext WixUIExtension firstvoices.wixobj desktopui.wixobj + + # ICE82: we suppress because it reports spurious errors with merge module + # keymanengine to do with duplicate sequence numbers. Safely ignored. + # ICE80: we suppress because it reports x64 components without targeting x64. + # Safely ignored. + + "$WIXLIGHT" \ + -sice:ICE82 -sice:ICE80 \ + -dWixUILicenseRtf=License.rtf \ + -out firstvoices.msi \ + -ext WixUIExtension firstvoices.wixobj desktopui.wixobj # # Sign the installation archive @@ -107,7 +118,7 @@ function create-setup-inf() { builder_heading create-setup-inf echo "[Setup]" > setup.inf - echo "Version=$VersionWin" >> setup.inf + echo "Version=$VERSION_WIN" >> setup.inf echo "MSIFileName=firstvoices.msi" >> setup.inf echo "MSIOptions=" >> setup.inf echo "AppName=FirstVoices Keyboards" >> setup.inf diff --git a/web/test.sh b/web/test.sh index b1dbc01263..e3cbaef60f 100755 --- a/web/test.sh +++ b/web/test.sh @@ -62,11 +62,11 @@ fi # Prepare the flags for the karma command. WTR_DEBUG= if builder_is_debug_build; then - WTR_DEBUG=" --manual" + WTR_DEBUG="--manual" fi # End common configs. -builder_run_action test:dom web-test-runner --config "src/test/auto/dom/web-test-runner${WTR_CONFIG}.config.mjs" "${WTR_DEBUG}" +builder_run_action test:dom web-test-runner --config "src/test/auto/dom/web-test-runner${WTR_CONFIG}.config.mjs" ${WTR_DEBUG} -builder_run_action test:integrated web-test-runner --config "src/test/auto/integrated/web-test-runner${WTR_CONFIG}.config.mjs" "${WTR_DEBUG}" +builder_run_action test:integrated web-test-runner --config "src/test/auto/integrated/web-test-runner${WTR_CONFIG}.config.mjs" ${WTR_DEBUG} diff --git a/windows/src/.gitignore b/windows/src/.gitignore index 54037b8c4a..3ac3da4ea5 100644 --- a/windows/src/.gitignore +++ b/windows/src/.gitignore @@ -31,3 +31,6 @@ global/delphi/cust/MessageIdentifierConsts.pas # Coverity intermediate folder and files cov-int/ keyman-windows-coverity.tgz + +# This file is still generated by devtools. TODO: eliminate in future +PathDefines.mak diff --git a/windows/src/build.sh b/windows/src/build.sh index 02ab4fbcac..a1fc4d0e1a 100755 --- a/windows/src/build.sh +++ b/windows/src/build.sh @@ -18,7 +18,8 @@ builder_describe \ ":engine Keyman Engine for Windows" \ ":desktop Keyman for Windows" \ ":components=global/delphi Delphi components" \ - ":test=test/unit-tests Shared unit tests" + ":test=test/unit-tests Shared unit tests" \ + ":fv=../../oem/firstvoices/windows/src/inst OEM FirstVoices for Windows app" builder_parse "$@" diff --git a/windows/src/desktop/kmshell/util/Keyman.System.KeymanStartTask.pas b/windows/src/desktop/kmshell/util/Keyman.System.KeymanStartTask.pas index 35cb960a7e..51d27a83a4 100644 --- a/windows/src/desktop/kmshell/util/Keyman.System.KeymanStartTask.pas +++ b/windows/src/desktop/kmshell/util/Keyman.System.KeymanStartTask.pas @@ -11,7 +11,6 @@ type TKeymanStartTask = class private class function GetTaskName: string; - class procedure CleanupAlphaTasks(pTaskFolder: ITaskFolder); static; {$IF FALSE} //Disabled to avoid hint during build; re-enable if wanting to //re-establish the task model @@ -115,15 +114,6 @@ begin end; end; - try - CleanupAlphaTasks(pTaskFolder); - except - on E:Exception do - begin - TKeymanSentryClient.ReportHandledException(E, 'Failed to cleanup alpha tasks'); - end; - end; - try // Create a new task pTask := pService.NewTask(0); @@ -228,8 +218,6 @@ begin end; end; - CleanupAlphaTasks(pTaskFolder); - if pTaskFolder.GetTasks(0).Count = 0 then begin pTaskFolder := nil; @@ -260,36 +248,4 @@ begin CreateTask; end; -class procedure TKeymanStartTask.CleanupAlphaTasks(pTaskFolder: ITaskFolder); -var - tasks: IRegisteredTaskCollection; - i: Integer; -begin - // Cleanup earlier alpha-version tasks: we renamed the task to include the - // user's login name in build 14.0.194 of Keyman, so that multiple users could - // create the task on the same machine. It's not obvious, but the Tasks - // namespace is shared between all users -- non-admin users will not be able - // to see or overwrite tasks created by other users; they'd just get a - // (silent) access denied result. - try - tasks := pTaskFolder.GetTasks(0); - for i := 1 to tasks.Count do - if SameText(tasks.Item[i].Name, CTaskName) then - begin - tasks := nil; - pTaskFolder.DeleteTask(CTaskName, 0); - Exit; - end; - except - on E:EOleException do - begin - if (E.ErrorCode <> HResultFromWin32(ERROR_FILE_NOT_FOUND)) and - (E.ErrorCode <> HResultFromWin32(ERROR_ACCESS_DENIED)) then - // We ignore when the task doesn't exist, but report other errors - TKeymanSentryClient.ReportHandledException(E, 'Failed to delete task '+CTaskName); - end; - end; -end; - - end.