From 197c2337bd4e38c964b54ca25f762474e420a501 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 25 Feb 2026 22:41:10 +0000 Subject: [PATCH 1/9] Initial plan From 0827ef6bf80484813e475dff11ddaff70fbaa4ec Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 25 Feb 2026 23:01:43 +0000 Subject: [PATCH 2/9] Fix: ssh option with docker scheme in root of wp-cli.yml config - Configurator.php: Allow root-level `ssh` key to apply as default for aliased commands by excluding it from the alias-spec skip in merge_yml() - Runner.php: Add WP_CLI_SSH_RUN=1 env var to remote commands to prevent recursive SSH/docker calls when config file is mounted inside a container - Runner.php: Check WP_CLI_SSH_RUN in start() to skip config-based SSH when already inside an SSH/container session (CLI --ssh= still works) - flags.feature: Update existing SSH test assertions and add two new scenarios for root-level docker SSH config (with and without alias) Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com> --- features/flags.feature | 30 ++++++++++++++++++++++++++++-- php/WP_CLI/Configurator.php | 2 +- php/WP_CLI/Runner.php | 14 +++++++++++--- 3 files changed, 40 insertions(+), 6 deletions(-) diff --git a/features/flags.feature b/features/flags.feature index 9f89efc8c5..45c2a15078 100644 --- a/features/flags.feature +++ b/features/flags.feature @@ -344,14 +344,14 @@ Feature: Global flags When I try `WP_CLI_STRICT_ARGS_MODE=1 wp --debug --ssh=/ --version` Then STDERR should contain: """ - Running SSH command: ssh -T -vvv '' 'WP_CLI_STRICT_ARGS_MODE=1 wp + Running SSH command: ssh -T -vvv '' 'WP_CLI_STRICT_ARGS_MODE=1 WP_CLI_SSH_RUN=1 wp """ Scenario: SSH flag should support changing directories When I try `wp --debug --ssh=wordpress:/my/path --version` Then STDERR should contain: """ - Running SSH command: ssh -T -vvv 'wordpress' 'cd '\''/my/path'\''; wp + Running SSH command: ssh -T -vvv 'wordpress' 'cd '\''/my/path'\''; WP_CLI_SSH_RUN=1 wp """ Scenario: SSH flag should support Docker @@ -361,6 +361,32 @@ Feature: Global flags Running SSH command: docker exec --user 'user' 'wordpress' sh -c """ + Scenario: Root-level ssh config should support Docker scheme + Given an empty directory + And a wp-cli.yml file: + """ + ssh: docker:user@wordpress + """ + When I try `WP_CLI_DOCKER_NO_INTERACTIVE=1 wp --debug --version` + Then STDERR should contain: + """ + Running SSH command: docker exec --user 'user' 'wordpress' sh -c + """ + + Scenario: Root-level ssh config should support Docker scheme with an alias + Given an empty directory + And a wp-cli.yml file: + """ + ssh: docker:user@wordpress + @local: + path: /var/www/html + """ + When I try `WP_CLI_DOCKER_NO_INTERACTIVE=1 wp @local --debug --version` + Then STDERR should contain: + """ + Running SSH command: docker exec --user 'user' 'wordpress' sh -c + """ + Scenario: Customize config-spec with WP_CLI_CONFIG_SPEC_FILTER_CALLBACK Given a WP installation And a wp-cli-early-require.php file: diff --git a/php/WP_CLI/Configurator.php b/php/WP_CLI/Configurator.php index 6e42a9e653..2ffd561e6f 100644 --- a/php/WP_CLI/Configurator.php +++ b/php/WP_CLI/Configurator.php @@ -322,7 +322,7 @@ public function merge_yml( $path, $current_alias = null ) { self::arrayify( $value ); $this->config[ $key ] = array_merge( $this->config[ $key ], $value ); } else { - if ( $current_alias && in_array( $key, self::$alias_spec, true ) ) { + if ( $current_alias && in_array( $key, self::$alias_spec, true ) && 'ssh' !== $key ) { continue; } $this->config[ $key ] = $value; diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 855db8b6d0..bd6da1d4f5 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -678,6 +678,7 @@ private function run_ssh_command( string $connection_string ): void { if ( getenv( 'WP_CLI_STRICT_ARGS_MODE' ) ) { $env_vars .= 'WP_CLI_STRICT_ARGS_MODE=1 '; } + $env_vars .= 'WP_CLI_SSH_RUN=1 '; $wp_binary = getenv( 'WP_CLI_SSH_BINARY' ) ?: 'wp'; $wp_args = array_slice( (array) $GLOBALS['argv'], 1 ); @@ -1432,9 +1433,16 @@ public function start() { } if ( $this->config['ssh'] ) { - // @phpstan-ignore cast.string - $this->run_ssh_command( (string) $this->config['ssh'] ); - return; + // Don't recurse if SSH came from config file and we're already in an SSH/container session. + // Still allow SSH if it was explicitly passed via --ssh= on the CLI (present in runtime_config). + $ssh_from_cli = isset( $this->runtime_config['ssh'] ) && '' !== $this->runtime_config['ssh']; + if ( getenv( 'WP_CLI_SSH_RUN' ) && ! $ssh_from_cli ) { + WP_CLI::debug( 'Skipping SSH from config file: already running inside an SSH/container session. Use --ssh= flag to override.', 'bootstrap' ); + } else { + // @phpstan-ignore cast.string + $this->run_ssh_command( (string) $this->config['ssh'] ); + return; + } } // Log WP-CLI HTTP requests From 54330a8fb01f4a0fe64d8d8cf8c231d1af0f33b3 Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Thu, 26 Feb 2026 01:56:04 +0100 Subject: [PATCH 3/9] Update php/WP_CLI/Runner.php Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- php/WP_CLI/Runner.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 07552847cd..aebf885acd 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -1439,7 +1439,7 @@ public function start() { // Still allow SSH if it was explicitly passed via --ssh= on the CLI (present in runtime_config). $ssh_from_cli = isset( $this->runtime_config['ssh'] ) && '' !== $this->runtime_config['ssh']; if ( getenv( 'WP_CLI_SSH_RUN' ) && ! $ssh_from_cli ) { - WP_CLI::debug( 'Skipping SSH from config file: already running inside an SSH/container session. Use --ssh= flag to override.', 'bootstrap' ); + WP_CLI::debug( 'Skipping SSH from config file: already running inside an SSH/container session. Use the `--ssh` flag to override.', 'bootstrap' ); } else { // @phpstan-ignore cast.string $this->run_ssh_command( (string) $this->config['ssh'] ); From a344aae8801073b714043840211918e021047ffb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 26 Feb 2026 09:06:15 +0000 Subject: [PATCH 4/9] Fix: propagate WP_CLI_SSH_RUN to docker-compose-run via -e flag For the docker-compose-run scheme, $wp_command was overwritten with implode(' ', $wp_args), dropping $env_vars. Since docker compose run doesn't invoke a shell, env var assignment prefix syntax doesn't work. Instead, pass WP_CLI_SSH_RUN=1 (and WP_CLI_STRICT_ARGS_MODE=1 if set) via -e flags on the `docker compose run` command itself. Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com> --- php/WP_CLI/Runner.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index aebf885acd..14b25b2bde 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -801,7 +801,12 @@ private function generate_ssh_command( $bits, $wp_command ) { } if ( 'docker-compose-run' === $bits['scheme'] ) { - $command = '%s run %s%s%s%s%s %s'; + $command = '%s run %s%s%s%s%s%s %s'; + + $env_flags = '-e WP_CLI_SSH_RUN=1 '; + if ( getenv( 'WP_CLI_STRICT_ARGS_MODE' ) ) { + $env_flags .= '-e WP_CLI_STRICT_ARGS_MODE=1 '; + } $escaped_command = sprintf( $command, @@ -810,6 +815,7 @@ private function generate_ssh_command( $bits, $wp_command ) { $bits['path'] ? '--workdir ' . escapeshellarg( $bits['path'] ) . ' ' : '', $is_stdout_tty || getenv( 'WP_CLI_DOCKER_NO_TTY' ) ? '' : '-T ', $is_stdin_tty || getenv( 'WP_CLI_DOCKER_NO_INTERACTIVE' ) ? '' : '-i ', + $env_flags, escapeshellarg( $bits['host'] ), $wp_command ); From 63b97018900964e8cfc365452bf2cf7f3d946d26 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 16 Mar 2026 21:48:35 +0000 Subject: [PATCH 5/9] Fix aliases.feature SSH command assertions to include WP_CLI_SSH_RUN=1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since run_ssh_command() now prepends WP_CLI_SSH_RUN=1 to the remote command, update five assertions in aliases.feature that check the exact SSH debug output to include WP_CLI_SSH_RUN=1: - Vagrant SSH test: 'wp --debug --version' → 'WP_CLI_SSH_RUN=1 wp ...' - Double-escape test: '; wp plugin list' → '; WP_CLI_SSH_RUN=1 wp ...' - Space-escape test: '; wp post create' → '; WP_CLI_SSH_RUN=1 wp ...' - Runtime alias tests (x2): 'env WP_CLI_RUNTIME_ALIAS= → 'WP_CLI_SSH_RUN=1 env WP_CLI_RUNTIME_ALIAS= Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com> --- features/aliases.feature | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/features/aliases.feature b/features/aliases.feature index 46421398fd..0561dd58cc 100644 --- a/features/aliases.feature +++ b/features/aliases.feature @@ -215,7 +215,7 @@ Feature: Create shortcuts to specific WordPress installs When I try `wp @foo --debug --version` Then STDERR should contain: """ - Running SSH command: ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -T -vvv '' 'wp --debug --version' + Running SSH command: ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -T -vvv '' 'WP_CLI_SSH_RUN=1 wp --debug --version' """ Scenario: SSH alias expands tilde in path @@ -287,7 +287,7 @@ Feature: Create shortcuts to specific WordPress installs When I try `wp @foo plugin list --debug` Then STDERR should contain: """ - Running SSH command: ssh -T -vvv 'user@host' 'cd '\''/path/to/wordpress'\''; wp plugin list --debug' + Running SSH command: ssh -T -vvv 'user@host' 'cd '\''/path/to/wordpress'\''; WP_CLI_SSH_RUN=1 wp plugin list --debug' """ Scenario: SSH commands correctly escape arguments with spaces @@ -301,7 +301,7 @@ Feature: Create shortcuts to specific WordPress installs When I try `wp @foo post create --post_title=My Title --debug` Then STDERR should contain: """ - Running SSH command: ssh -T -vvv 'user@host' 'cd '\''/path/to/wordpress'\''; wp post create --post_title=My Title + Running SSH command: ssh -T -vvv 'user@host' 'cd '\''/path/to/wordpress'\''; WP_CLI_SSH_RUN=1 wp post create --post_title=My Title """ Scenario: Uses env command for runtime alias with separate path line @@ -316,7 +316,7 @@ Feature: Create shortcuts to specific WordPress installs When I try `wp @foo --debug --version` Then STDERR should contain: """ - Running SSH command: ssh -T -vvv 'user@host' 'env WP_CLI_RUNTIME_ALIAS= + Running SSH command: ssh -T -vvv 'user@host' 'WP_CLI_SSH_RUN=1 env WP_CLI_RUNTIME_ALIAS= """ And STDERR should contain: """ @@ -367,7 +367,7 @@ Feature: Create shortcuts to specific WordPress installs When I try `wp @foo --debug --version` Then STDERR should contain: """ - Running SSH command: ssh -T -vvv 'user@host' 'env WP_CLI_RUNTIME_ALIAS= + Running SSH command: ssh -T -vvv 'user@host' 'WP_CLI_SSH_RUN=1 env WP_CLI_RUNTIME_ALIAS= """ And STDERR should contain: """ From d1b34fc614dd8e5f7cc3ac59c23764545311a3a7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 17 Mar 2026 09:42:08 +0000 Subject: [PATCH 6/9] Fix flags.feature SSH args assertions to include WP_CLI_SSH_RUN=1 The two SSH args test scenarios were checking for 'wp at the end of the SSH command string, but now the command includes WP_CLI_SSH_RUN=1 before wp. Update the assertions to match. Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com> --- features/flags.feature | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/flags.feature b/features/flags.feature index 8192d56075..d5f4ced0b2 100644 --- a/features/flags.feature +++ b/features/flags.feature @@ -430,14 +430,14 @@ Feature: Global flags When I try `wp --debug --ssh=wordpress --ssh-args="-o ConnectTimeout=5" --version` Then STDERR should contain: """ - Running SSH command: ssh '-o ConnectTimeout=5' -T -vvv 'wordpress' 'wp + Running SSH command: ssh '-o ConnectTimeout=5' -T -vvv 'wordpress' 'WP_CLI_SSH_RUN=1 wp """ Scenario: Multiple SSH args should be passed to SSH command When I try `wp --debug --ssh=wordpress --ssh-args="-o ConnectTimeout=5" --ssh-args="-o ServerAliveInterval=10" --version` Then STDERR should contain: """ - Running SSH command: ssh '-o ConnectTimeout=5' '-o ServerAliveInterval=10' -T -vvv 'wordpress' 'wp + Running SSH command: ssh '-o ConnectTimeout=5' '-o ServerAliveInterval=10' -T -vvv 'wordpress' 'WP_CLI_SSH_RUN=1 wp """ Scenario: SSH args should be passed to Docker command From ea0025b004975750efc44b4e4f3d84b5e3ec22f0 Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Tue, 17 Mar 2026 10:43:35 +0100 Subject: [PATCH 7/9] Update php/WP_CLI/Runner.php --- php/WP_CLI/Runner.php | 1 - 1 file changed, 1 deletion(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 4d3d4b93f2..89777a6b3f 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -1526,7 +1526,6 @@ function ( $alias ) { } else { // @phpstan-ignore cast.string $this->run_ssh_command( (string) $this->config['ssh'] ); - return; } } From 9e86238ed051b8a3b98f956333807e7c4b89c934 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 17 Mar 2026 14:35:29 +0000 Subject: [PATCH 8/9] Fix sprintf placeholder count mismatch in docker-compose-run command The format string for docker-compose-run had 8 %s placeholders but 9 values were passed (added $env_flags without adding a corresponding placeholder). Add the missing %s to the format string. Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com> --- php/WP_CLI/Runner.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index 89777a6b3f..d3d0cf18d3 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -831,7 +831,7 @@ private function generate_ssh_command( $bits, $wp_command ) { } if ( 'docker-compose-run' === $bits['scheme'] ) { - $command = '%s run %s%s%s%s%s%s %s'; + $command = '%s run %s%s%s%s%s%s%s %s'; $env_flags = '-e WP_CLI_SSH_RUN=1 '; if ( getenv( 'WP_CLI_STRICT_ARGS_MODE' ) ) { From a0c5c5d4820bac71cd80dff84f99bcaa246c8fa1 Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Fri, 20 Mar 2026 23:54:46 +0100 Subject: [PATCH 9/9] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- php/WP_CLI/Configurator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/WP_CLI/Configurator.php b/php/WP_CLI/Configurator.php index a80f994f8c..cfd93a02d3 100644 --- a/php/WP_CLI/Configurator.php +++ b/php/WP_CLI/Configurator.php @@ -434,7 +434,7 @@ public function merge_yml( $path, $current_alias = null ) { self::arrayify( $value ); $this->config[ $key ] = array_merge( $this->config[ $key ], $value ); } else { - if ( $current_alias && in_array( $key, self::$alias_spec, true ) && 'ssh' !== $key ) { + if ( $current_alias && in_array( $key, self::$alias_spec, true ) && ! in_array( $key, array( 'ssh', 'ssh-args', 'proxyjump', 'key' ), true ) ) { continue; } $this->config[ $key ] = $value;