Skip to content

Add compiler guardrail to reject ${{ ... }} in compiled run scripts#32048

Merged
pelikhan merged 5 commits into
mainfrom
copilot/add-compiler-runtime-check
May 14, 2026
Merged

Add compiler guardrail to reject ${{ ... }} in compiled run scripts#32048
pelikhan merged 5 commits into
mainfrom
copilot/add-compiler-runtime-check

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 14, 2026

Bug Fix

This addresses a compiler regression gap: generated .lock.yml files could still carry GitHub Actions expressions directly in shell run scripts (for example ${{ github.token }}). Compiled workflows should never do this; expressions must be rewritten into env bindings and referenced as shell variables.

What was the bug?

Compiled workflow validation only enforced template-injection checks for selected unsafe contexts, so non-unsafe expressions could still appear inline in run blocks and bypass the intended rewrite contract.

How did you fix it?

  • Regression guardrail in compiler validation
    • Added a strict check that rejects any ${{ ... }} expression found inside run script content in compiled YAML.
  • Coverage of both validation execution paths
    • Applied the check when YAML is already parsed (normal schema-validation path).
    • Applied the check in skip-validation mode via run-block expression pre-scan + parse-on-demand path.
  • Error surface for fast triage
    • Added a dedicated compiler-regression error with expression/snippet examples and expected safe pattern.
  • Focused regression tests
    • Extended path-parity tests with a concrete ${{ github.token }} case to ensure both paths fail consistently when inline expressions remain in run.

Example

# rejected (compiler regression signal)
run: echo "${{ github.token }}"

# expected compiler output pattern
env:
  GH_TOKEN: ${{ github.token }}
run: echo "$GH_TOKEN"

Testing

Covered by existing workflow/template-injection validation tests with added regression assertions for ${{ github.token }} in both compiler validation paths.

Copilot AI and others added 2 commits May 14, 2026 04:16
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title Add compiler guardrail for GitHub expressions in run scripts Add compiler guardrail to reject ${{ ... }} in compiled run scripts May 14, 2026
Copilot AI requested a review from pelikhan May 14, 2026 04:18
@pelikhan pelikhan marked this pull request as ready for review May 14, 2026 04:53
Copilot AI review requested due to automatic review settings May 14, 2026 04:53
@pelikhan
Copy link
Copy Markdown
Collaborator

@copilot recompile

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a compiler validation guardrail to detect compiler regressions where raw GitHub Actions expressions (${{ ... }}) remain embedded in compiled run: scripts, and ensures consistent behavior across both schema-validation paths.

Changes:

  • Adds a generalized run:-block expression scanner and applies it in skip-validation mode to decide when to reparse YAML.
  • Introduces a parsed-workflow validator that rejects any remaining ${{ ... }} inside run: scripts and surfaces a dedicated “compiler regression” error message.
  • Extends path-parity tests to assert both validation paths fail when run: contains ${{ github.token }} inline.
Show a summary per file
File Description
pkg/workflow/template_injection_validation.go Adds generalized run-block scanning and a new parsed-workflow guardrail validator for raw expressions in run: scripts.
pkg/workflow/template_injection_utils.go Adds a dedicated error formatter for the new compiler-regression guardrail.
pkg/workflow/compiler.go Wires the new guardrail into both schema-enabled and skip-validation compilation paths.
pkg/workflow/compiler_template_injection_both_paths_test.go Adds regression tests to ensure both validation paths reject inline ${{ ... }} in run:.

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 5/5 changed files
  • Comments generated: 1

Comment on lines +221 to +225
for _, runContent := range runBlocks {
expressions := inlineExpressionRegex.FindAllString(runContent, -1)
for _, expr := range expressions {
snippet := extractRunSnippet(runContent, expr)
violations = append(violations, TemplateInjectionViolation{
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented May 14, 2026

@copilot recompile

Recompiled and pushed in 95cf022.

It includes the lockfile regeneration plus the guardrail follow-ups needed for compile to pass with the new run-script checks.

@pelikhan
Copy link
Copy Markdown
Collaborator

@copilot review all comments

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented May 14, 2026

@copilot review all comments

Addressed the actionable review feedback and pushed f695af8.

Change made:

  • Aligned validateNoGitHubExpressionsInRunScriptsFromParsed with existing heredoc handling by excluding heredoc content from run-script expression scanning (removeHeredocContent), preventing heredoc false positives.
  • Added both-path regression coverage to confirm expressions inside heredocs are allowed in both schema-enabled and skip-validation paths.

@pelikhan pelikhan merged commit 2d56685 into main May 14, 2026
@pelikhan pelikhan deleted the copilot/add-compiler-runtime-check branch May 14, 2026 05:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants