2018-04-12 09:41:16 +00:00
#!/bin/sh
2021-07-01 10:06:37 +00:00
# Syntax:
# - ci-test-extensions from-commits "<commit range>"
# Automatically detect the extensions to be tested by inspecting the git commits
# - ci-test-extensions from-list "<space-separated extensions>"
# Test the specified extensions
# - ci-test-extensions all
# Test all the supported extensions
#
2021-07-01 09:51:41 +00:00
# Global environment variables used:
# - IPETEST_DOCKER_DISTRO (required) the handle of the docker distibution to be used (eg 'buster', 'alpine3.14')
# - IPETEST_ONLY_PHPVERSIONS (optional) a space-separeted list of PHP versions: if set, we'll test only those PHP versions (eg '8.0 8.1')
2018-04-12 09:41:16 +00:00
# Let's set a sane environment
set -o errexit
set -o nounset
2021-06-30 08:10:18 +00:00
# Check if we should use a specific PHP version for a specific distribution
#
# Arguments:
# $1: the distribution
# $2: the PHP version
shouldProcessPhpVersionForDistro() {
case "$2@$1" in
8.1@alpine3.12)
return 1
;;
*)
return 0
;;
esac
}
2020-02-16 14:47:34 +00:00
# Extract the extensions to be tested from commit messages
#
# Update: EXTENSIONS_TO_BE_TESTED
# Set: STOP_EXTENSIONS_FOUND
extractExtensionsFromCommits() {
STOP_EXTENSIONS_FOUND=0
IFS='
'
for extractExtensionsFromCommits_hash in $(git -C "$CI_BUILD_DIR" log --pretty='format:%H' "$CI_COMMIT_RANGE"); do
extractExtensionsFromCommits_firstLine=1
extractExtensionsFromCommits_message="$(git -C "$CI_BUILD_DIR" log --pretty='format:%B' -n 1 "$extractExtensionsFromCommits_hash")"
IFS='
'
for extractExtensionsFromCommits_messageLine in $extractExtensionsFromCommits_message; do
if test $extractExtensionsFromCommits_firstLine -eq 1; then
extractExtensionsFromCommits_firstLine=0
else
extractExtensionsFromCommits_testList=
case "$extractExtensionsFromCommits_messageLine" in
Test:*)
extractExtensionsFromCommits_testList=${extractExtensionsFromCommits_messageLine#Test:}
;;
TEST:*)
extractExtensionsFromCommits_testList=${extractExtensionsFromCommits_messageLine#TEST:}
;;
test:*)
extractExtensionsFromCommits_testList=${extractExtensionsFromCommits_messageLine#test:}
;;
esac
if test -n "$extractExtensionsFromCommits_testList"; then
IFS=' ,;'
for extractExtensionsFromCommits_extension in $extractExtensionsFromCommits_testList; do
if test $extractExtensionsFromCommits_extension = '-STOP-'; then
STOP_EXTENSIONS_FOUND=1
break 2
fi
if ! stringInList "$extractExtensionsFromCommits_extension" "$EXTENSIONS_TO_BE_TESTED"; then
EXTENSIONS_TO_BE_TESTED="$EXTENSIONS_TO_BE_TESTED $extractExtensionsFromCommits_extension"
fi
done
fi
fi
done
done
EXTENSIONS_TO_BE_TESTED="${EXTENSIONS_TO_BE_TESTED# }"
}
2018-04-12 09:41:16 +00:00
2020-02-16 14:47:34 +00:00
# Extract the extensions to be tested from changes in the data/supported-extensions file
#
# Update: EXTENSIONS_TO_BE_TESTED
extractExtensionsFromData() {
IFS='
'
extractExtensionsFromData_foundAt=
for extractExtensionsFromData_line in $(git -C "$CI_BUILD_DIR" diff --no-indent-heuristic --minimal --no-color --word-diff=none -no-renames --unified=0 "$CI_COMMIT_RANGE" -- data/supported-extensions); do
if test -n "$extractExtensionsFromData_line"; then
if test -z "$extractExtensionsFromData_foundAt"; then
if test -z "${extractExtensionsFromData_line##@@*}"; then
extractExtensionsFromData_foundAt=y
fi
elif test -z "${extractExtensionsFromData_line##+*}"; then
extractExtensionsFromData_extension="${extractExtensionsFromData_line%% *}"
2020-02-16 17:39:57 +00:00
extractExtensionsFromData_extension="${extractExtensionsFromData_extension#+}"
2020-02-16 14:47:34 +00:00
if ! stringInList "$extractExtensionsFromData_extension" "$EXTENSIONS_TO_BE_TESTED"; then
EXTENSIONS_TO_BE_TESTED="$EXTENSIONS_TO_BE_TESTED $extractExtensionsFromData_extension"
fi
fi
fi
done
EXTENSIONS_TO_BE_TESTED="${EXTENSIONS_TO_BE_TESTED# }"
}
2018-04-12 09:41:16 +00:00
2020-03-03 11:07:51 +00:00
# Remove from the EXTENSIONS_TO_BE_TESTED variable the extensions that are
# not supported in the distro specified in the data/special-requirements file
# Update: EXTENSIONS_TO_BE_TESTED
filterUnsupportedExensionsForDistro() {
if test -z "$EXTENSIONS_TO_BE_TESTED"; then
return
fi
filterUnsupportedExensionsForDistro_reqs="$CI_BUILD_DIR/data/special-requirements"
if ! test -f "$filterUnsupportedExensionsForDistro_reqs"; then
return
fi
filterUnsupportedExensionsForDistro_filtered=''
2020-12-15 13:59:24 +00:00
IFS=' '
2022-03-23 09:55:44 +00:00
case "$IPETEST_DOCKER_DISTRO" in
alpine*)
filterUnsupportedExensionsForDistro_baseDistro="alpine"
;;
*)
filterUnsupportedExensionsForDistro_baseDistro="debian"
;;
esac
2020-12-15 13:59:24 +00:00
for filterUnsupportedExensionsForDistro_extension in $EXTENSIONS_TO_BE_TESTED; do
2021-07-01 09:51:41 +00:00
if stringInList "!$IPETEST_DOCKER_DISTRO" "$(cat "$filterUnsupportedExensionsForDistro_reqs" | grep -E "^$filterUnsupportedExensionsForDistro_extension[ \t]")"; then
printf 'Note: extension "%s" is not supported for distro "%s"\n' "$filterUnsupportedExensionsForDistro_extension" "$IPETEST_DOCKER_DISTRO"
2022-03-23 09:55:44 +00:00
elif stringInList "!$filterUnsupportedExensionsForDistro_baseDistro" "$(cat "$filterUnsupportedExensionsForDistro_reqs" | grep -E "^$filterUnsupportedExensionsForDistro_extension[ \t]")"; then
printf 'Note: extension "%s" is not supported for distro "%s"\n' "$filterUnsupportedExensionsForDistro_extension" "$filterUnsupportedExensionsForDistro_baseDistro"
2020-03-03 11:07:51 +00:00
else
filterUnsupportedExensionsForDistro_filtered="$filterUnsupportedExensionsForDistro_filtered $filterUnsupportedExensionsForDistro_extension"
fi
done
2020-12-15 13:59:24 +00:00
resetIFS
2020-03-03 11:07:51 +00:00
EXTENSIONS_TO_BE_TESTED="${filterUnsupportedExensionsForDistro_filtered# }"
}
2018-04-12 09:41:16 +00:00
# Get the docker image ID for a PHP extension and a PHP version
#
# Arguments:
2019-12-18 15:45:20 +00:00
# $1: space-separated list with the names of the PHP extensions
2018-04-12 09:41:16 +00:00
# $2: the PHP version
#
# Outputs:
2021-06-30 08:10:18 +00:00
# the full docker image ID (if exists/is usable)
2019-12-20 15:52:00 +00:00
getDockerImageName() {
2021-07-01 09:51:41 +00:00
if ! shouldProcessPhpVersionForDistro "$IPETEST_DOCKER_DISTRO" "$2"; then
2021-06-30 08:10:18 +00:00
return
fi
2019-12-20 10:51:20 +00:00
case "$2" in
2022-06-11 06:26:39 +00:00
8.2)
getDockerImageName_version="$2-rc"
;;
2019-12-06 16:12:05 +00:00
*)
2019-12-20 10:51:20 +00:00
getDockerImageName_version="$2"
2019-12-06 16:12:05 +00:00
;;
esac
2019-12-23 10:51:19 +00:00
getDockerImageName_suffix='cli'
2020-02-02 15:17:49 +00:00
getDockerImageName_reqs="$CI_BUILD_DIR/data/special-requirements"
2019-12-20 10:51:20 +00:00
if test -f "$getDockerImageName_reqs"; then
2019-12-18 15:45:20 +00:00
IFS=' '
for getDockerImageName_testExtension in $1; do
2019-12-20 10:51:20 +00:00
if test -n "$(cat "$getDockerImageName_reqs" | grep -E "^$getDockerImageName_testExtension[ \t]+zts[ \t]*$")"; then
2019-12-23 10:51:19 +00:00
getDockerImageName_suffix='zts'
2019-12-18 15:45:20 +00:00
fi
done
2018-04-12 09:41:16 +00:00
fi
2021-07-01 09:51:41 +00:00
getDockerImageName_imageName="$(printf 'php:%s-%s-%s' "$getDockerImageName_version" "$getDockerImageName_suffix" "$IPETEST_DOCKER_DISTRO")"
2020-01-31 10:09:13 +00:00
case "$getDockerImageName_imageName" in
php:5.5-cli-jessie)
getDockerImageName_imageName='php:5.5-cli'
;;
php:5.5-zts-jessie)
getDockerImageName_imageName='php:5.5-zts'
;;
esac
2019-12-23 10:51:19 +00:00
if test -z "$(docker images -q "$getDockerImageName_imageName" 2>/dev/null)"; then
getDockerImageName_log="$(docker pull "$getDockerImageName_imageName" 2>&1 || true)"
if test -z "$(docker images -q "$getDockerImageName_imageName" 2>/dev/null)"; then
if test "${getDockerImageName_log#*manifest unknown}" != "$getDockerImageName_log" || test "${getDockerImageName_log#*manifest for * not found}" != "$getDockerImageName_log"; then
return
fi
printf '%s\n' "$getDockerImageName_log" >&2
exit 1
fi
fi
printf '%s' "$getDockerImageName_imageName"
2018-04-12 09:41:16 +00:00
}
2019-12-18 15:45:20 +00:00
# Get the list of all supported PHP versions
2019-08-12 19:56:24 +00:00
#
# Arguments:
2019-12-18 15:45:20 +00:00
# $1: space-separated list with the names of the PHP extensions to be tested
#
# Outputs:
# the space-separated list of supported PHP versions
2019-12-20 15:52:00 +00:00
getAllPHPVersionsForExtensions() {
2020-09-18 18:22:39 +00:00
if test -n "${PHP_VERSION_TO_TEST:-}"; then
echo "$PHP_VERSION_TO_TEST"
return
fi
2019-12-18 15:45:20 +00:00
getAllPHPVersionsForExtensions_result=''
IFS=' '
for getAllPHPVersionsForExtensions_extension in $1; do
getAllPHPVersionsForExtensions_this="$(getAllPHPVersionsForExtension "$getAllPHPVersionsForExtensions_extension")"
if test -z "$getAllPHPVersionsForExtensions_this"; then
return
fi
if test -z "$getAllPHPVersionsForExtensions_result"; then
getAllPHPVersionsForExtensions_result="$getAllPHPVersionsForExtensions_this"
else
getAllPHPVersionsForExtensions_tmp=''
for getAllPHPVersionsForExtensions_php1 in $getAllPHPVersionsForExtensions_this; do
if stringInList "$getAllPHPVersionsForExtensions_php1" "$getAllPHPVersionsForExtensions_result"; then
getAllPHPVersionsForExtensions_tmp="$getAllPHPVersionsForExtensions_tmp $getAllPHPVersionsForExtensions_php1"
fi
done
getAllPHPVersionsForExtensions_result="${getAllPHPVersionsForExtensions_tmp# }"
fi
done
printf '%s' "$getAllPHPVersionsForExtensions_result"
}
# Get the list of all supported PHP versions
#
# Arguments:
# $1: the names of a PHP extension to be tested
2019-08-12 19:56:24 +00:00
#
# Outputs:
# the space-separated list of supported PHP versions
2019-12-20 15:52:00 +00:00
getAllPHPVersionsForExtension() {
2019-12-18 15:45:20 +00:00
getAllPHPVersionsForExtension_result=''
while IFS= read -r getAllPHPVersionsForExtension_line; do
getAllPHPVersionsForExtension_ok=
2019-08-12 19:56:24 +00:00
IFS=' '
2019-12-18 15:45:20 +00:00
for getAllPHPVersionsForExtension_chunk in $getAllPHPVersionsForExtension_line; do
if test -z "$getAllPHPVersionsForExtension_ok"; then
if test "$getAllPHPVersionsForExtension_chunk" = "$1"; then
getAllPHPVersionsForExtension_ok=y
2019-08-12 19:56:24 +00:00
else
2019-12-18 15:45:20 +00:00
getAllPHPVersionsForExtension_ok=n
2019-08-12 19:56:24 +00:00
fi
else
2019-12-18 15:45:20 +00:00
if test $getAllPHPVersionsForExtension_ok = 'y'; then
if test -z "$getAllPHPVersionsForExtension_result"; then
getAllPHPVersionsForExtension_result="$getAllPHPVersionsForExtension_chunk"
2019-08-12 19:56:24 +00:00
else
2019-12-18 15:45:20 +00:00
if ! stringInList "$getAllPHPVersionsForExtension_chunk" "$getAllPHPVersionsForExtension_result"; then
getAllPHPVersionsForExtension_result="$getAllPHPVersionsForExtension_result $getAllPHPVersionsForExtension_chunk"
2019-08-12 19:56:24 +00:00
fi
fi
fi
fi
done
2020-02-02 15:17:49 +00:00
done <"$CI_BUILD_DIR/data/supported-extensions"
2020-09-18 18:02:07 +00:00
2021-08-26 07:14:04 +00:00
getAllPHPVersionsForExtension_reqs="$CI_BUILD_DIR/data/special-requirements"
if test -f "$getAllPHPVersionsForExtension_reqs"; then
2020-09-18 18:02:07 +00:00
getAllPHPVersionsForExtension_filtered_result=''
for getAllPHPVersionsForExtension_result_filter in $getAllPHPVersionsForExtension_result; do
2021-08-26 07:14:04 +00:00
if stringInList "!$getAllPHPVersionsForExtension_result_filter-$IPETEST_DOCKER_DISTRO" "$(cat "$getAllPHPVersionsForExtension_reqs" | grep -E "^$1[ \t]")"; then
2021-07-01 09:51:41 +00:00
printf 'Note: extension "%s" is not supported for distro "%s" using php "%s"\n' "$1" "$IPETEST_DOCKER_DISTRO" "$getAllPHPVersionsForExtension_result_filter" >/dev/stderr
2020-09-18 18:02:07 +00:00
else
getAllPHPVersionsForExtension_filtered_result="$getAllPHPVersionsForExtension_filtered_result $getAllPHPVersionsForExtension_result_filter"
fi
done
else
getAllPHPVersionsForExtension_filtered_result="$getAllPHPVersionsForExtension_result"
fi
printf '%s' "${getAllPHPVersionsForExtension_filtered_result# }"
2019-08-12 19:56:24 +00:00
}
2020-02-16 14:47:34 +00:00
# Test extensions
2019-08-12 19:56:24 +00:00
#
# Arguments:
2020-02-16 14:47:34 +00:00
# $1: space-separated list with the names of the PHP extensions to be tested
2019-12-11 11:57:53 +00:00
#
2019-08-12 19:56:24 +00:00
# Return:
# 0 (true): if test passes
# 1 (false): if test fails
2020-02-16 14:47:34 +00:00
testExtension() {
2019-08-12 19:56:24 +00:00
testExtensionsFromMessage_result=0
2020-02-16 14:47:34 +00:00
IFS=' '
for testExtension_extension in $1; do
2020-10-18 18:48:31 +00:00
testExtension_extension="$(printf '%s' "$testExtension_extension" | sed -E 's/\+/ /g')"
2020-02-16 14:47:34 +00:00
printf '### TESTING EXTENSION(S) %s ###\n' "$testExtension_extension"
for testExtension_phpVersion in $(getAllPHPVersionsForExtensions "$testExtension_extension"); do
2021-07-01 09:51:41 +00:00
if test -z "${IPETEST_ONLY_PHPVERSIONS:-}" || stringInList "$testExtension_phpVersion" "$IPETEST_ONLY_PHPVERSIONS"; then
if ! testExtensionFor "$testExtension_extension" "$testExtension_phpVersion"; then
testExtensionsFromMessage_result=1
fi
2019-12-17 08:48:49 +00:00
fi
2019-08-12 19:56:24 +00:00
done
done
resetIFS
return $testExtensionsFromMessage_result
}
2020-02-16 14:47:34 +00:00
# Test extensions with specific PHP versions
#
# Arguments:
# $1: space-separated list with the names of the PHP extensions to be tested
# $2: the PHP version
#
# Return:
# 0 (true): if test passes
# 1 (false): if test fails
testExtensionFor() {
printf 'PHP version: %s\n' "$2"
if test -n "$(printf '%s' "$2" | sed -E 's/^[0-9]+\.[0-9]+$//')"; then
printf ' INVALID PHP VERSION: %s\n' "$2" >&2
return 1
2018-04-12 09:41:16 +00:00
fi
2020-02-16 14:47:34 +00:00
testExtensionFor_Image="$(getDockerImageName "$1" "$2")"
if test $? -ne 0; then
exit 1
2019-08-12 19:56:24 +00:00
fi
2020-02-16 14:47:34 +00:00
if test -z "$testExtensionFor_Image"; then
printf ' - Docker image not available\n'
return 0
2019-12-11 11:57:53 +00:00
fi
2020-02-16 14:47:34 +00:00
printf ' - Docker image: %s\n' "$testExtensionFor_Image"
testExtensionFor_out="$(mktemp)"
2020-02-16 17:48:55 +00:00
testExtensionFor_start=$(date +%s)
2021-10-07 21:40:39 +00:00
if $(docker run --rm --volume "$CI_BUILD_DIR:/app" --env CI=true --env IPE_FIX_CACERTS=1 --workdir /app "$testExtensionFor_Image" sh -c "./install-php-extensions $1 && php ./scripts/check-installed-extension.php $1" >"$testExtensionFor_out" 2>&1); then
2020-02-16 17:48:55 +00:00
testExtensionFor_end=$(date +%s)
testExtensionFor_delta=$(expr $testExtensionFor_end - $testExtensionFor_start)
2020-02-16 14:47:34 +00:00
rm -rf "$testExtensionFor_out"
2020-02-16 17:48:55 +00:00
printf ' - Passed in %s seconds\n' $testExtensionFor_delta
2020-02-16 14:47:34 +00:00
return 0
fi
printf ' - FAILED!\n' >&2
cat "$testExtensionFor_out" >&2
rm -rf "$testExtensionFor_out"
return 1
}
echo 'Checking environment'
2020-02-21 12:10:49 +00:00
if test -z "${GITHUB_WORKSPACE:-}"; then
2020-02-16 14:47:34 +00:00
echo 'Not in a CI environment' >&2
exit 1
fi
2020-02-21 12:10:49 +00:00
CI_BUILD_DIR="$GITHUB_WORKSPACE"
2021-07-01 09:51:41 +00:00
if test -z "${IPETEST_DOCKER_DISTRO:-}"; then
echo 'IPETEST_DOCKER_DISTRO environment variable not set' >&2
2020-02-16 14:47:34 +00:00
exit 1
fi
2020-03-03 11:07:51 +00:00
. "$CI_BUILD_DIR/scripts/common"
2020-02-21 12:10:49 +00:00
case "${1:-}" in
from-commits)
if test -z "${2:-}"; then
echo 'Missing commit range of the push event' >&2
exit 1
fi
CI_COMMIT_RANGE="$2"
STOP_EXTENSIONS_FOUND=0
EXTENSIONS_TO_BE_TESTED=''
extractExtensionsFromCommits
if test $STOP_EXTENSIONS_FOUND -eq 0; then
extractExtensionsFromData
fi
;;
from-list)
EXTENSIONS_TO_BE_TESTED="${2:-}"
;;
2021-07-01 10:06:37 +00:00
all)
2021-07-01 10:38:29 +00:00
EXTENSIONS_TO_BE_TESTED="$(cat "$CI_BUILD_DIR/data/supported-extensions" | cut -d' ' -f1 | tr '\n' ' ')"
2021-07-01 10:06:37 +00:00
;;
2020-02-21 12:10:49 +00:00
*)
if test -z "${1:-}"; then
printf 'Missing source of extensions to be tested\n' >&2
else
printf '"%s" is an unknown source of extensions to be tested\n' "$1" >&2
fi
exit 1
;;
esac
2020-02-16 14:47:34 +00:00
2020-03-03 11:07:51 +00:00
filterUnsupportedExensionsForDistro
2020-02-16 14:47:34 +00:00
if test -z "$EXTENSIONS_TO_BE_TESTED"; then
echo 'No extensions to be tested.'
exit 0
2018-04-12 09:41:16 +00:00
fi
2020-02-16 14:47:34 +00:00
printf '### EXTENSIONS TO BE TESTED: %s\n' "$EXTENSIONS_TO_BE_TESTED"
SOME_TEST_FAILED=0
IFS='
'
for EXTENSION_TO_BE_TESTED in "$EXTENSIONS_TO_BE_TESTED"; do
testExtension "$EXTENSION_TO_BE_TESTED" || SOME_TEST_FAILED=1
done
if test $SOME_TEST_FAILED -ne 0; then
exit 1
2018-04-12 09:41:16 +00:00
fi