#!/usr/bin/env bash # # Provides a platform-independent implementation of the build steps used for CI when # building the Keyman Engine for Web. # # TODO: merge this with resources/teamcity/web scripts ## START STANDARD BUILD SCRIPT INCLUDE # adjust relative paths as necessary THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")" . "${THIS_SCRIPT%/*}/../resources/build/builder-basic.inc.sh" ## END STANDARD BUILD SCRIPT INCLUDE . "${KEYMAN_ROOT}/resources/build/utils.inc.sh" . "${KEYMAN_ROOT}/resources/build/zip.inc.sh" . "${KEYMAN_ROOT}/resources/build/ci/pull-requests.inc.sh" # This script runs from its own folder cd "${THIS_SCRIPT_PATH}" # ################################ Main script ################################ S_KEYMAN_COM= builder_describe "CI processes for Keyman Engine for Web releases (KMW)." \ "@/web/src/tools/building/sourcemap-root prepare:s.keyman.com" \ "build" \ "test Runs all unit tests" \ "post-test Runs post-test cleanup. Should be run even if a prior step fails" \ "validate-size Runs the build-size comparison check" \ "prepare Prepare upload artifacts for specified target(s)" \ ":s.keyman.com Builds artifacts for s.keyman.com" \ ":downloads.keyman.com Builds artifacts for downloads.keyman.com" \ "--s.keyman.com=S_KEYMAN_COM Sets the root location of a checked-out s.keyman.com repo" builder_parse "$@" #### KEYMAN_TIER=$(cat ../TIER.md) BUILD_NUMBER=$(cat ../VERSION.md) function web_sentry_upload () { if [[ -z "${SENTRY_ORG:-}" ]] || [[ -z "${SENTRY_PROJECT:-}" ]]; then echo "Skipping Sentry upload: SENTRY_ORG and/or SENTRY_PROJECT are unset." return fi echo "Uploading $1 to Sentry..." # --strip-common-prefix does not take an argument, unlike --strip-prefix. It auto-detects # the most common prefix instead. sentry-cli releases files "${KEYMAN_VERSION_GIT_TAG}" upload-sourcemaps --strip-common-prefix "$1" \ --rewrite --ext js --ext map --ext ts echo "Upload successful." } function build_action() { # Build step: since CI builds start (and should start) from scratch, run the following # three actions: # - configure: retrieve all NPM dependencies # - clean: make extra-sure that no prior build products exist. # - also useful when validating this script on a local dev machine! # - build: then do the ACTUAL build. # one option: builder_launch /web/build.sh configure clean build if builder_is_ci_build && builder_is_ci_build_level_release; then # Upload the sentry-configuration engine used by the mobile apps to sentry # Also, clean 'em first. for sourcemap in "${KEYMAN_ROOT}/web/src/engine/sentry-manager/build/lib/"*.map; do node "${KEYMAN_ROOT}/web/build/tools/building/sourcemap-root/index.js" null "${sourcemap}" --clean done web_sentry_upload "${KEYMAN_ROOT}/web/src/engine/sentry-manager/build/lib/" # And, of course, the main build-products too web_sentry_upload "${KEYMAN_ROOT}/web/build/app/webview/release/" web_sentry_upload "${KEYMAN_ROOT}/web/build/publish/release/" fi } function test_action() { builder_launch /web/build.sh test } function post_test_action() { # Always make sure BrowserStack stuff is terminated after the test step. # Even if it fails and/or hangs. # No matter what. Otherwise, it may leave a lock-file that breaks a later build! ../common/test/resources/test_kill_browserstack.sh } function validate_size_action() { # Performs the web build product size check as reported on Web test PRs. FLAGS= if ! builder_is_debug_build; then FLAGS=--write-status fi # Do not use --report when in --debug mode; it sets an error code that is VERY difficult to # catch with our set -e & `trap` setup. ./src/tools/building/check-build-size.sh $FLAGS } function prepare_s_keyman_com_action() { if ! builder_has_option --s.keyman.com; then builder_die "--s.keyman.com is unset!" fi if builder_is_debug_build; then # First phase: make sure the s.keyman.com repo is locally-available and up to date. pushd "${S_KEYMAN_COM}" # For testing on a local development machine / a machine with the repo already loaded. git checkout master git pull popd fi # Second phase: copy the artifacts over # The main build products are expected to reside at the root of this folder. BASE_PUBLISH_FOLDER="${S_KEYMAN_COM}/kmw/engine/${KEYMAN_VERSION}" echo "FOLDER: ${BASE_PUBLISH_FOLDER}" mkdir -p "${BASE_PUBLISH_FOLDER}" # s.keyman.com - release-config only. It's notably smaller, thus far more favorable # for distribution via cloud service. cp -Rf build/publish/release/* "${BASE_PUBLISH_FOLDER}" # Third phase: tweak the sourcemaps # We can use an alt-mode of Web's sourcemap-root tool for this. for sourcemap in "${BASE_PUBLISH_FOLDER}/"*.map; do node "${KEYMAN_ROOT}/web/build/tools/building/sourcemap-root/index.js" null "${sourcemap}" --sourceRoot "https://s.keyman.com/kmw/engine/${KEYMAN_VERSION}/src" done # Construct the PR echo "Committing and pushing KeymanWeb release ${KEYMAN_VERSION} to s.keyman.com" ci_add_files "${S_KEYMAN_COM}" "kmw/engine/${KEYMAN_VERSION}" if ! ci_repo_has_cached_changes "${S_KEYMAN_COM}"; then builder_die "No release was added to s.keyman.com, something went wrong" fi ci_open_pull_request "${S_KEYMAN_COM}" auto/keymanweb/release "auto: KeymanWeb release ${KEYMAN_VERSION}" } # Note: for now, this command is used to prepare the artifacts used by the download site, but # NOT to actually UPLOAD them via rsync or to produce related .download_info files. function prepare_downloads_keyman_com_action() { UPLOAD_PATH="${KEYMAN_ROOT}/web/build/upload/${KEYMAN_VERSION}" # --- First action artifact - the KMW zip file --- ZIP="${UPLOAD_PATH}/keymanweb-${KEYMAN_VERSION}.zip" mkdir -p "${UPLOAD_PATH}" ( # shellcheck disable=2164 cd build/publish # Zip both the 'debug' and 'release' configurations together. add_zip_files -q -r "${ZIP}" ./* ) # --- Second action artifact - the 'static' folder (hosted user testing on downloads.keyman.com) --- echo "" echo "Building \`static/\` folder for long-term hosting of testing resources..." STATIC="${UPLOAD_PATH}/static" mkdir -p "${STATIC}" mkdir -p "${STATIC}/build" cp -rf build/app "${STATIC}/build/app" cp -rf build/engine "${STATIC}/build/engine" cp -rf build/publish "${STATIC}/build/publish" cp -rf build/tools "${STATIC}/build/tools" # avoid build/upload, since that's the folder we're building! cp -f index.html "${STATIC}/index.html" mkdir -p "${STATIC}/src/tools" cp -rf src/tools/testing "${STATIC}/src/tools/testing" cp -rf src/test "${STATIC}/src/test" cp -rf src/samples "${STATIC}/src/samples" } builder_run_action build build_action builder_run_action test test_action builder_run_action post-test post_test_action builder_run_action validate-size validate_size_action builder_run_action prepare:s.keyman.com prepare_s_keyman_com_action builder_run_action prepare:downloads.keyman.com prepare_downloads_keyman_com_action