Skip to content

[plan] Parameterize engine.version to accept GitHub Actions expressions (injection-safe) #23841

@github-actions

Description

@github-actions

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 work

Expected Behavior

engine:
  id: copilot
  version: ${{ inputs.engine-version }}  # ✅ Expression string

Approach

  1. Identify compilation sites for engine.version:

    • Search pkg/workflow/copilot_engine_installation.go, claude_engine.go, codex_engine.go, gemini_engine.go for where config.Version is used.
    • Each engine likely emits a different step that uses the version string.
  2. Update EngineConfig in pkg/workflow/engine.go:

    • The Version field is already a string; no type change needed.
    • Add expression detection: if version value matches ${{ ... }}, mark it as a runtime expression.
  3. Update frontmatter extraction in pkg/workflow/engine.go (ExtractEngineConfig):

    • Accept ${{ ... }} strings as valid version values (currently only plain strings are accepted).
  4. 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_VERSION in the shell command.
    • This prevents shell injection regardless of expression content.
  5. Update JSON schema to accept expression strings for engine.version.

  6. Add tests covering expression versions for each engine.

Files to Modify

  • pkg/workflow/engine.go — expression detection in ExtractEngineConfig
  • pkg/workflow/copilot_engine_installation.go — safe env var injection
  • pkg/workflow/claude_engine.go, codex_engine.go, gemini_engine.go — same
  • pkg/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.yml via 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

Metadata

Metadata

Labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions