Conversation
- Extract expressions from MainWorkflowMarkdown (not MarkdownContent) to avoid processing imported content before substitution - Add needs.* and steps.* expression evaluation from environment variables in runtime_import.cjs - This allows needs.search_issues.outputs.* to be passed to the agent prompt Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
…in runtime-imported markdown Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Fixes runtime-imported markdown prompt rendering so workflows can use ${{ needs.* }} / ${{ steps.* }} expressions (notably for issue-monster), by surfacing those values via GH_AW_* environment variables and teaching runtime-import to resolve them from process.env.
Changes:
- Compiler: additionally extracts expressions from
MainWorkflowMarkdownand adds them to the env vars used during prompt generation/runtime interpolation. - Runtime:
runtime_import.cjsnow attempts to resolveneeds.*/steps.*expressions fromprocess.envusing a deterministicGH_AW_*naming scheme. - Regenerates many compiled workflow lockfiles to include additional
GH_AW_*env vars (includingneeds.*outputs and variousgithub.*fields).
Reviewed changes
Copilot reviewed 113 out of 113 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| pkg/workflow/compiler_yaml.go | Extract expressions from main workflow markdown (runtime-imported body) and merge them into compiler-provided env mappings. |
| actions/setup/js/runtime_import.cjs | Add needs.*/steps.* evaluation via env var lookup during runtime-import expression processing. |
| .github/workflows/workflow-normalizer.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/workflow-generator.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/weekly-issue-summary.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/video-analyzer.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/unbloat-docs.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/ubuntu-image-analyzer.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/typist.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/terminal-stylist.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/technical-doc-writer.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/super-linter.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/sub-issue-closer.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/static-analysis-report.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/stale-repo-identifier.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/smoke-project.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/smoke-opencode.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/smoke-copilot.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/smoke-codex.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/smoke-claude.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/slide-deck-maintainer.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/sergo.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/semantic-function-refactor.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/security-review.lock.yml | Regenerated lockfile with additional GH_AW_* env vars (incl. needs.*). |
| .github/workflows/security-guard.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/security-compliance.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/scout.lock.yml | Regenerated lockfile with additional GH_AW_* env vars (incl. complex expr hashes + needs.*). |
| .github/workflows/safe-output-health.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/research.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/repository-quality-improver.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/repo-audit-analyzer.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/release.lock.yml | Regenerated lockfile with additional GH_AW_* env vars (incl. needs.release.outputs.*). |
| .github/workflows/q.lock.yml | Regenerated lockfile with additional GH_AW_* env vars (incl. complex expr hashes + needs.*). |
| .github/workflows/python-data-charts.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/prompt-clustering-analysis.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/pr-triage-agent.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/pr-nitpick-reviewer.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/portfolio-analyst.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/poem-bot.lock.yml | Regenerated lockfile with additional GH_AW_* env vars (incl. needs.*). |
| .github/workflows/plan.lock.yml | Regenerated lockfile with additional GH_AW_* env vars (incl. needs.*). |
| .github/workflows/pdf-summary.lock.yml | Regenerated lockfile with additional GH_AW_* env vars (incl. complex expr hashes + needs.*). |
| .github/workflows/notion-issue-summary.lock.yml | Regenerated lockfile with additional GH_AW_* env vars (incl. hashed expr for issue-number). |
| .github/workflows/metrics-collector.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/mergefest.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/lockfile-stats.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/jsweep.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/issue-triage-agent.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/issue-monster.lock.yml | Regenerated lockfile to pass needs.search_issues.outputs.* into runtime-import evaluation via env vars. |
| .github/workflows/issue-classifier.lock.yml | Regenerated lockfile with additional GH_AW_* env vars (incl. needs.*). |
| .github/workflows/issue-arborist.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/hourly-ci-cleaner.lock.yml | Regenerated lockfile with additional GH_AW_* env vars (incl. needs.check_ci_status.outputs.*). |
| .github/workflows/grumpy-reviewer.lock.yml | Regenerated lockfile with additional GH_AW_* env vars (incl. needs.*). |
| .github/workflows/go-pattern-detector.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/go-fan.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/glossary-maintainer.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/github-remote-mcp-auth-test.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/github-mcp-tools-report.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/github-mcp-structural-analysis.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/functional-pragmatist.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/firewall.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/firewall-escape.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/duplicate-code-detector.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/draft-pr-cleanup.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/docs-noob-tester.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/developer-docs-consolidator.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/dev-hawk.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/dependabot-project-manager.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/dependabot-go-checker.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/delight.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/daily-testify-uber-super-expert.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/daily-team-evolution-insights.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/daily-syntax-error-quality.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/daily-secrets-analysis.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/daily-safe-output-optimizer.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/daily-repo-chronicle.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/daily-regulatory.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/daily-performance-summary.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/daily-observability-report.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/daily-multi-device-docs-tester.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/daily-mcp-concurrency-analysis.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/daily-malicious-code-scan.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/daily-issues-report.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/daily-file-diet.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/daily-fact.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/daily-doc-updater.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/daily-copilot-token-report.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/daily-compiler-quality.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/daily-cli-tools-tester.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/daily-cli-performance.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/craft.lock.yml | Regenerated lockfile with additional GH_AW_* env vars (incl. needs.*). |
| .github/workflows/copilot-session-insights.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/copilot-pr-prompt-analysis.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/copilot-pr-nlp-analysis.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/copilot-pr-merged-report.lock.yml | Regenerated lockfile; adds placeholder substitution + env vars to support runtime-import expression interpolation. |
| .github/workflows/copilot-cli-deep-research.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/copilot-agent-analysis.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/commit-changes-analyzer.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/codex-github-remote-mcp-test.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/code-simplifier.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/cloclo.lock.yml | Regenerated lockfile with additional GH_AW_* env vars (incl. needs.*). |
| .github/workflows/cli-version-checker.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/cli-consistency-checker.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/claude-code-user-docs-review.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/ci-doctor.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/ci-coach.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/changeset.lock.yml | Regenerated lockfile with additional GH_AW_* env vars (incl. needs.*). |
| .github/workflows/breaking-change-checker.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/brave.lock.yml | Regenerated lockfile with additional GH_AW_* env vars (incl. complex expr hashes + needs.*). |
| .github/workflows/blog-auditor.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/audit-workflows.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/artifacts-summary.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
| .github/workflows/archie.lock.yml | Regenerated lockfile with additional GH_AW_* env vars (incl. complex expr hashes + needs.*). |
| .github/workflows/ai-moderator.lock.yml | Regenerated lockfile with additional GH_AW_* env vars. |
Comments suppressed due to low confidence (2)
actions/setup/js/runtime_import.cjs:221
- The runtime-import env var fast-path treats empty string as "not found" (
envValue !== ""). If a needs/steps output legitimately evaluates to an empty string, this will fall through and return the original${{ ... }}string, leaving an unevaluated expression in the imported markdown. Consider returning the env value whenever the variable is present (e.g., check only forenvValue !== undefined), so empty outputs are handled correctly.
actions/setup/js/runtime_import.cjs:223 - Env var name derivation for
needs.*/steps.*expressions only replaces dots with underscores, but doesn’t normalize other valid identifier characters like-. Job IDs and step IDs commonly contain hyphens; the compiler’s ExpressionExtractor currently falls back to hash-based names for those, and GitHub Actions env keys also typically can’t contain-. This meansneeds.some-job.outputs.x/steps.some-step.outputs.xin runtime-imported markdown may never resolve. Suggest normalizing to a shared scheme (e.g., replace any[^A-Z0-9_]with_) and ensuring the compiler generates matching env var names for those expressions.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // Create a new extractor for main workflow markdown | ||
| mainExtractor := NewExpressionExtractor() | ||
| mainExprMappings, err := mainExtractor.ExtractExpressions(data.MainWorkflowMarkdown) | ||
| if err == nil && len(mainExprMappings) > 0 { | ||
| compilerYamlLog.Printf("Extracted %d expressions from main workflow markdown", len(mainExprMappings)) | ||
| // Merge with imported expressions (append to existing mappings) | ||
| expressionMappings = append(expressionMappings, mainExprMappings...) | ||
| } |
There was a problem hiding this comment.
mainExprMappings are appended to expressionMappings without deduplication. If the same expression appears in both imported markdown and the main markdown, generateInterpolationAndTemplateStep will emit duplicate env: keys (it iterates expressionMappings directly), which can produce invalid YAML / nondeterministic behavior. Consider deduping by EnvVar (or Original) before calling generateInterpolationAndTemplateStep, or changing that step generator to build a stable unique set.
| // Check if this is a needs.* or steps.* expression that should be looked up from environment variables | ||
| // The compiler extracts these expressions and makes them available as GH_AW_* environment variables | ||
| // For example: needs.search_issues.outputs.issue_list → GH_AW_NEEDS_SEARCH_ISSUES_OUTPUTS_ISSUE_LIST | ||
| if (trimmed.startsWith("needs.") || trimmed.startsWith("steps.")) { | ||
| // Convert expression to environment variable name | ||
| // e.g., "needs.search_issues.outputs.issue_list" → "GH_AW_NEEDS_SEARCH_ISSUES_OUTPUTS_ISSUE_LIST" | ||
| const envVarName = "GH_AW_" + trimmed.toUpperCase().replace(/\./g, "_"); | ||
| const envValue = process.env[envVarName]; | ||
| if (envValue !== undefined && envValue !== null && envValue !== "") { | ||
| return envValue; | ||
| } | ||
| // If not found in environment, continue to try other evaluation methods below | ||
| } |
There was a problem hiding this comment.
This change adds new evaluation behavior for needs.* / steps.* expressions via process.env, but runtime_import.test.cjs currently asserts these expressions are unresolvable and should remain wrapped. Please update/add tests to cover the new env-lookup path (including the empty-string case and an id containing - once name normalization is decided).
This issue also appears in the following locations of the same file:
- line 214
- line 214
The issue-monster workflow wasn't assigning issues to agents because
${{ needs.search_issues.outputs.* }}expressions in the workflow body were never interpolated. The agent received no issue data and callednoopinstead ofassign_to_agent.Changes
Compiler (pkg/workflow/compiler_yaml.go)
MainWorkflowMarkdown(notMarkdownContentwhich includes unprocessed imports)github.aw.inputs.*expressions before substitutionRuntime (actions/setup/js/runtime_import.cjs)
needs.*andsteps.*expressions from environment variables during runtime-importneeds.search_issues.outputs.issue_list→GH_AW_NEEDS_SEARCH_ISSUES_OUTPUTS_ISSUE_LIST)Example
Workflow markdown with job dependencies:
Now compiles to workflow with environment variables:
And runtime-import evaluates these expressions from
process.envwhen processing the markdown body.Warning
Firewall rules blocked me from connecting to one or more addresses (expand for details)
I tried to connect to the following addresses, but was blocked by firewall rules:
https://api.github.com/repos/github/gh-aw/actions/runs/21771775670/artifacts/usr/bin/curl curl -sL -H Authorization: ******(http block)If you need me to access, download, or install something from one of these locations, you can either:
Original prompt
💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.