spiegel-keyman/resources/build/run-required-test-builds.sh
Marc Durdin 7c8003a0f7 chore(common): cancel earlier builds when new test builds triggered
Fixes #10590.

Cancels existing running or queued test builds on TeamCity when a new
build is started for the same 'branch' (aka branch or PR).

Does not touch release builds or other projects -- only touches
recognized test build configurations.
2024-02-01 16:02:23 +07:00

195 lines
5.9 KiB
Bash
Executable file

#!/usr/bin/env bash
#
# Determine if we need to do a build based on rules in
# trigger-definitions.inc.sh, rather than calculating changes in
# TeamCity. If a build is needed, then we ask TeamCity to
# start the build.
#
set -e
set -u
if [[ $# -lt 1 ]]; then
echo 'Usage: run-required-test-build.sh pull-request-number|branch'
echo ' where branch can be master, beta'
exit 1
else
PRNUM="$1"
fi
function debug_echo() {
if [ ! -z ${DEBUG:-} ]; then
echo "DEBUG: $1"
fi
true
}
#
# This must be run under a TeamCity environment in order to receive all variables
#
## START STANDARD BUILD SCRIPT INCLUDE
# adjust relative paths as necessary
THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "${THIS_SCRIPT%/*}/../../resources/build/build-utils.sh"
## END STANDARD BUILD SCRIPT INCLUDE
. "${THIS_SCRIPT%/*}/trigger-definitions.inc.sh"
. "${THIS_SCRIPT%/*}/trigger-builds.inc.sh"
. "${THIS_SCRIPT%/*}/jq.inc.sh"
#
# Iterate through the platforms 'array' passed in and
# run builds associated with each platform found
#
function triggerTestBuilds() {
# Note: we always run builds for 'all' platforms
local platforms=( `echo "all $1"` )
local branch="$2"
local force="${3:-false}"
# Cancel any already running builds for this branch
node "$THIS_SCRIPT_PATH/ci/cancel-builds/cancel-test-builds.mjs" "$branch" "$TEAMCITY_TOKEN"
for platform in "${platforms[@]}"; do
echo "# $platform: checking for changes"
eval test_builds='(${'bc_test_$platform'[@]})'
for test_build in "${test_builds[@]}"; do
if [[ $test_build == "" ]]; then continue; fi
if [ "${test_build:(-7)}" == "_GitHub" ]; then
local job=${test_build%_GitHub}
echo " -- Triggering GitHub action build $job/$branch"
triggerGitHubActionsBuild true "$job" "$branch"
else
echo " -- Triggering build configuration $test_build on teamcity"
triggerTeamCityBuild true "$test_build" "$vcs_test" "$branch"
fi
done
done
}
#
# Following is not an error; this script can run against master/beta/stable
# branches as well as pull requests
#
if [[ ! "$PRNUM" =~ ^[[:digit:]]+$ ]]; then
# branch name is 'master', 'beta' [, or 'stable' -- in the future]
echo ". Branch $PRNUM needs to pass tests on all platforms."
triggerTestBuilds "`echo ${available_platforms[@]}`" "$PRNUM" "true"
exit 0
fi
#
# Find the base and head of the pull request from GitHub (while we can
# just use the current branch name, this lets us test the script against
# different pull requests; and there is no way to know which base is
# targeted by the PR other than to ask GitHub, anyway.)
#
echo ". Get information about pull request #$PRNUM from GitHub"
prinfo=`curl -s -H "User-Agent: @keymanapp" -H "Authorization: Bearer $GITHUB_TOKEN" https://api.github.com/repos/keymanapp/keyman/pulls/$PRNUM`
prbase=`echo ${prinfo} | "$JQ" -r '.base.ref'`
prhead=`echo ${prinfo} | "$JQ" -r '.head.ref'`
prbaserepo=`echo ${prinfo} | "$JQ" -r '.base.repo.html_url'`
prheadrepo=`echo ${prinfo} | "$JQ" -r '.head.repo.html_url'`
debug_echo "PRNUM: $PRNUM"
debug_echo "BASE: $prbase ($prbaserepo)"
debug_echo "HEAD: $prhead ($prheadrepo)"
prremote=origin
if [ "$prbaserepo" != "https://github.com/keymanapp/keyman" ]; then
echo "Unknown base repository $prbaserepo."
exit 1
fi
#
# By default, TeamCity does not fetch any remote branch information
# so let's grab the remote branch info before we try and run a diff
#
# (Ensure we are within the repository before running git calls)
echo ". Ensure our local branch is up to date"
pushd "$KEYMAN_ROOT" > /dev/null
git fetch origin > /dev/null
#
# If the repo is a fork, we need to fetch the remote as well; note that
# this only happens on a manual build as automatic trigger does not run
# on untrusted forks.
#
if [ "$prheadrepo" != "https://github.com/keymanapp/keyman" ]; then
prremote=external-rrtb
git remote add "$prremote" "$prheadrepo"
git fetch "$prremote" > /dev/null
fi
#
# 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 in our local copy
#
echo ". Get list of changed files in the pull request"
prfiles=`git diff --name-only "origin/$prbase"..."$prremote/$prhead" || ( if [ $? == 128 ]; then echo abort; else exit $?; fi )`
if [ "$prfiles" == "abort" ]; then
# Don't trigger any builds, exit with success
if [ "$prremote" != "origin" ]; then
git remote remove "$prremote"
fi
echo "Remote branch origin/$prhead has gone away; probably an automatic pull request. Skipping build."
exit 0
fi
if [ "$prremote" != "origin" ]; then
git remote remove "$prremote"
fi
debug_echo "Files found: ${prfiles[*]}"
popd > /dev/null
#
# Find the platforms that have changes based on the watch_ variables in trigger-definitions.inc.sh
#
echo ". Find platforms that have changes"
build_platforms=()
# Scan the files found
while IFS= read -r line; do
# for each platform
for platform in "${available_platforms[@]}"; do
if [[ ! " ${build_platforms[@]} " =~ " $platform " ]]; then
# Which platform are we watching?
eval watch='$'watch_$platform
# Add common patterns to the watch list
watch="^($platform|(oem/[^/]+/$platform)|resources|$watch)"
if [[ "$line" =~ $watch ]]; then
build_platforms+=($platform)
fi
fi
done
done <<< "$prfiles"
debug_echo "Build platforms: ${build_platforms[*]}"
if (( ${#build_platforms[@]} > 0)); then
#
# Start the test builds
#
echo ". Start test builds"
triggerTestBuilds "`echo ${build_platforms[@]}`" "$PRNUM"
else
echo ". No builds to start"
curl --silent --write-out '\n' \
--request POST \
--header "Accept: application/vnd.github+json" \
--header "Authorization: token $GITHUB_TOKEN" \
--data '{"state":"success","description":"Skipping since no platform builds necessary","context":"Test Build (Keyman)"}' \
"https://api.github.com/repos/keymanapp/keyman/statuses/${BUILD_VCS_NUMBER}"
fi
exit 0