#!/usr/bin/env bash # Install the PREVIOUS version into a throwaway shop and let WordPress update # it from the published feed, on its own. # # This is the only check that proves the whole chain: header, filter, feed, # download address, zip layout and the folder WordPress unpacks into. Every # part of it can be individually correct and the update still not arrive — # a package URL on an address the shop cannot reach, a zip whose top-level # directory is not the plugin slug, a version WordPress does not consider # newer. Run it after a release. # # FROM_VERSION=1.3.1 ci/update-smoke.sh set -euo pipefail cd "$(dirname "$0")/.." . ci/lib.sh ci_load_conf FROM_VERSION="${FROM_VERSION:-0.0.1}" expected=$(ci_plugin_version) id="wpup-$$" 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 "Installing $PLUGIN_SLUG $FROM_VERSION, then asking WordPress to update it. Expecting $expected." 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 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 sleep infinity >/dev/null 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 [ "$i" = 60 ] && { echo "MariaDB never came up." >&2; exit 1; } sleep 2 done ci_step "a shop running the previous version" wp core download --quiet wp config create --dbname=wordpress --dbuser=wordpress --dbpass=wordpress --dbhost="$id-db" --quiet wp core install --url=http://plugin.test --title="update smoke" --admin_user=admin \ --admin_password=admin --admin_email=ci@example.com --skip-email --quiet [ "$NEEDS_WOOCOMMERCE" = yes ] && wp plugin install woocommerce --activate --quiet # The working tree, with the version wound back. WordPress compares the feed # against this header and nothing else, so this is what makes it an "older" # install as far as the update check is concerned. ./ci/dist-files.sh | 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" docker exec "$id-cli" sed -i -E \ "s/^([[:space:]]*\*[[:space:]]*Version:[[:space:]]*).*/\1$FROM_VERSION/" \ "/var/www/html/wp-content/plugins/$PLUGIN_SLUG/$PLUGIN_MAIN" wp plugin activate "$PLUGIN_SLUG" --quiet installed=$(wp plugin get "$PLUGIN_SLUG" --field=version) echo " installed $installed" [ "$installed" = "$FROM_VERSION" ] || { echo "Winding the version back did not take." >&2; exit 1; } ci_step "what WordPress thinks, unprompted" # Not the plugin's own code — WordPress's update check, the same one that runs # on a schedule in a live shop. wp plugin update --all --dry-run 2>&1 | sed 's/^/ /' || true available=$(wp plugin list --name="$PLUGIN_SLUG" --field=update) echo " update status: $available" [ "$available" = available ] || { echo "WordPress was not offered an update. The header, the filter or the feed is wrong." >&2 exit 1 } ci_step "letting WordPress install it" wp plugin update "$PLUGIN_SLUG" 2>&1 | sed 's/^/ /' now=$(wp plugin get "$PLUGIN_SLUG" --field=version) status=$(wp plugin list --name="$PLUGIN_SLUG" --field=status) echo echo " version after update: $now (was $FROM_VERSION)" echo " status: $status" [ "$now" = "$expected" ] || { echo "Expected $expected after the update." >&2; exit 1; } [ "$status" = active ] || { echo "The plugin is no longer active after updating itself." >&2; exit 1; } # A zip whose top-level directory is not the slug installs a SECOND copy # beside the first instead of replacing it, and the old one stays active. count=$(docker exec "$id-cli" sh -c 'ls /var/www/html/wp-content/plugins | wc -l') docker exec "$id-cli" ls /var/www/html/wp-content/plugins | sed 's/^/ /' ci_step "and it still works afterwards" wp eval 'echo WC_EDM_VERSION;' | sed 's/^/ WC_EDM_VERSION: /' wp plugin list --name="$PLUGIN_SLUG" --field=update | grep -qx none \ && echo " WordPress no longer offers an update — the header and the feed agree." echo echo "WordPress found, downloaded and installed $expected from the published feed on its own."