From 1246693c00da828fe1f4bcad71c44a61bde68bd8 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Fri, 7 Feb 2020 13:42:43 +1100 Subject: [PATCH 1/3] chore(ci): is build required? Adds a script that tests whether changes are likely to impact the target platform and cancels the build if not. --- resources/build/build-triggers.sh | 17 ++++ resources/build/is-build-required.sh | 123 +++++++++++++++++++++++++++ 2 files changed, 140 insertions(+) create mode 100644 resources/build/build-triggers.sh create mode 100644 resources/build/is-build-required.sh diff --git a/resources/build/build-triggers.sh b/resources/build/build-triggers.sh new file mode 100644 index 0000000000..e278798b46 --- /dev/null +++ b/resources/build/build-triggers.sh @@ -0,0 +1,17 @@ +#!/bin/bash +# +# This file maps specific paths to build triggers +# + +# the base folder for each pattern does not need to be included, nor oem folders +# e.g. android='common/predictive-text|common/lexical-model-types' +# will expand into android='^(android|(oem/[^/]+/android)|common/predictive-text|common/lexical-model-types)' + +watch_android='android|common/predictive-text|common/lexical-model-types' +watch_ios='common/predictive-text|common/lexical-model-types' +watch_linux='common/engine' +watch_mac='common/engine' +watch_web='common/predictive-text|common/lexical-model-types' + +# Windows currently builds Developer and Desktop, so we need everything from common,developer,web +watch_windows='common|developer|web' diff --git a/resources/build/is-build-required.sh b/resources/build/is-build-required.sh new file mode 100644 index 0000000000..9d90111b80 --- /dev/null +++ b/resources/build/is-build-required.sh @@ -0,0 +1,123 @@ +#!/bin/bash +# +# Determine if we need to do a build based on rules in +# build-triggers.sh, rather than calculating changes in +# TeamCity. If a build is not needed, then cancel the +# build in TeamCity +# + +set -e +set -u + +## START STANDARD BUILD SCRIPT INCLUDE +# adjust relative paths as necessary +THIS_SCRIPT="$(greadlink -f "${BASH_SOURCE[0]}" 2>/dev/null || readlink -f "${BASH_SOURCE[0]}")" +. "$(dirname "$THIS_SCRIPT")/build-utils.sh" +## END STANDARD BUILD SCRIPT INCLUDE + +. "$(dirname "$THIS_SCRIPT")/build-triggers.sh" + +# +# Parameter test +# + +invalid=false + +if [ $# -lt 1 ]; then + if [ ! -z "${TEAMCITY_PLATFORM}" ]; then + platform="$TEAMCITY_PLATFORM" + else + echo "Either TEAMCITY_PLATFORM env var must be set, or must pass as first parameter" + invalid=true + fi +else + platform="$1" +fi + +if [ $# -lt 2 ]; then + if [ ! -z "${TEAMCITY_PR_NUMBER-}" ]; then + PRNUM="$TEAMCITY_PR_NUMBER" + else + echo "Either TEAMCITY_PR_NUMBER env var must be set, or must pass as second parameter" + invalid=true + fi +else + PRNUM="$2" +fi + +if [[ ! "$platform" =~ android|ios|linux|mac|web|windows ]]; then + echo "Invalid platform $platform" + invalid=true +fi + +if [[ $invalid == true ]]; then + echo "Usage: $(basename "$THIS_SCRIPT") [platform [prnum]]" + echo "platform can be one of:" + echo " android" + echo " ios" + echo " linux" + echo " mac" + echo " web" + echo " windows (includes Desktop + Developer)" + echo "If not passed, then platform is read from env TEAMCITY_PLATFORM," + echo "and PRNUM is read from env TEAMCITY_PR_NUMBER" + exit 1 +fi + +# +# Following is not an error; this script can run against master/beta/stable +# branches as well as pull requests +# + +if [[ ! "$PRNUM" =~ ^[[:digit:]]+$ ]]; then + echo "Branch spec $PRNUM is not a pull request number; not stopping build." + exit 0 +fi + +# +# Make sure our local index is up to date with origin +# + +pushd "$KEYMAN_ROOT" > /dev/null + +git fetch origin + +# +# Find the base and head of the pull request from GitHub +# + +prinfo=`curl -s -H "User-Agent: @keymanapp" https://api.github.com/repos/keymanapp/keyman/pulls/$PRNUM` +prbase=`echo ${prinfo} | sed -E 's/.+"base".+"ref":"([^"]+)".+/\1/'` +prhead=`echo ${prinfo} | sed -E 's/.+"head".+"ref":"([^"]+)".+"base".+"ref":.+/\1/'` + +# echo "Base of $PRNUM ($prhead) is $prbase" + +# +# Then get a list of changed files between BASE of the branch and the branch itself +# We work from origin so we don't need the branches checked out ourselves +# + +prfiles=`git diff "origin/$prbase"..."origin/$prhead" --name-only` + +# Which platform are we watching? +eval watch='$'watch_$platform +# Add common patterns to the watch list +watch="^($platform|(oem/[^/]+/$platform)|resources|$watch)" + +# echo "watch=$watch" + +# Scan the files found +while IFS= read -r line; do + # echo "... $line" + if [[ "$line" =~ $watch ]]; then + echo "Platform $platform is impacted by changes found in PR #$PRNUM. Continuing build." + exit 0 + fi +done <<< "$prfiles" + +popd >/dev/null + +# Exit 1 will fail the build, but we override the failure with the buildStatus text! +echo "Platform $platform is not impacted by the changes found in PR #$PRNUM. Skipping build." +echo "##teamcity[buildStatus status='SUCCESS' text='Platform $platform is not impacted by the changes found in PR #$PRNUM. Skipping build.']" +exit 1 From 32f220cf2224b69a748dcd71dd447905b431972f Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Fri, 7 Feb 2020 13:56:46 +1100 Subject: [PATCH 2/3] chore(ci): set execute bit --- resources/build/is-build-required.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 resources/build/is-build-required.sh diff --git a/resources/build/is-build-required.sh b/resources/build/is-build-required.sh old mode 100644 new mode 100755 From 67f08b0414f5c4d2248b11825b9f1f405b8553f9 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Fri, 7 Feb 2020 14:21:17 +1100 Subject: [PATCH 3/3] chore(ci): address review comment --- resources/build/build-triggers.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/build/build-triggers.sh b/resources/build/build-triggers.sh index e278798b46..f5b7ce85a1 100644 --- a/resources/build/build-triggers.sh +++ b/resources/build/build-triggers.sh @@ -7,8 +7,8 @@ # e.g. android='common/predictive-text|common/lexical-model-types' # will expand into android='^(android|(oem/[^/]+/android)|common/predictive-text|common/lexical-model-types)' -watch_android='android|common/predictive-text|common/lexical-model-types' -watch_ios='common/predictive-text|common/lexical-model-types' +watch_android='web|common/predictive-text|common/lexical-model-types' +watch_ios='web|common/predictive-text|common/lexical-model-types' watch_linux='common/engine' watch_mac='common/engine' watch_web='common/predictive-text|common/lexical-model-types'