79 lines
2.8 KiB
Bash
79 lines
2.8 KiB
Bash
#!/usr/bin/env bash
|
|||
|
|
# Build the installable plugin zip and check it is actually installable.
|
||
|
|
#
|
||
|
|
# Writes build/<slug>.zip, containing a single top-level <slug>/ directory —
|
||
|
|
# WordPress identifies an installed plugin by that folder name, so a zip that
|
||
|
|
# unpacks to anything else installs a second copy alongside the first instead
|
||
|
|
# of updating it.
|
||
|
|
set -euo pipefail
|
||
|
|
|
||
|
|
cd "$(dirname "$0")/.."
|
||
|
|
. ci/lib.sh
|
||
|
|
ci_load_conf
|
||
|
|
|
||
|
|
version=$(ci_plugin_version)
|
||
|
|
[ -n "$version" ] || { echo "Could not read Version: from $PLUGIN_MAIN." >&2; exit 1; }
|
||
|
|
|
||
|
|
rm -rf build
|
||
|
|
mkdir -p "build/$PLUGIN_SLUG"
|
||
|
|
|
||
|
|
# One list, shared with the hygiene checks and the test site, so a file cannot
|
||
|
|
# be excluded from the tests and included in the release.
|
||
|
|
./ci/dist-files.sh | while IFS= read -r f; do
|
||
|
|
mkdir -p "build/$PLUGIN_SLUG/$(dirname "$f")"
|
||
|
|
cp "$f" "build/$PLUGIN_SLUG/$f"
|
||
|
|
done
|
||
|
|
|
||
|
|
# `zip` is on GitHub's runners but not in every Gitea runner image, and a
|
||
|
|
# release that fails on the packaging step is the most annoying possible place
|
||
|
|
# to discover a missing tool. python3 is present in both.
|
||
|
|
(
|
||
|
|
cd build
|
||
|
|
if command -v zip >/dev/null 2>&1; then
|
||
|
|
zip -rq "$PLUGIN_SLUG.zip" "$PLUGIN_SLUG"
|
||
|
|
elif command -v python3 >/dev/null 2>&1; then
|
||
|
|
python3 -m zipfile -c "$PLUGIN_SLUG.zip" "$PLUGIN_SLUG"
|
||
|
|
else
|
||
|
|
echo "Neither zip nor python3 is available to build the archive." >&2
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
)
|
||
|
|
|
||
|
|
# Listing entries by name rather than parsing `unzip -l` output, with the same
|
||
|
|
# python3 fallback as above because unzip is not guaranteed on a runner either.
|
||
|
|
zip_entries() {
|
||
|
|
if command -v unzip >/dev/null 2>&1; then
|
||
|
|
unzip -Z1 "build/$PLUGIN_SLUG.zip"
|
||
|
|
else
|
||
|
|
python3 -c 'import sys,zipfile;print("\n".join(zipfile.ZipFile(sys.argv[1]).namelist()))' \
|
||
|
|
"build/$PLUGIN_SLUG.zip"
|
||
|
|
fi
|
||
|
|
}
|
||
|
|
|
||
|
|
ci_step "what the zip contains"
|
||
|
|
zip_entries | sed 's/^/ /'
|
||
|
|
|
||
|
|
ci_step "checks"
|
||
|
|
zip_entries | grep -qx "$PLUGIN_SLUG/$PLUGIN_MAIN" \
|
||
|
|
|| { echo "The main plugin file is not in the zip." >&2; exit 1; }
|
||
|
|
echo " the main file is present"
|
||
|
|
|
||
|
|
# A leaked ci/ or tests/ directory is not merely untidy: everything under
|
||
|
|
# wp-content/plugins/ can in principle be fetched over HTTP from a live shop.
|
||
|
|
for unwanted in ci tests docs .git .github .gitea; do
|
||
|
|
if zip_entries | grep -q "^$PLUGIN_SLUG/$unwanted/"; then
|
||
|
|
echo "The zip contains $unwanted/, which must never reach a shop." >&2
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
done
|
||
|
|
echo " no tooling, tests or git files leaked in"
|
||
|
|
|
||
|
|
# Every entry sits under exactly one top-level directory named for the slug.
|
||
|
|
strays=$(zip_entries | grep -v "^$PLUGIN_SLUG/" || true)
|
||
|
|
[ -z "$strays" ] || { echo "Files outside $PLUGIN_SLUG/ in the zip:" >&2; echo "$strays" >&2; exit 1; }
|
||
|
|
echo " everything unpacks into $PLUGIN_SLUG/"
|
||
|
|
|
||
|
|
size=$(du -h "build/$PLUGIN_SLUG.zip" | cut -f1)
|
||
|
|
echo
|
||
|
|
echo "build/$PLUGIN_SLUG.zip — version $version, $size"
|