Files
nolimit-discounts/ci/site-test.sh
T

149 lines
6.3 KiB
Bash
Raw Permalink Normal View History

#!/usr/bin/env bash
# Stand up a throwaway WordPress + WooCommerce, install this plugin into it,
# and run the site tests from ci/plugin.conf inside it.
#
# WP_VERSION=latest|nightly|6.8 WC_VERSION=latest|beta|11.1.0 PHP_VERSION=8.3
#
# The point of the version knobs is the question this whole directory exists to
# answer: *will the shop still work after I press update?* Running the same
# tests against `latest` and against `nightly`/`beta` answers it before the
# update happens rather than after.
#
# Written for a Gitea Actions job, which runs INSIDE a container that talks to
# the HOST's docker daemon. A bind mount of $PWD there mounts an empty
# directory nobody created, and the symptom is "Could not open input file",
# which reads like a typo in the path. So the plugin goes in over `docker cp`
# and all state lives in named volumes. That also makes the script behave
# identically on GitHub's runners and on a laptop.
set -euo pipefail
cd "$(dirname "$0")/.."
. ci/lib.sh
ci_load_conf
WP_VERSION="${WP_VERSION:-latest}"
WC_VERSION="${WC_VERSION:-latest}"
PHP_VERSION="${PHP_VERSION:-8.3}"
id="wpci-$$"
net="$id-net"
cleanup() {
docker rm -f "$id-db" "$id-cli" >/dev/null 2>&1 || true
docker volume rm -f "$id-wp" >/dev/null 2>&1 || true
docker network rm "$net" >/dev/null 2>&1 || true
}
trap cleanup EXIT
echo "WordPress=$WP_VERSION WooCommerce=$WC_VERSION PHP=$PHP_VERSION plugin=$PLUGIN_SLUG"
ci_step "database"
docker network create "$net" >/dev/null
docker volume create "$id-wp" >/dev/null
docker run -d --name "$id-db" --network "$net" \
-e MARIADB_ROOT_PASSWORD=root -e MARIADB_DATABASE=wordpress \
-e MARIADB_USER=wordpress -e MARIADB_PASSWORD=wordpress mariadb:lts >/dev/null
# wordpress:cli runs as www-data (33); a fresh named volume is root-owned, so
# ownership is fixed from a root container before anything tries to write.
docker run --rm -v "$id-wp:/var/www/html" alpine chown 33:33 /var/www/html
docker run -d --name "$id-cli" --network "$net" -v "$id-wp:/var/www/html" \
-e WORDPRESS_DB_HOST="$id-db" "wordpress:cli-php$PHP_VERSION" sleep infinity >/dev/null
# The image ships no php.ini, so PHP's 128M default applies and `wp core
# download` dies unpacking the zip. WP_CLI_PHP_ARGS does not help here: the
# phar is executed directly, not through the wp launcher.
docker exec -u root "$id-cli" sh -c 'echo memory_limit=512M > /usr/local/etc/php/conf.d/zz-memory.ini'
wp() { docker exec "$id-cli" wp "$@"; }
for i in $(seq 1 60); do
docker exec "$id-db" mariadb -uwordpress -pwordpress -e 'select 1' wordpress >/dev/null 2>&1 && break
if [ "$i" = 60 ]; then echo "MariaDB never came up." >&2; exit 1; fi
sleep 2
done
ci_step "WordPress $WP_VERSION"
if [ "$WP_VERSION" = latest ]; then
wp core download --quiet
else
wp core download --version="$WP_VERSION" --quiet
fi
wp config create --dbname=wordpress --dbuser=wordpress --dbpass=wordpress \
--dbhost="$id-db" --quiet
# Deprecations are the way a WordPress or PHP upgrade actually breaks a plugin:
# nothing fails, a notice appears, and six months later it is a fatal. They are
# logged to a file (not the page) and checked at the end of this script.
wp config set WP_DEBUG true --raw --quiet
wp config set WP_DEBUG_LOG true --raw --quiet
wp config set WP_DEBUG_DISPLAY false --raw --quiet
wp core install --url=http://plugin.test --title="$PLUGIN_SLUG CI" \
--admin_user=admin --admin_password=admin --admin_email=ci@example.com \
--skip-email --quiet
echo " installed $(wp core version)"
if [ "$NEEDS_WOOCOMMERCE" = yes ]; then
ci_step "WooCommerce $WC_VERSION"
case "$WC_VERSION" in
latest)
wp plugin install woocommerce --activate --quiet
;;
beta)
# Resolved inside the container, which has PHP and network; the host
# runner is not guaranteed either.
target=$(docker exec -i -e SLUG=woocommerce "$id-cli" php < ci/latest-prerelease.php)
if [ -n "$target" ]; then
echo " prerelease available: $target"
wp plugin install woocommerce --version="$target" --activate --quiet
else
echo " no prerelease newer than stable right now — using the stable release"
wp plugin install woocommerce --activate --quiet
fi
;;
*)
wp plugin install woocommerce --version="$WC_VERSION" --activate --quiet
;;
esac
# HPOS, because that is what a shop set up in the last few years runs, and a
# plugin that touches orders behaves differently under it.
wp option update woocommerce_custom_orders_table_enabled yes >/dev/null
echo " installed $(wp plugin get woocommerce --field=version)"
fi
ci_step "$PLUGIN_SLUG"
# Exactly the files the release zip will contain, plus the site tests. Testing
# the working tree instead would test a plugin no shop ever receives: one
# unanchored .gitignore line is enough for a file to be present locally,
# absent from the release, and never missed until a customer installs it.
{ ./ci/dist-files.sh; printf '%s\n' ${SITE_TESTS:-}; } | tr '\n' '\0' | tar --null -T - -cf - \
| docker exec -i "$id-cli" sh -c \
"mkdir -p /var/www/html/wp-content/plugins/$PLUGIN_SLUG \
&& tar -xf - -C /var/www/html/wp-content/plugins/$PLUGIN_SLUG"
wp plugin activate "$PLUGIN_SLUG" --quiet
wp plugin list --name="$PLUGIN_SLUG" --field=status | grep -qx active \
|| { echo "The plugin did not stay active after activation." >&2; exit 1; }
echo " activated $(wp plugin get "$PLUGIN_SLUG" --field=version)"
for f in ${SITE_TESTS:-}; do
ci_step "$f"
wp eval-file "wp-content/plugins/$PLUGIN_SLUG/$f"
done
ci_step "PHP notices and deprecations"
# Only lines naming this plugin. WordPress core and WooCommerce deprecate their
# own things on every release, and failing on those would make the build red
# for something nobody here can fix — which is how a red build gets ignored.
log=$(wp eval 'echo WP_CONTENT_DIR;')/debug.log
if docker exec "$id-cli" test -f "$log"; then
if docker exec "$id-cli" grep -F "/plugins/$PLUGIN_SLUG/" "$log"; then
echo
ci_fail "The plugin logged the notices above on WordPress $(wp core version). They are the shape an update breaks in: harmless now, fatal two releases later."
exit 1
fi
echo " none from this plugin"
else
echo " nothing logged at all"
fi
ci_step "done"
echo "WordPress $(wp core version)$( [ "$NEEDS_WOOCOMMERCE" = yes ] && echo " + WooCommerce $(wp plugin get woocommerce --field=version)" ) on PHP $PHP_VERSION: green"