mirror of
https://github.com/github/spec-kit.git
synced 2026-07-08 23:59:55 +08:00
fix(workflows): shell step validate() rejects non-string run (#3348)
ShellStep.validate() only checked that 'run' was present, so run: (null) or a GitHub-Actions-style list validated clean; execute() then str()-coerces the value and invokes it under shell=True, literally running 'None' or "['echo', 'hi']" as a command. Add a type check after the presence check, mirroring the command-step (#3262) and gate options validation. Expression strings ('{{ ... }}') are strings, so they stay valid. Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -90,6 +90,16 @@ class ShellStep(StepBase):
|
||||
errors.append(
|
||||
f"Shell step {config.get('id', '?')!r} is missing 'run' field."
|
||||
)
|
||||
elif not isinstance(config["run"], str):
|
||||
# execute() str()-coerces run and invokes it under shell=True, so a
|
||||
# null or list 'run' would run the Python repr ('None', "['echo']")
|
||||
# as a command. Reject non-strings at validation, mirroring the
|
||||
# command-step input/options and gate options type checks. An
|
||||
# expression like "{{ ... }}" is still a str, so it stays valid.
|
||||
errors.append(
|
||||
f"Shell step {config.get('id', '?')!r}: 'run' must be a string, "
|
||||
f"got {type(config['run']).__name__}."
|
||||
)
|
||||
output_format = config.get("output_format")
|
||||
if output_format is not None and output_format != "json":
|
||||
errors.append(
|
||||
|
||||
Reference in New Issue
Block a user