feat(operation:run): add --parameter option for runtime operations - #22
feat(operation:run): add --parameter option for runtime operations#22ralt wants to merge 1 commit into
Conversation
1e5e867 to
fa14cd1
Compare
Allow passing parameters to runtime operations via the --parameter option, which accepts repeated values or comma-separated lists. Requires platformsh/client ^3.0.0-beta3 for the new $parameters argument in execRuntimeOperation(). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
fa14cd1 to
7c0af35
Compare
pjcdawkins
left a comment
There was a problem hiding this comment.
Thanks for this, and apologies it sat unreviewed for so long — that is on us, not you.
Starting with the important part: both red checks are ours, not yours. Nothing in your PHP needs to change to make CI pass.
The two CI failures
legacy-php (PHPStan) — the annotation is RunCommand.php:130 EnvironmentDeployment::execRuntimeOperation() invoked with 3 parameters, 2 required. When this ran on 2026-03-02, legacy/composer.lock still pinned platformsh/client 3.0.0-beta2, whose signature was execRuntimeOperation(string $name, string $service). The third array $parameters = [] argument arrived in 3.0.0-beta5, which we pulled in via 8707228 (#32) — merged 2026-03-20, eighteen days after your CI run. Main now pins beta5. Running PHPStan level 8 on your file against the currently vendored client leaves only the pre-existing baselined $service nullable error, so the step passes on a rebase.
check (Security workflow) — the annotation is Dependency review is not supported on this repository. That was a repository setting on our side. It has since been enabled, and check now passes on later PRs including ones from forks. A rebase push re-runs it green.
So: merge or rebase onto current main and both go green. Your only file is otherwise byte-identical to main's, so it should apply cleanly. Since the branch lives in upsun/cli rather than a fork, we can also refresh it for you — say the word if you would rather not bother.
The one change worth making
--parameter currently goes through ArrayArgument::getOption() (RunCommand.php:43 and :129), which splits each value on commas and whitespace (ArrayArgument::split(), legacy/src/Console/ArrayArgument.php:59). That means:
operation:run migrate --parameter "--target=/var/www/my app"
is sent as two parameters, ["--target=/var/www/my", "app"], and no amount of quoting can prevent it — the split happens after the shell and after Symfony's parsing.
This is a functional problem rather than a style preference, because the API treats each parameter as one shell-quoted positional argument (it uses shlex.join), and its own functional tests cover parameters containing whitespace. So a value with a space is a supported case that this option cannot currently express.
Every other SPLIT_HELP user in the CLI passes lists of identifiers or enum values — project IDs, activity states, environment types — none of which contain spaces. The closest analog for opaque user-supplied values is source-operation:run --variable (legacy/src/Command/SourceOperation/RunCommand.php:34), which deliberately uses VALUE_REQUIRED|VALUE_IS_ARRAY with a raw $input->getOption() and no splitting.
Suggested change: drop the ArrayArgument usage and the . ArrayArgument::SPLIT_HELP from the description, read the option directly, and make the help text say that one --parameter equals exactly one parameter, repeatable and order-preserving.
Smaller things, take or leave
- A test would be cheap now in a way it was not when you opened this:
integration-tests/runtime_operation_test.goalready captures the runtime-operations POST body (lines 79-89), so adding--parameter foo --parameter barto therunsubtest and assertingbody["parameters"]would pin the wire format in a few lines. That file was added 2026-05-26, after you opened this, so it was not available to you — but you will be rebasing past it anyway. A case with a value containing a space would document the intended semantics. - The example at
RunCommand.php:45uses--parameter param1 --parameter param2, which does not convey what a parameter is. Comparesource-operation:run's example (update --variable env:FOO=bar). Something likemigrate --app app --parameter --forcereads better. - Unrelated to you:
ArrayArgument::split()preserves array keys afterarray_filter(), so a leading comma or space (--parameter ",a") produces a JSON object instead of an array. It is a pre-existing helper defect that already affects other callers on main, and it becomes moot for this command once the splitting goes away. We will fix the helper separately.
Once the --parameter handling is direct and the branch is rebased, this is good to merge.
Review by Claude Code.
Allow passing parameters to runtime operations via the --parameter option, which accepts repeated values or comma-separated lists.