diff --git a/HISTORY.md b/HISTORY.md index 44480f929b..e39d76bd02 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,12 @@ # Keyman Version History +## 19.0.106 alpha 2025-08-27 + +* fix(windows): check if automatic updates off before prompt (#14295) +* refactor(linux): use bash testing framework for packaging tests (#14603) +* maint(resources): use correct version for PR title for history cherry-pick (#14610) +* refactor(common): fix shellcheck warnings (#14580) + ## 19.0.105 alpha 2025-08-25 * maint(linux): ignore generate patch directories (#14600) @@ -656,6 +663,12 @@ * refactor(windows): rename `TKeymanMutex.MutexOwned` to `TakeOwnership` and add `ReleaseOwnership` (#13168) * chore: increment to alpha 19.0 (#13187) +## 18.0.240 stable 2025-08-27 + +* maint(resources): automatically cherry-pick history updates to master (#14596) +* maint(linux): fix lintian warnings (#14591) +* maint(linux): ignore generate patch directories (#14601) + ## 18.0.239 stable 2025-08-22 * docs(linux): clarify requirement of patched ibus for Keyman < 18 (#14113) diff --git a/VERSION.md b/VERSION.md index f5f6f62116..84e9e82913 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -19.0.106 \ No newline at end of file +19.0.107 \ No newline at end of file diff --git a/linux/scripts/test/deb-packaging.tests.sh b/linux/scripts/test/deb-packaging.tests.sh index c3cd751e5c..09867dd2f3 100755 --- a/linux/scripts/test/deb-packaging.tests.sh +++ b/linux/scripts/test/deb-packaging.tests.sh @@ -7,9 +7,10 @@ THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")" . "${THIS_SCRIPT%/*}/../../../resources/build/builder-basic.inc.sh" ## END STANDARD BUILD SCRIPT INCLUDE +. "${KEYMAN_ROOT}/resources/build/test/testing-framework.inc.sh" . "${THIS_SCRIPT%/*}/test.inc.sh" -test_check_updated_version_number__NoChange_OK() { +function test__check_updated_version_number__NoChange_OK() { createBase alpha echo "readme" > README.md @@ -21,7 +22,7 @@ test_check_updated_version_number__NoChange_OK() { linux/scripts/deb-packaging.sh --bin-pkg "${BINPKG_NAME}" --git-sha "$(git rev-parse HEAD)" --git-base master verify } -test_check_updated_version_number__LineAdded_OK() { +function test__check_updated_version_number__LineAdded_OK() { createBase alpha sed -i 's/ km_core_actions_dispose@Base 17.0.197/ km_core_actions_dispose@Base 17.0.197\n km_core_added@Base 17.0.255/' linux/debian/libkeymancore1.symbols @@ -33,7 +34,7 @@ test_check_updated_version_number__LineAdded_OK() { linux/scripts/deb-packaging.sh --bin-pkg "${BINPKG_NAME}" --git-sha "$(git rev-parse HEAD)" --git-base master verify } -test_check_updated_version_number__LineAddedWithoutVerUpd_ERROR() { +function test__check_updated_version_number__LineAddedWithoutVerUpd_ERROR() { local output createBase alpha @@ -48,7 +49,7 @@ test_check_updated_version_number__LineAddedWithoutVerUpd_ERROR() { [[ "${output[*]}" == *"ERROR: libkeymancore1.symbols file got changed without changing the package version number of the symbol"* ]] } -test_check_updated_version_number__LineRemovedWithAPIUpd_OK() { +function test__check_updated_version_number__LineRemovedWithAPIUpd_OK() { createBase alpha echo "2.0.0" > core/CORE_API_VERSION.md git add core/CORE_API_VERSION.md @@ -64,7 +65,7 @@ test_check_updated_version_number__LineRemovedWithAPIUpd_OK() { linux/scripts/deb-packaging.sh --bin-pkg "${BINPKG_NAME}" --git-sha "$(git rev-parse HEAD)" --git-base master verify } -test_check_updated_version_number__LineRemoved_OnlyCoreApiUpd_ERROR() { +function test__check_updated_version_number__LineRemoved_OnlyCoreApiUpd_ERROR() { local output createBase alpha echo "2.0.0" > core/CORE_API_VERSION.md @@ -80,7 +81,7 @@ test_check_updated_version_number__LineRemoved_OnlyCoreApiUpd_ERROR() { [[ "${output[*]}" == *"ERROR: Missing libkeymancore2.symbols file"* ]] } -test_check_updated_version_number__LineRemoved_OnlySymbolsFileUpd_ERROR() { +function test__check_updated_version_number__LineRemoved_OnlySymbolsFileUpd_ERROR() { local output createBase alpha git mv linux/debian/libkeymancore{1,2}.symbols @@ -97,7 +98,7 @@ test_check_updated_version_number__LineRemoved_OnlySymbolsFileUpd_ERROR() { [[ "${output[*]}" == *"ERROR: Missing libkeymancore1.symbols file"* ]] } -test_check_updated_version_number__LineRemovedWithAPIUpd_NotMetadataUpd_ERROR() { +function test__check_updated_version_number__LineRemovedWithAPIUpd_NotMetadataUpd_ERROR() { local output createBase alpha echo "2.0.0" > core/CORE_API_VERSION.md @@ -114,7 +115,7 @@ test_check_updated_version_number__LineRemovedWithAPIUpd_NotMetadataUpd_ERROR() [[ "${output[*]}" == *"ERROR: API version in .symbols file and in CORE_API_VERSION.md is different"* ]] } -test_check_updated_version_number__LineRemoved_InAlpha_ChangedBefore_OK() { +function test__check_updated_version_number__LineRemoved_InAlpha_ChangedBefore_OK() { createBase alpha git checkout master # simulate a commit that already introduced an API version change @@ -137,7 +138,7 @@ test_check_updated_version_number__LineRemoved_InAlpha_ChangedBefore_OK() { linux/scripts/deb-packaging.sh --bin-pkg "${BINPKG_NAME}" --git-sha "$(git rev-parse HEAD)" --git-base master verify } -test_check_updated_version_number__LineRemoved_InAlpha_FileMissingInStable_ApiVerChanged_OK() { +function test__check_updated_version_number__LineRemoved_InAlpha_FileMissingInStable_ApiVerChanged_OK() { createBase alpha git checkout master # simulate a commit that renamed the .symbols file and updated the API version @@ -164,7 +165,7 @@ test_check_updated_version_number__LineRemoved_InAlpha_FileMissingInStable_ApiVe linux/scripts/deb-packaging.sh --bin-pkg "${BINPKG_NAME}" --git-sha "$(git rev-parse HEAD)" --git-base master verify } -test_check_updated_version_number__LineRemoved_InAlpha_FileMissingInStable_ApiVerUnchanged_ERROR() { +function test__check_updated_version_number__LineRemoved_InAlpha_FileMissingInStable_ApiVerUnchanged_ERROR() { local output createBase alpha git checkout master @@ -189,7 +190,7 @@ test_check_updated_version_number__LineRemoved_InAlpha_FileMissingInStable_ApiVe [[ "${output[*]}" == *" ERROR: Major API change without updating API version number in libfoo1.symbols file"* ]] } -test_check_updated_version_number__LineRemoved_InAlpha_ChangeFromStable_ERROR() { +function test__check_updated_version_number__LineRemoved_InAlpha_ChangeFromStable_ERROR() { local output createBase alpha @@ -204,7 +205,7 @@ test_check_updated_version_number__LineRemoved_InAlpha_ChangeFromStable_ERROR() [[ "${output[*]}" == *" ERROR: Major API change without updating API version number in libkeymancore1.symbols file"* ]] } -test_check_updated_version_number__LineRemoved_InBeta_ApiVerUnchanged_ERROR() { +function test__check_updated_version_number__LineRemoved_InBeta_ApiVerUnchanged_ERROR() { local output createBase beta @@ -231,7 +232,7 @@ test_check_updated_version_number__LineRemoved_InBeta_ApiVerUnchanged_ERROR() { [[ "${output[*]}" == *" ERROR: Major API change without updating API version number in libkeymancore2.symbols file"* ]] } -test_check_updated_version_number__LineRemoved_InBeta_ApiVerChanged_OK() { +function test__check_updated_version_number__LineRemoved_InBeta_ApiVerChanged_OK() { createBase beta # simulate a commit that already introduced an API version change in Beta @@ -260,7 +261,7 @@ test_check_updated_version_number__LineRemoved_InBeta_ApiVerChanged_OK() { linux/scripts/deb-packaging.sh --bin-pkg "${BINPKG_NAME}" --git-sha "$(git rev-parse HEAD)" --git-base beta verify } -test_check_updated_version_number__LineRemoved_InBeta_FileMissingInStable_ApiVerUnchanged_ERROR() { +function test__check_updated_version_number__LineRemoved_InBeta_FileMissingInStable_ApiVerUnchanged_ERROR() { local output createBase alpha git checkout -b beta @@ -285,7 +286,7 @@ test_check_updated_version_number__LineRemoved_InBeta_FileMissingInStable_ApiVer [[ "${output[*]}" == *" ERROR: Major API change without updating API version number in libfoo1.symbols file"* ]] } -test_check_updated_version_number__LineInsertedInBranch_OK() { +function test__check_updated_version_number__LineInsertedInBranch_OK() { createBase alpha local base_sha=$(git rev-parse master) @@ -313,21 +314,6 @@ test_check_updated_version_number__LineInsertedInBranch_OK() { linux/scripts/deb-packaging.sh --bin-pkg "${BINPKG_NAME}" --git-sha "$(git rev-parse HEAD)" --git-base "${base_sha}" verify } -echo "(test logs are in /tmp/.log)" -run_test test_check_updated_version_number__NoChange_OK -run_test test_check_updated_version_number__LineAdded_OK -run_test test_check_updated_version_number__LineAddedWithoutVerUpd_ERROR -run_test test_check_updated_version_number__LineRemovedWithAPIUpd_OK -run_test test_check_updated_version_number__LineRemoved_OnlyCoreApiUpd_ERROR -run_test test_check_updated_version_number__LineRemoved_OnlySymbolsFileUpd_ERROR -run_test test_check_updated_version_number__LineRemovedWithAPIUpd_NotMetadataUpd_ERROR -run_test test_check_updated_version_number__LineRemoved_InAlpha_ChangedBefore_OK -run_test test_check_updated_version_number__LineRemoved_InAlpha_FileMissingInStable_ApiVerChanged_OK -run_test test_check_updated_version_number__LineRemoved_InAlpha_FileMissingInStable_ApiVerUnchanged_ERROR -run_test test_check_updated_version_number__LineRemoved_InAlpha_ChangeFromStable_ERROR -run_test test_check_updated_version_number__LineRemoved_InBeta_ApiVerUnchanged_ERROR -run_test test_check_updated_version_number__LineRemoved_InBeta_ApiVerChanged_OK -run_test test_check_updated_version_number__LineRemoved_InBeta_FileMissingInStable_ApiVerUnchanged_ERROR -run_test test_check_updated_version_number__LineInsertedInBranch_OK - # TODO: still some test cases missing for the different checks + +run_tests --quiet diff --git a/linux/scripts/test/test.inc.sh b/linux/scripts/test/test.inc.sh index 16c0bda2f7..188836bec3 100644 --- a/linux/scripts/test/test.inc.sh +++ b/linux/scripts/test/test.inc.sh @@ -81,9 +81,3 @@ createBase() { BINPKG_NAME=${tmpDir}/libkeymancore1_17.0.257-1+noble1_amd64.deb touch "${BINPKG_NAME}" } - -run_test() { - setup - $1 > "/tmp/$1.log" 2>&1 && echo -e "${COLOR_GREEN}$1: OK${COLOR_RESET}" || echo -e "${COLOR_RED}$1: FAILED${COLOR_RESET}" - teardown -} diff --git a/linux/scripts/test/verify_api.tests.sh b/linux/scripts/test/verify_api.tests.sh index d3095ae150..3a67770240 100755 --- a/linux/scripts/test/verify_api.tests.sh +++ b/linux/scripts/test/verify_api.tests.sh @@ -9,42 +9,56 @@ THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")" . "${THIS_SCRIPT%/*}/../../../resources/build/builder-basic.inc.sh" ## END STANDARD BUILD SCRIPT INCLUDE +# shellcheck disable=2154 +. "${KEYMAN_ROOT}/resources/build/test/testing-framework.inc.sh" . "${THIS_SCRIPT%/*}/test.inc.sh" . "${KEYMAN_ROOT}/linux/scripts/verify_api.inc.sh" -fixture_setup() { +function setup_file() { SONAME=1 LIB_NAME=libkeymancore PKG_NAME="${LIB_NAME}${SONAME}" EXIT_CODE=-1 } -test_compare_versions__less_patch() { - [[ $(compare_versions "17.0.197" "17.0.198") == -1 ]] +function test__compare_versions__less_patch() { + local result + result="$(compare_versions "17.0.197" "17.0.198")" + assert-equal "${result}" -1 } -test_compare_versions__less_minor() { - [[ $(compare_versions "17.0.197" "17.1.197") == -1 ]] +function test__compare_versions__less_minor() { + local result + result="$(compare_versions "17.0.197" "17.1.197")" + assert-equal "${result}" -1 } -test_compare_versions__less_major() { - [[ $(compare_versions "17.0.197" "18.0.0") == -1 ]] +function test__compare_versions__less_major() { + local result + result="$(compare_versions "17.0.197" "18.0.0")" + assert-equal "${result}" -1 } -test_compare_versions__greater() { - [[ $(compare_versions "17.0.198" "17.0.197") == 1 ]] +function test__compare_versions__greater() { + local result + result="$(compare_versions "17.0.198" "17.0.197")" + assert-equal "${result}" 1 } -test_compare_versions__same() { - [[ $(compare_versions "17.0.197" "17.0.197") == 0 ]] +function test__compare_versions__same() { + local result + result="$(compare_versions "17.0.197" "17.0.197")" + assert-equal "${result}" 0 } -test_compare_versions__greater0() { - [[ $(compare_versions "17.0.197" "0") == 1 ]] +function test__compare_versions__greater0() { + local result + result="$(compare_versions "17.0.197" "0")" + assert-equal "${result}" 1 } -test_get_highest_version_in_symbols_file() { +function test__get_highest_version_in_symbols_file() { local output createBase alpha echo ' (c++|optional)"typeinfo name for std::codecvt@Base" 17.0.244' >> linux/debian/libkeymancore1.symbols @@ -54,10 +68,10 @@ test_get_highest_version_in_symbols_file() { # Execute output=$(get_highest_version_in_symbols_file "$(git rev-parse HEAD)") echo "${output[*]}" # for logging - [[ "${output}" == "17.0.244" ]] + assert-equal "${output}" "17.0.244" } -test_check_updated_version_number__LineInsertedInBranch_OK() { +function test__check_updated_version_number__LineInsertedInBranch_OK() { local output createBase alpha @@ -89,17 +103,7 @@ test_check_updated_version_number__LineInsertedInBranch_OK() { output=$(check_updated_version_number) echo "${output[*]}" # for logging - [[ "${output[*]}" == *"OK: libkeymancore1.symbols file got updated with package version number"* ]] + assert-contains "${output[*]}" "OK: libkeymancore1.symbols file got updated with package version number" } - -fixture_setup -echo "(test logs are in /tmp/.log)" -run_test test_compare_versions__less_patch -run_test test_compare_versions__less_minor -run_test test_compare_versions__less_major -run_test test_compare_versions__greater -run_test test_compare_versions__same -run_test test_compare_versions__greater0 -run_test test_get_highest_version_in_symbols_file -run_test test_check_updated_version_number__LineInsertedInBranch_OK +run_tests --quiet diff --git a/resources/build/ci/trigger-build-bot.inc.sh b/resources/build/ci/trigger-build-bot.inc.sh index 34938ae96a..f7cdc815f8 100644 --- a/resources/build/ci/trigger-build-bot.inc.sh +++ b/resources/build/ci/trigger-build-bot.inc.sh @@ -21,19 +21,20 @@ function test_bot_check_pr_body() { local PRNUM=$1 local prinfo="$2" + local prbody prTestCommand prTestBody set -o noglob IFS=$'\n' - local prbody="$(echo "$prinfo" | "${JQ}" -r '.body')" - local prTestCommand="$(echo "$prbody" | grep 'Test-bot:' | cut -d: -f 2 - | cut -d' ' -f 1 -)" - local prTestBody="$(echo "$prbody" | grep -i '# User Testing')" + prbody="$(echo "${prinfo}" | "${JQ}" -r '.body')" + prTestCommand="$(echo "${prbody}" | grep 'Test-bot:' | cut -d: -f 2 - | cut -d' ' -f 1 -)" + prTestBody="$(echo "${prbody}" | grep -i '# User Testing' || true)" unset IFS set +o noglob - if ([[ "$prTestCommand" == skip ]] || [[ -z "${prTestCommand// }" ]]) && [[ -z "${prTestBody// }" ]]; then + if { [[ "${prTestCommand}" == skip ]] || [[ -z "${prTestCommand// }" ]]; } && [[ -z "${prTestBody// }" ]]; then local platform for platform in "${!build_platforms[@]}"; do - build_platforms[$platform]=build + build_platforms["${platform}"]=build done fi } @@ -66,35 +67,62 @@ function build_bot_check_messages() { # Extract the Build-bot commands from commit messages and the PR body + local buildBotShas=($(echo "$prcommits" | "${JQ}" -r '.[].sha')) IFS=$'\n' - local buildBotCommands=($(echo "$prcommits" | "${JQ}" -r '.[].commit.message' | grep 'Build-bot:' | cut -c 11- -)) local prCommands=($(echo "$prinfo" | "${JQ}" -r '.body' | tr -d '\r' | grep 'Build-bot:' | cut -c 11- -)) unset IFS # The PR body Build-bot comment will be read last, which allows it to override # all previous commands - if [[ ${#prCommands[@]} -gt 0 ]]; then - buildBotCommands+=("${prCommands[@]}") - fi + local buildBotCommand + local sha + for sha in "${buildBotShas[@]}"; do - for buildBotCommand in "${buildBotCommands[@]}"; do - # Block illegal Build-bot: commands - if [[ ! "$buildBotCommand" =~ ^[a-z_,\ :,]+$ ]]; then - builder_echo warning "WARNING[Build-bot]: ignoring invalid command [2]: '${buildBotCommand}'" - continue - fi + IFS=$'\n' + local buildBotCommands=($(echo "$prcommits" | "${JQ}" -r '.[] | select(.sha | contains("'$sha'")) | .commit.message' | grep 'Build-bot:' | cut -c 11- -)) + unset IFS - # debug_echo "buildBotCommand:{$buildBotCommand}" + for buildBotCommand in "${buildBotCommands[@]}"; do + buildBotCommand=$(builder_trim "${buildBotCommand}") + builder_echo heading "Build-bot: Found command in commit ${sha}: '${buildBotCommand}'" - # We now know that our command has only a-z, comma, colon, and space, so we - # can parse without risking escaping our bash jail + # Block illegal Build-bot: commands + if [[ ! "$buildBotCommand" =~ ^[a-z_,\ :,]+$ ]]; then + builder_echo warning "WARNING[Build-bot]: ignoring invalid command: '${buildBotCommand}'" + continue + fi - if [[ ! -z "${buildBotCommand// }" ]]; then - build_bot_update_commands $buildBotCommand - fi + # We now know that our command has only a-z, comma, colon, and space, so we + # can parse without risking escaping our bash jail + + if [[ ! -z "${buildBotCommand// }" ]]; then + _build_bot_update_commands $buildBotCommand + fi + done done + if [[ ${#prCommands[@]} -gt 0 ]]; then + for buildBotCommand in "${prCommands[@]}"; do + buildBotCommand=$(builder_trim "${buildBotCommand}") + builder_echo heading "Build-bot: Found command in body of PR #${PRNUM}: '${buildBotCommand}'" + + # Block illegal Build-bot: commands + if [[ ! "$buildBotCommand" =~ ^[a-z_\ :,]+$ ]]; then + builder_echo warning "WARNING[Build-bot]: ignoring invalid command: '${buildBotCommand}'" + continue + fi + + # We now know that our command has only a-z, comma, colon, underline, and + # space, so we can parse without risking escaping our bash jail + + if [[ ! -z "${buildBotCommand// }" ]]; then + _build_bot_update_commands $buildBotCommand + fi + done + + fi + set +o noglob } @@ -105,13 +133,13 @@ function build_bot_check_messages() { # Note that this function assumes that inputs are sanitized, see # build_bot_check_messages # -function build_bot_update_commands() { +function _build_bot_update_commands() { local level= local platforms= local command="$*" local re='^(build|skip|release)( [a-z,]+)?$' - if [[ "$command" =~ $re ]]; then + if [[ "${command}" =~ ${re} ]]; then # legacy (until aug 2025) format is "level [platform]" (comma format never used) if [[ $# == 1 ]]; then level=$1 @@ -126,41 +154,42 @@ function build_bot_update_commands() { unset IFS fi - if [[ ! $level =~ ^$valid_build_levels$ ]]; then + if [[ ! ${level} =~ ^${valid_build_levels}$ ]]; then # Just skip this build command - builder_echo warning "WARNING[Build-bot]: ignoring invalid build level '$level' in command '$command'" + builder_echo warning "WARNING[Build-bot]: ignoring invalid build level '${level}' in command '${command}'" return 0 fi - builder_echo blue "Platforms to be updated from command '$command' are: ${platforms[@]}" + builder_echo grey "Build-bot: Platforms to be updated from command '${command}' are: ${platforms[*]}" - build_bot_verify_platforms platforms + _build_bot_verify_platforms platforms local platform for platform in "${platforms[@]}"; do - builder_echo "Build-bot: Updating build level for $platform to $level" - build_platforms[$platform]=$level + builder_echo "Build-bot: Updating build level for ${platform} to ${level}" + build_platforms["${platform}"]=${level} done else # modern format is "level[:platform[,platform...]][ level[:platform[,platform...]]...]" declare -a commands IFS=' ' - read -r -a commands <<< "$command" + read -r -a commands <<< "${command}" unset IFS for command in "${commands[@]}"; do declare -a params IFS=: - read -r -a params <<< "$command" + read -r -a params <<< "${command}" + unset IFS level=${params[0]} - if [[ ! $level =~ ^$valid_build_levels$ ]]; then + if [[ ! ${level} =~ ^${valid_build_levels}$ ]]; then # Just skip this build command - builder_echo warning "WARNING[Build-bot]: ignoring invalid build level '$level' in command '$command'" + builder_echo warning "WARNING[Build-bot]: ignoring invalid build level '${level}' in command '${command}'" continue fi if [[ ${#params[@]} == 1 ]]; then - platforms="${!build_platforms[@]}" + read -r -a platforms <<< "${!build_platforms[@]}" else # remaining parameters are comma separated platforms IFS=',' @@ -168,13 +197,13 @@ function build_bot_update_commands() { unset IFS fi - build_bot_verify_platforms platforms + _build_bot_verify_platforms platforms local platform for platform in "${platforms[@]}"; do - if [[ "${build_platforms[$platform]+x}" != "${level}" ]]; then - builder_echo "Build-bot: Updating build level for $platform to $level" - build_platforms[$platform]=$level + if [[ "${build_platforms[${platform}]+x}" != "${level}" ]]; then + builder_echo "Build-bot: Updating build level for ${platform} to ${level}" + build_platforms["${platform}"]=${level} fi done done @@ -187,20 +216,20 @@ function build_bot_update_commands() { # Parameters: # 1: name of platforms array parameter (byref) # -function build_bot_verify_platforms() { +function _build_bot_verify_platforms() { local -n input_platforms=$1 local output_platforms=() local platform for platform in "${input_platforms[@]}"; do # We'll emit a warning with invalid platforms, then remove them from the array - if [[ ! $platform =~ ^(all|$available_platforms_regex)$ ]]; then - builder_echo warning "WARNING[Build-bot]: ignoring invalid platform '$platform'" - elif [[ $platform == all ]]; then - input_platforms=(${available_platforms[@]}) + if [[ ! ${platform} =~ ^(all|${available_platforms_regex})$ ]]; then + builder_echo warning "WARNING[Build-bot]: ignoring invalid platform '${platform}'" + elif [[ ${platform} == all ]]; then + input_platforms=("${available_platforms[@]}") return else - if [[ ! "${output_platforms[@]}" =~ [[:\<:]]$platform[[:\>:]] ]]; then - output_platforms+=($platform) + if [[ ! "${output_platforms[@]}" =~ [[:\<:]]${platform}[[:\>:]] ]]; then + output_platforms+=("${platform}") fi fi done diff --git a/resources/build/test/build-bot/pr-9999-commits.txt b/resources/build/test/build-bot/pr-9999-commits.txt index ac257dfa8e..ae6bdf378f 100644 --- a/resources/build/test/build-bot/pr-9999-commits.txt +++ b/resources/build/test/build-bot/pr-9999-commits.txt @@ -1,15 +1,18 @@ [ { + "sha": "1234", "commit": { "message": "maint(common): test\nBuild-bot: build windows\n" } }, { + "sha": "5678", "commit": { "message": "maint(common): test\nBuild-bot: release windows\n" } }, { + "sha": "9abc", "commit": { "message": "maint(common): test\nBuild-bot: skip windows\n" } diff --git a/resources/build/test/build-bot/trigger-build-bot.test.sh b/resources/build/test/build-bot/trigger-build-bot.test.sh index 4098f4b5ae..a39b8361ae 100755 --- a/resources/build/test/build-bot/trigger-build-bot.test.sh +++ b/resources/build/test/build-bot/trigger-build-bot.test.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +# shellcheck disable=2154 disable=1091 ## START STANDARD BUILD SCRIPT INCLUDE # adjust relative paths as necessary @@ -25,7 +26,7 @@ test_build_bot_check_messages() { builder_echo start test_build_bot_check_messages 'START TEST: build_bot_check_messages' # Mostly real data (only Build-bot commands edited for test) - _do_test_build_bot_check_messages_file 14013 "[windows]=release" "$ALL_BUILD_PLATFORMS_SKIP_EXPECTED" + _do_test_build_bot_check_messages_file 14013 "[windows]=release" "${ALL_BUILD_PLATFORMS_SKIP_EXPECTED}" # Simplified data for testing Build-bot command sequences only _do_test_build_bot_check_messages_file 9999 "[windows]=release" '[windows]="skip" [developer]="release"' @@ -35,17 +36,18 @@ test_build_bot_check_messages() { _do_test_build_bot_check_messages_inline 10 "[windows]=release" '[common]="release" [windows]="build"' '{ "body": "Build-bot: skip:windows build release:common" }' '[]' # Test some bad inputs - _do_test_build_bot_check_messages_inline 1 "[windows]=release" '[windows]="release"' '{}' '[{ "commit": { "message": "maint(common): test\nBuild-bot: foo windows\n" }}]' + _do_test_build_bot_check_messages_inline 1 "[windows]=release" '[windows]="release"' '{}' '[{ "sha": "1234", "commit": { "message": "maint(common): test\nBuild-bot: foo windows\n" }}]' # empty body, 'foo windows' in commit - _do_test_build_bot_check_messages_inline 2 "[windows]=release" '[windows]="release"' '{ "body": "" }' '[{ "commit": { "message": "maint(common): test\nBuild-bot: foo windows\n" }}]' + _do_test_build_bot_check_messages_inline 2 "[windows]=release" '[windows]="release"' '{ "body": "" }' '[{ "sha": "1234", "commit": { "message": "maint(common): test\nBuild-bot: foo windows\n" }}]' # attempts to escape jail - _do_test_build_bot_check_messages_inline 3 "[windows]=release" '[windows]="release"' '{ "body": "Build-bot: '"'"'echo foo" }' '[{ "commit": { "message": "maint(common): test\n" }}]' - _do_test_build_bot_check_messages_inline 4 "[windows]=release" '[windows]="release"' '{ "body": "Build-bot: echo *" }' '[{ "commit": { "message": "maint(common): test\n" }}]' - _do_test_build_bot_check_messages_inline 5 "[windows]=release" '[windows]="release"' '{ "body": "Build-bot: \\0" }' '[{ "commit": { "message": "maint(common): test\n" }}]' - _do_test_build_bot_check_messages_inline 5 "[windows]=release" '[windows]="release"' '{ "body": "Build-bot: `echo escaped`" }' '[{ "commit": { "message": "maint(common): test\n" }}]' - _do_test_build_bot_check_messages_inline 6 "[windows]=release" '[windows]="release"' '{ "body": "Build-bot: ' '[{ "commit": { "message": "maint(common): test\n" }}]' + _do_test_build_bot_check_messages_inline 3 "[windows]=release" '[windows]="release"' '{ "body": "Build-bot: '"'"'echo foo" }' '[{ "sha": "1234", "commit": { "message": "maint(common): test\n" }}]' + _do_test_build_bot_check_messages_inline 4 "[windows]=release" '[windows]="release"' '{ "body": "Build-bot: echo *" }' '[{ "sha": "1234", "commit": { "message": "maint(common): test\n" }}]' + _do_test_build_bot_check_messages_inline 5 "[windows]=release" '[windows]="release"' '{ "body": "Build-bot: \\0" }' '[{ "sha": "1234", "commit": { "message": "maint(common): test\n" }}]' + # shellcheck disable=SC2016 + _do_test_build_bot_check_messages_inline 5 "[windows]=release" '[windows]="release"' '{ "body": "Build-bot: `echo escaped`" }' '[{ "sha": "1234", "commit": { "message": "maint(common): test\n" }}]' + _do_test_build_bot_check_messages_inline 6 "[windows]=release" '[windows]="release"' '{ "body": "Build-bot: ' '[{ "sha": "1234", "commit": { "message": "maint(common): test\n" }}]' # incomplete command - _do_test_build_bot_check_messages_inline 7 "[windows]=release" '[windows]="release"' '{ "body": "Build-bot: " }' '[{ "commit": { "message": "maint(common): test\n" }}]' + _do_test_build_bot_check_messages_inline 7 "[windows]=release" '[windows]="release"' '{ "body": "Build-bot: " }' '[{ "sha": "1234", "commit": { "message": "maint(common): test\n" }}]' builder_echo end test_build_bot_check_messages success 'SUCCESS: build_bot_check_messages' } @@ -62,13 +64,14 @@ _do_test_build_bot_check_messages_file() { eval "declare -gA build_platforms=($2)" eval "declare -A expected_build_platforms=($3)" - build_bot_check_messages $prnum "$(cat ${THIS_SCRIPT_PATH}/pr-$prnum-data.txt)" "$(cat ${THIS_SCRIPT_PATH}/pr-$prnum-commits.txt)" + # shellcheck disable=2312 + build_bot_check_messages "${prnum}" "$(cat "${THIS_SCRIPT_PATH}/pr-${prnum}-data.txt")" "$(cat "${THIS_SCRIPT_PATH}/pr-${prnum}-commits.txt")" for i in "${!expected_build_platforms[@]}"; do - assert-equal "${build_platforms[$i]:-missing}" "${expected_build_platforms[$i]:-missing}" "PR #$prnum: build_platforms[$i]" + assert-equal "${build_platforms[${i}]:-missing}" "${expected_build_platforms[${i}]:-missing}" "PR #${prnum}: build_platforms[${i}]" done for i in "${!build_platforms[@]}"; do - assert-equal "${build_platforms[$i]:-missing}" "${expected_build_platforms[$i]:-missing}" "PR #$prnum: build_platforms[$i]" + assert-equal "${build_platforms[${i}]:-missing}" "${expected_build_platforms[${i}]:-missing}" "PR #${prnum}: build_platforms[${i}]" done } @@ -89,13 +92,13 @@ _do_test_build_bot_check_messages_inline() { local prinfo="$4" local prcommits="$5" - build_bot_check_messages $prnum "$prinfo" "$prcommits" + build_bot_check_messages "${prnum}" "${prinfo}" "${prcommits}" for i in "${!expected_build_platforms[@]}"; do - assert-equal "${build_platforms[$i]:-missing}" "${expected_build_platforms[$i]:-missing}" "PR #$prnum: build_platforms[$i]" + assert-equal "${build_platforms[${i}]:-missing}" "${expected_build_platforms[${i}]:-missing}" "PR #${prnum}: build_platforms[${i}]" done for i in "${!build_platforms[@]}"; do - assert-equal "${build_platforms[$i]:-missing}" "${expected_build_platforms[$i]:-missing}" "PR #$prnum: build_platforms[$i]" + assert-equal "${build_platforms[${i}]:-missing}" "${expected_build_platforms[${i}]:-missing}" "PR #${prnum}: build_platforms[${i}]" done } @@ -104,7 +107,11 @@ _do_test_build_bot_check_messages_inline() { #---------------------------------------------------------------------------------------------------- test_build_bot_update_commands() { - builder_echo start test_build_bot_update_commands 'START TEST: build_bot_update_commands' + builder_echo start test_build_bot_update_commands 'START TEST: _build_bot_update_commands' + + # added for #14565 + _do_test_build_bot_update_commands '[common_windows]="build" [windows]="build" [developer]="build"' "skip build:windows,developer" '[common_windows]="skip" [windows]="build" [developer]="build"' + _do_test_build_bot_update_commands '[windows]="release"' "skip:windows" '[windows]="skip"' _do_test_build_bot_update_commands '[windows]="release"' "skip windows" '[windows]="skip"' _do_test_build_bot_update_commands '[windows]="release"' "skip:windows,developer" '[windows]="skip" [developer]="skip"' @@ -119,8 +126,8 @@ test_build_bot_update_commands() { # not testing invalid legacy command: _do_test_build_bot_update_commands '[windows]="release"' "build foo" '[windows]="release"' _do_test_build_bot_update_commands '[windows]="release"' "build:common" '[common]="build" [windows]="release"' _do_test_build_bot_update_commands '[windows]="release"' "build common" '[common]="build" [windows]="release"' - _do_test_build_bot_update_commands '[windows]="release"' "build:all" "$ALL_BUILD_PLATFORMS_BUILD_EXPECTED" - _do_test_build_bot_update_commands '[windows]="release"' "build all" "$ALL_BUILD_PLATFORMS_BUILD_EXPECTED" + _do_test_build_bot_update_commands '[windows]="release"' "build:all" "${ALL_BUILD_PLATFORMS_BUILD_EXPECTED}" + _do_test_build_bot_update_commands '[windows]="release"' "build all" "${ALL_BUILD_PLATFORMS_BUILD_EXPECTED}" builder_echo end test_build_bot_update_commands success 'SUCCESS: build_bot_update_commands' } @@ -134,39 +141,42 @@ test_build_bot_update_commands() { # _do_test_build_bot_update_commands() { eval "declare -gA build_platforms=($1)" - local update_command="$2" + local update_commands="$2" eval "declare -A expected_build_platforms=($3)" - build_bot_update_commands $update_command + # shellcheck disable=SC2086 # intentionally no quotes + _build_bot_update_commands ${update_commands} for i in "${!expected_build_platforms[@]}"; do - assert-equal "${build_platforms[$i]}" "${expected_build_platforms[$i]}" "build_platforms[$i]" + assert-equal "${build_platforms[${i}]}" "${expected_build_platforms[${i}]}" "build_platforms[${i}]" done for i in "${!build_platforms[@]}"; do - assert-equal "${build_platforms[$i]}" "${expected_build_platforms[$i]}" "build_platforms[$i]" + assert-equal "${build_platforms[${i}]}" "${expected_build_platforms[${i}]}" "build_platforms[${i}]" done } #---------------------------------------------------------------------------------------------------- test_build_bot_verify_platforms() { - builder_echo start test_build_bot_verify_platforms 'START TEST: build_bot_verify_platforms' + builder_echo start test_build_bot_verify_platforms 'START TEST: _build_bot_verify_platforms' _do_test_build_bot_verify_platforms "windows mac" "windows mac" _do_test_build_bot_verify_platforms "windows foo" "windows" _do_test_build_bot_verify_platforms "core" "core" _do_test_build_bot_verify_platforms "all" "${available_platforms[*]}" - builder_echo end test_build_bot_verify_platforms success 'SUCCESS: build_bot_verify_platforms' + builder_echo end test_build_bot_verify_platforms success 'SUCCESS: _build_bot_verify_platforms' } _do_test_build_bot_verify_platforms() { + # shellcheck disable=SC2206 # intentionally no quotes local platforms=($1) + # shellcheck disable=SC2206 # intentionally no quotes local expected_platforms=($2) - build_bot_verify_platforms platforms + _build_bot_verify_platforms platforms assert-equal ${#platforms[@]} ${#expected_platforms[@]} "#platforms[@]" for i in "${!expected_platforms[@]}"; do - assert-equal "${platforms[$i]}" "${expected_platforms[$i]}" "platforms[$i]" + assert-equal "${platforms[${i}]}" "${expected_platforms[${i}]}" "platforms[${i}]" done } @@ -194,13 +204,13 @@ _do_test_test_bot_check_pr_body() { local prinfo="$3" eval "declare -A expected_build_platforms=($4)" - test_bot_check_pr_body $prnum "$prinfo" + test_bot_check_pr_body "${prnum}" "${prinfo}" for i in "${!expected_build_platforms[@]}"; do - assert-equal "${build_platforms[$i]}" "${expected_build_platforms[$i]}" "PR #$prnum: build_platforms[$i]" + assert-equal "${build_platforms[${i}]}" "${expected_build_platforms[${i}]}" "PR #${prnum}: build_platforms[${i}]" done for i in "${!build_platforms[@]}"; do - assert-equal "${build_platforms[$i]}" "${expected_build_platforms[$i]}" "PR #$prnum: build_platforms[$i]" + assert-equal "${build_platforms[${i}]}" "${expected_build_platforms[${i}]}" "PR #${prnum}: build_platforms[${i}]" done } @@ -209,4 +219,4 @@ _do_test_test_bot_check_pr_body() { test_build_bot_verify_platforms test_build_bot_update_commands test_build_bot_check_messages -test_test_bot_check_pr_body \ No newline at end of file +test_test_bot_check_pr_body diff --git a/resources/build/test/testing-framework.inc.sh b/resources/build/test/testing-framework.inc.sh index ef1932630c..4465f57f95 100644 --- a/resources/build/test/testing-framework.inc.sh +++ b/resources/build/test/testing-framework.inc.sh @@ -104,6 +104,9 @@ teardown_file() { # Discover and run all tests in the current script # # Parameters: +# --quiet optional first parameter. If specified suppress the +# output of the tests and save it in a logfile in +# /tmp/.log instead. # [$1 [$2]] / [first [last]] - optional range of lines in the tests script to search for tests. # This helps to split a test file into several sections where # each section can have separate setup/teardown functions. @@ -115,6 +118,13 @@ teardown_file() { # } run_tests() { local test_count test_fail_count line func + if [[ "${1:-}" == "--quiet" ]]; then + test_suppress_output=true + builder_echo green "(test logs are in /tmp/.log)" + shift + else + test_suppress_output=false + fi local first="${1:-1}" local last="${2:-$(wc -l < "${BASH_ARGV0}")}" local file="${3:-${BASH_ARGV0}}" @@ -220,9 +230,19 @@ _get_test_func() { echo "${name}" } +_call() { + local func="$1" + local testname="$2" + if ${test_suppress_output}; then + ${func} >> "/tmp/${testname}.log" 2>&1 + else + ${func} + fi +} + _test_wrapper() { local func="$1" - ${func} + _call "${func}" "${func}" return "${test_failures}" } @@ -235,10 +255,14 @@ _run_single_test() { builder_echo_debug "Running test ${func}" fi + if ${test_suppress_output}; then + echo "" > "/tmp/${func}.log" + fi + set +e test_failures=0 ((test_count++)) - setup + _call setup "${func}" # shellcheck disable=SC2310 if _test_wrapper "${func}"; then @@ -248,7 +272,7 @@ _run_single_test() { _failed "${func}" fi - teardown + _call teardown "${func}" set -e } diff --git a/resources/teamcity/triggers/trigger-release-builds.sh b/resources/teamcity/triggers/trigger-release-builds.sh index 65852ca8de..f914a804f4 100755 --- a/resources/teamcity/triggers/trigger-release-builds.sh +++ b/resources/teamcity/triggers/trigger-release-builds.sh @@ -186,9 +186,9 @@ if [ "$action" == "commit" ]; then # If HISTORY.md has been updated, then we want to create a branch and push # it for review if git status --porcelain=v1 | grep -q HISTORY.md; then - git switch -c "auto/cherry-pick-$NEWVERSION-history-to-alpha" master + git switch -c "auto/cherry-pick-$KEYMAN_VERSION-history-to-alpha" master git add HISTORY.md - git commit -m "auto: cherry-pick $NEWVERSION history to alpha + git commit -m "auto: cherry-pick $KEYMAN_VERSION history to alpha Build-bot: skip Test-bot: skip