Skip to content

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

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions