From 83d3dc312a07f72c20f1f64f49ebd159f50ec87c Mon Sep 17 00:00:00 2001 From: Alain Schlesser Date: Tue, 21 Jul 2026 12:21:48 +0200 Subject: [PATCH 1/2] Honor WP_CLI_PHP and WP_CLI_PHP_ARGS in the Debian and RPM packages The Debian and RPM packages shipped the Phar directly as /usr/bin/wp, so it launched through its `#!/usr/bin/env php` shebang and never consulted WP_CLI_PHP or WP_CLI_PHP_ARGS. Those variables are only read by the bin/wp shell wrapper, which is not part of a Phar install, so a packaged wp-cli has never been able to select its PHP interpreter. Reported in wp-cli/wp-cli#5886. Install the Phar to /usr/share/wp-cli/wp-cli.phar and ship a small POSIX-sh launcher at /usr/bin/wp that selects the interpreter from WP_CLI_PHP (falling back to the php on PATH), exports WP_CLI_PHP_USED, and passes WP_CLI_PHP_ARGS through, mirroring the semantics of wp-cli's bin/wp. The launcher is generated inline because the deployment workflow downloads the build scripts standalone. `wp cli update` keeps working: it resolves the Phar via argv[0], so it rewrites /usr/share/wp-cli/wp-cli.phar and leaves the launcher untouched. Also replace the ls-only package verification steps with smoke tests that assert the package layout and that the launcher actually honors WP_CLI_PHP. Fixes #1078 --- .github/workflows/deployment.yml | 40 +++++++++++++++++++++++++++++-- utils/wp-cli-rpm.spec | 17 +++++++++---- utils/wp-cli-updatedeb.sh | 41 ++++++++++++++++++++++++++++---- utils/wp-cli-updaterpm.sh | 28 +++++++++++++++++++++- 4 files changed, 114 insertions(+), 12 deletions(-) diff --git a/.github/workflows/deployment.yml b/.github/workflows/deployment.yml index 9e70e9a40..cd05f8f2c 100644 --- a/.github/workflows/deployment.yml +++ b/.github/workflows/deployment.yml @@ -293,7 +293,22 @@ jobs: - name: Verify built RPM package contents run: | - ls rpm-src/noarch + set -euxo pipefail + rpm_file="$(ls rpm-src/noarch/wp-cli-*.noarch.rpm)" + # The package must ship a launcher in the bin dir and the Phar in the data dir. + rpm -qlp "$rpm_file" | tee /tmp/rpm-files.txt + grep -qx '/usr/bin/wp' /tmp/rpm-files.txt + grep -qx '/usr/share/wp-cli/wp-cli.phar' /tmp/rpm-files.txt + # /usr/bin/wp must be the shell launcher that honors WP_CLI_PHP / WP_CLI_PHP_ARGS, + # not the Phar itself. + mkdir -p rpm-verify + ( cd rpm-verify && rpm2cpio "../$rpm_file" | cpio -idm ) + test -x rpm-verify/usr/bin/wp + head -n1 rpm-verify/usr/bin/wp | grep -q '^#!/bin/sh' + grep -q 'WP_CLI_PHP' rpm-verify/usr/bin/wp + grep -q 'WP_CLI_PHP_ARGS' rpm-verify/usr/bin/wp + grep -q '/usr/share/wp-cli/wp-cli.phar' rpm-verify/usr/bin/wp + test -s rpm-verify/usr/share/wp-cli/wp-cli.phar - name: Copy RPM package into builds folder run: | @@ -346,7 +361,28 @@ jobs: - name: Verify built DEB package contents run: | - ls . + set -euxo pipefail + deb_file="$(ls php-wpcli*all.deb)" + # The package must ship a launcher in the bin dir and the Phar in the data dir. + dpkg-deb -c "$deb_file" | tee /tmp/deb-files.txt + grep -Eq ' \./usr/bin/wp$' /tmp/deb-files.txt + grep -Eq ' \./usr/share/wp-cli/wp-cli.phar$' /tmp/deb-files.txt + # Install the package and exercise the launcher (php ships on the runner). + sudo dpkg -i "$deb_file" || sudo apt-get install -f -y + test -x /usr/bin/wp + head -n1 /usr/bin/wp | grep -q '^#!/bin/sh' + test -s /usr/share/wp-cli/wp-cli.phar + # Default interpreter works. + wp --info + wp cli version + # WP_CLI_PHP selects the interpreter and WP_CLI_PHP_ARGS is passed through. + WP_CLI_PHP="$(command -v php)" WP_CLI_PHP_ARGS="-d memory_limit=256M" wp cli version + # A deliberately broken WP_CLI_PHP must actually be used: if it were ignored, + # this would still succeed. This is the regression guard for the whole fix. + if WP_CLI_PHP=/bin/false wp cli version 2>/dev/null; then + echo "WP_CLI_PHP was ignored by the launcher" >&2 + exit 1 + fi - name: Copy DEB package into builds folder run: | diff --git a/utils/wp-cli-rpm.spec b/utils/wp-cli-rpm.spec index 60c5f37fe..edfcd6cc2 100644 --- a/utils/wp-cli-rpm.spec +++ b/utils/wp-cli-rpm.spec @@ -1,11 +1,12 @@ Name: wp-cli Version: 0.0.0 -Release: 2%{?dist} +Release: 3%{?dist} Summary: The command line interface for WordPress License: MIT URL: http://wp-cli.org/ Source0: wp-cli.phar Source1: wp.1 +Source2: wp BuildArch: noarch %post @@ -29,16 +30,24 @@ chmod +x %{SOURCE0} %build %install -mkdir -p %{buildroot}%{_bindir} -install -p -m 0755 %{SOURCE0} %{buildroot}%{_bindir}/wp -mkdir -p %{buildroot}%{_mandir}/man1 +install -d -m 0755 %{buildroot}%{_datadir}/wp-cli +install -p -m 0755 %{SOURCE0} %{buildroot}%{_datadir}/wp-cli/wp-cli.phar +install -d -m 0755 %{buildroot}%{_bindir} +install -p -m 0755 %{SOURCE2} %{buildroot}%{_bindir}/wp +install -d -m 0755 %{buildroot}%{_mandir}/man1 install -p -m 0644 %{SOURCE1} %{buildroot}%{_mandir}/man1/ %files %attr(0755, root, root) %{_bindir}/wp +%dir %attr(0755, root, root) %{_datadir}/wp-cli +%attr(0755, root, root) %{_datadir}/wp-cli/wp-cli.phar %attr(0644, root, root) %{_mandir}/man1/wp.1* %changelog +* Tue Jul 21 2026 Alain Schlesser - 0.0.0-3 +- Install the Phar to %{_datadir}/wp-cli and ship a launcher at %{_bindir}/wp + so WP_CLI_PHP and WP_CLI_PHP_ARGS are honored. + * Tue Dec 12 2017 Murtaza Sarıaltun - 0.0.0-2 - Remove php requirements. - Update creating man page steps. diff --git a/utils/wp-cli-updatedeb.sh b/utils/wp-cli-updatedeb.sh index b04be32cc..09ab7bd12 100755 --- a/utils/wp-cli-updatedeb.sh +++ b/utils/wp-cli-updatedeb.sh @@ -40,6 +40,32 @@ Description: wp-cli is a set of command-line tools for managing EOF } +dump_launcher() { + # Write the launcher script that selects the PHP interpreter (honoring + # WP_CLI_PHP and WP_CLI_PHP_ARGS) and runs the bundled Phar. + # Quoted heredoc delimiter keeps the variables literal. + cat > "$1" <<'LAUNCHER' +#!/bin/sh +# +# WP-CLI launcher for the Debian package. +# Selects the PHP interpreter, honoring the WP_CLI_PHP and WP_CLI_PHP_ARGS +# environment variables, then runs the bundled Phar. +# See https://github.com/wp-cli/wp-cli-bundle/issues/1078 + +if [ -n "$WP_CLI_PHP" ]; then + php="$WP_CLI_PHP" +else + php="$(command -v php)" +fi + +export WP_CLI_PHP_USED="$php" + +# WP_CLI_PHP_ARGS is intentionally unquoted so multiple arguments are split. +# shellcheck disable=SC2086 +exec "$php" $WP_CLI_PHP_ARGS /usr/share/wp-cli/wp-cli.phar "$@" +LAUNCHER +} + set -e # Download the binary if needed @@ -76,13 +102,18 @@ fi # content dirs [ -d usr/bin ] || mkdir -p usr/bin +[ -d usr/share/wp-cli ] || mkdir -p usr/share/wp-cli -# move phar -mv ../wp-cli.phar usr/bin/wp -chmod +x usr/bin/wp +# install the Phar to a shared location and a launcher to the bin dir +mv ../wp-cli.phar usr/share/wp-cli/wp-cli.phar +chmod 0755 usr/share/wp-cli/wp-cli.phar +dump_launcher usr/bin/wp +chmod 0755 usr/bin/wp # get version -WPCLI_VER="$(usr/bin/wp cli version | cut -d " " -f 2)" +# The launcher hard-codes the installed /usr/share path, which does not exist +# inside the staging dir yet, so invoke PHP against the staged Phar directly. +WPCLI_VER="$(php usr/share/wp-cli/wp-cli.phar cli version | cut -d " " -f 2)" [ -z "$WPCLI_VER" ] && die 5 "Cannot get wp-cli version" echo "Current version: ${WPCLI_VER}" @@ -94,7 +125,7 @@ if ! [ -r usr/share/man/man1/wp.1.gz ]; then mkdir -p usr/share/man/man1 &> /dev/null { echo '.TH "WP" "1"' - usr/bin/wp --help + php usr/share/wp-cli/wp-cli.phar --help } \ | sed 's/^\([A-Z ]\+\)$/.SH "\1"/' \ | sed 's/^ wp$/wp \\- A command line interface for WordPress/' \ diff --git a/utils/wp-cli-updaterpm.sh b/utils/wp-cli-updaterpm.sh index e4697be53..3c571d25c 100755 --- a/utils/wp-cli-updaterpm.sh +++ b/utils/wp-cli-updaterpm.sh @@ -45,6 +45,30 @@ pushd "$SOURCE_DIR" > /dev/null mv ../wp-cli.phar wp-cli.phar cp ../wp-cli-rpm.spec wp-cli.spec +# Write the launcher script that selects the PHP interpreter (honoring +# WP_CLI_PHP and WP_CLI_PHP_ARGS) and runs the bundled Phar. +# Quoted heredoc delimiter keeps the variables literal. +cat > wp <<'LAUNCHER' +#!/bin/sh +# +# WP-CLI launcher for the RPM package. +# Selects the PHP interpreter, honoring the WP_CLI_PHP and WP_CLI_PHP_ARGS +# environment variables, then runs the bundled Phar. +# See https://github.com/wp-cli/wp-cli-bundle/issues/1078 + +if [ -n "$WP_CLI_PHP" ]; then + php="$WP_CLI_PHP" +else + php="$(command -v php)" +fi + +export WP_CLI_PHP_USED="$php" + +# WP_CLI_PHP_ARGS is intentionally unquoted so multiple arguments are split. +# shellcheck disable=SC2086 +exec "$php" $WP_CLI_PHP_ARGS /usr/share/wp-cli/wp-cli.phar "$@" +LAUNCHER + # Replace version placeholder WPCLI_VER="$(php wp-cli.phar cli version | cut -d " " -f 2)" if [ -z "$WPCLI_VER" ]; then @@ -52,7 +76,9 @@ if [ -z "$WPCLI_VER" ]; then fi echo "Current version: ${WPCLI_VER}" sed -i -e "s/^Version: .*\$/Version: ${WPCLI_VER}/" wp-cli.spec || die 4 "Version update failed" -sed -i -e "s/^\(\* .*\) 0\.0\.0-1\$/\1 ${WPCLI_VER}-1/" wp-cli.spec || die 5 "Changleog update failed" +# Rewrite the placeholder version in every changelog entry (0.0.0-N -> ${WPCLI_VER}-N) +# so the top entry stays coherent with the package version for rpmlint. +sed -i -e "s/^\(\* .*\) 0\.0\.0-\([0-9]\+\)\$/\1 ${WPCLI_VER}-\2/" wp-cli.spec || die 5 "Changelog update failed" # Create man page { From d81e91e44b4c7ea9c8b4dcfb0e51a03eddce626e Mon Sep 17 00:00:00 2001 From: Alain Schlesser Date: Tue, 21 Jul 2026 12:58:57 +0200 Subject: [PATCH 2/2] Assert WP_CLI_PHP_ARGS forwarding in the package smoke tests The DEB check passed even when the launcher silently dropped WP_CLI_PHP_ARGS, because `wp cli version` prints the same output either way, and the RPM check only grepped the launcher text. Replace both with a probe that stands in for PHP and asserts it received `-d memory_limit=256M` and inherited WP_CLI_PHP_USED before delegating, run through the installed DEB launcher and the extracted RPM launcher. --- .github/workflows/deployment.yml | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/.github/workflows/deployment.yml b/.github/workflows/deployment.yml index cd05f8f2c..a261f0e17 100644 --- a/.github/workflows/deployment.yml +++ b/.github/workflows/deployment.yml @@ -305,10 +305,22 @@ jobs: ( cd rpm-verify && rpm2cpio "../$rpm_file" | cpio -idm ) test -x rpm-verify/usr/bin/wp head -n1 rpm-verify/usr/bin/wp | grep -q '^#!/bin/sh' - grep -q 'WP_CLI_PHP' rpm-verify/usr/bin/wp - grep -q 'WP_CLI_PHP_ARGS' rpm-verify/usr/bin/wp grep -q '/usr/share/wp-cli/wp-cli.phar' rpm-verify/usr/bin/wp test -s rpm-verify/usr/share/wp-cli/wp-cli.phar + # Run the extracted launcher through a probe standing in for PHP: it must + # forward WP_CLI_PHP_ARGS before the Phar and export WP_CLI_PHP_USED. The + # probe asserts and exits without needing the Phar at its installed path. + printf '%s\n' \ + '#!/bin/sh' \ + 'case " $* " in' \ + ' *" -d memory_limit=256M "*) : ;;' \ + ' *) echo "WP_CLI_PHP_ARGS not forwarded: $*" >&2; exit 3 ;;' \ + 'esac' \ + '[ -n "$WP_CLI_PHP_USED" ] || { echo "WP_CLI_PHP_USED not exported" >&2; exit 4; }' \ + 'exit 0' \ + > /tmp/wp-cli-php-probe + chmod +x /tmp/wp-cli-php-probe + WP_CLI_PHP=/tmp/wp-cli-php-probe WP_CLI_PHP_ARGS="-d memory_limit=256M" rpm-verify/usr/bin/wp cli version - name: Copy RPM package into builds folder run: | @@ -375,8 +387,20 @@ jobs: # Default interpreter works. wp --info wp cli version - # WP_CLI_PHP selects the interpreter and WP_CLI_PHP_ARGS is passed through. - WP_CLI_PHP="$(command -v php)" WP_CLI_PHP_ARGS="-d memory_limit=256M" wp cli version + # A probe that stands in for PHP and asserts what the launcher forwarded: + # it must receive WP_CLI_PHP_ARGS before the Phar and inherit WP_CLI_PHP_USED. + printf '%s\n' \ + '#!/bin/sh' \ + 'case " $* " in' \ + ' *" -d memory_limit=256M "*) : ;;' \ + ' *) echo "WP_CLI_PHP_ARGS not forwarded: $*" >&2; exit 3 ;;' \ + 'esac' \ + '[ -n "$WP_CLI_PHP_USED" ] || { echo "WP_CLI_PHP_USED not exported" >&2; exit 4; }' \ + 'exit 0' \ + > /tmp/wp-cli-php-probe + chmod +x /tmp/wp-cli-php-probe + # Proves WP_CLI_PHP selects the interpreter AND WP_CLI_PHP_ARGS reaches it. + WP_CLI_PHP=/tmp/wp-cli-php-probe WP_CLI_PHP_ARGS="-d memory_limit=256M" wp cli version # A deliberately broken WP_CLI_PHP must actually be used: if it were ignored, # this would still succeed. This is the regression guard for the whole fix. if WP_CLI_PHP=/bin/false wp cli version 2>/dev/null; then