Skip to content

Nested remote imports resolve against hardcoded .github/workflows/ instead of parent workflowspec base path #16370

@strawgate

Description

@strawgate

Bug

When a consumer shim imports a remote workflowspec whose repo-relative path is not under .github/workflows/ (e.g., gh-agent-workflows/gh-aw-workflows/test-improvement-rwxp.md), the compiler resolves nested relative imports against a hardcoded .github/workflows/ base instead of the parent workflowspec's actual base directory.

This produces inconsistent runtime-import cache paths in the lock file and causes security scanner warnings for files that don't exist locally.

Reproduction

In a consumer repo with this shim (test-improvement.md):

imports:
- elastic/ai-github-actions/gh-agent-workflows/gh-aw-workflows/test-improvement-rwxp.md@<sha>

The remote prompt file imports fragments:

imports:
  - gh-aw-fragments/elastic-tools.md
  - gh-aw-fragments/formatting.md
  ...

Running gh aw compile produces:

WARNING: Skipping security scan for unresolvable import 'gh-aw-fragments/elastic-tools.md': file not found: .../.github/workflows/gh-aw-fragments/elastic-tools.md
WARNING: Skipping security scan for unresolvable import 'gh-aw-fragments/formatting.md': ...

And the lock file has inconsistent runtime-import paths:

# Top-level import — cached via gh-agent-workflows/ (correct, matches workflowspec):
{{#runtime-import .github/aw/imports/elastic/ai-github-actions/<sha>/gh-agent-workflows_gh-aw-workflows_test-improvement-rwxp.md}}

# Nested import — cached via .github/workflows/ (WRONG, doesn't match parent's base):
{{#runtime-import .github/aw/imports/elastic/ai-github-actions/<sha>/.github_workflows_gh-aw-fragments_elastic-tools.md}}

Compare with a working workflow (mention-in-pr) whose shim imports through .github/workflows/:

# Both top-level and nested are consistent:
{{#runtime-import .github/aw/imports/elastic/ai-github-actions/<sha>/.github_workflows_gh-aw-workflows_mention-in-pr-rwxp.md}}
{{#runtime-import .github/aw/imports/elastic/ai-github-actions/<sha>/.github_workflows_gh-aw-fragments_elastic-tools.md}}

Root Cause

In import_processor.go, the nested import resolution hardcodes .github/workflows/:

resolvedPath = fmt.Sprintf("%s/%s/.github/workflows/%s@%s",
    item.remoteOrigin.Owner, item.remoteOrigin.Repo, cleanPath, item.remoteOrigin.Ref)

This was introduced in #15987.

Fix

Derive the base path from the parent workflowspec instead of hardcoding .github/workflows/. Since imports are always 2-level (dir/file.md), the base is everything between owner/repo/ and the last two path components of the workflowspec.

For elastic/ai-github-actions/gh-agent-workflows/gh-aw-workflows/test-improvement-rwxp.md@sha:

  • repo path parts: ["gh-agent-workflows", "gh-aw-workflows", "test-improvement-rwxp.md"]
  • base = parts before last 2 = "gh-agent-workflows"
  • nested gh-aw-fragments/elastic-tools.mdelastic/ai-github-actions/gh-agent-workflows/gh-aw-fragments/elastic-tools.md@sha

Add a BasePath field to remoteImportOrigin and use it for nested resolution. This also avoids unnecessary symlink resolution API calls when the workflowspec already points at the real file locations.

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions