-
Notifications
You must be signed in to change notification settings - Fork 328
[plan] Parameterize engine.version to accept GitHub Actions expressions (injection-safe) #23841
Description
Objective
Allow the engine.version frontmatter field to accept GitHub Actions expression strings (e.g. ${{ inputs.engine-version }}), enabling reusable workflow_call workflows to pin or override the engine version at call time.
Context
Tracked in issue #23724. The field is currently interpolated directly into shell arguments, so the implementation must include injection-safe handling. This is different from engine.id (which requires an architectural change) — engine.version is a version constraint string that can safely be passed through as a runtime value.
Security Concern
engine.version is interpolated into shell commands (e.g., npm install @github/copilot@<version>). When accepting expressions, the compiled YAML must ensure:
- The expression is embedded as a GitHub Actions expression (evaluated before shell execution), not concatenated into a raw shell string.
- The shell step must use the expression value via an env var, not via shell substitution, to avoid injection.
Current Behavior
engine:
id: copilot
version: "1.2.3" # Only literal strings workExpected Behavior
engine:
id: copilot
version: ${{ inputs.engine-version }} # ✅ Expression stringApproach
-
Identify compilation sites for
engine.version:- Search
pkg/workflow/copilot_engine_installation.go,claude_engine.go,codex_engine.go,gemini_engine.gofor whereconfig.Versionis used. - Each engine likely emits a different step that uses the version string.
- Search
-
Update
EngineConfiginpkg/workflow/engine.go:- The
Versionfield is already astring; no type change needed. - Add expression detection: if
versionvalue matches${{ ... }}, mark it as a runtime expression.
- The
-
Update frontmatter extraction in
pkg/workflow/engine.go(ExtractEngineConfig):- Accept
${{ ... }}strings as validversionvalues (currently only plain strings are accepted).
- Accept
-
Update each engine's compilation to emit the version expression safely:
- Instead of
npm install package@${version}, use an env var:env: { ENGINE_VERSION: "${{ inputs.engine-version }}" }and reference$ENGINE_VERSIONin the shell command. - This prevents shell injection regardless of expression content.
- Instead of
-
Update JSON schema to accept expression strings for
engine.version. -
Add tests covering expression versions for each engine.
Files to Modify
pkg/workflow/engine.go— expression detection inExtractEngineConfigpkg/workflow/copilot_engine_installation.go— safe env var injectionpkg/workflow/claude_engine.go,codex_engine.go,gemini_engine.go— samepkg/parser/schemas/main_workflow_schema.json— relax version constraint- Tests in
pkg/workflow/
Acceptance Criteria
-
engine.version: "1.2.3"still works (backward compatible) -
engine.version: ${{ inputs.engine-version }}compiles and the expression appears in the compiled.lock.ymlvia env var (not raw shell interpolation) - No shell injection is possible via the expression value
- Tests pass:
make agent-finish
Related to Ask: Runtime Parameterization of Compile-Time Frontmatter Fields #23724
Generated by Plan Command for issue #23724 · ◷
- expires on Apr 3, 2026, 5:44 AM UTC