CompileWorkflowData compiles pre-parsed workflow content into GitHub Actions YAML. Unlike CompileWorkflow, this accepts already-parsed frontmatter and markdown content rather than reading from disk. This is useful for testing and programmatic workflow generation. The compilation process includes: -
(workflowData *WorkflowData, markdownPath string)
| 410 | // making it efficient for scenarios where the same workflow is compiled multiple times |
| 411 | // or when workflow data comes from a non-file source. |
| 412 | func (c *Compiler) CompileWorkflowData(workflowData *WorkflowData, markdownPath string) error { |
| 413 | // Store markdownPath for use in dynamic tool generation and prompt generation |
| 414 | c.markdownPath = markdownPath |
| 415 | |
| 416 | // Track compilation time for performance monitoring |
| 417 | startTime := time.Now() |
| 418 | defer func() { |
| 419 | workflowLog.Printf("Compilation completed in %v", time.Since(startTime)) |
| 420 | }() |
| 421 | |
| 422 | // Reset the step order tracker for this compilation |
| 423 | c.stepOrderTracker = NewStepOrderTracker() |
| 424 | |
| 425 | // Reset schedule friendly formats for this compilation |
| 426 | c.scheduleFriendlyFormats = nil |
| 427 | |
| 428 | // Reset the artifact manager for this compilation |
| 429 | if c.artifactManager == nil { |
| 430 | c.artifactManager = NewArtifactManager() |
| 431 | } else { |
| 432 | c.artifactManager.Reset() |
| 433 | } |
| 434 | |
| 435 | // Enable GHES artifact compatibility from CLI flag or aw.json (CLI flag wins). |
| 436 | // c.ghesCompatFromCLI is set once per compiler instance via SetGHESCompat(). |
| 437 | c.ghesArtifactCompat = c.ghesCompatFromCLI |
| 438 | if !c.ghesArtifactCompat { |
| 439 | // Fall back to aw.json ghes field when CLI flag was not passed. |
| 440 | if repoConfig, err := c.loadRepoConfig(); err == nil && repoConfig != nil { |
| 441 | c.ghesArtifactCompat = repoConfig.GHES |
| 442 | } |
| 443 | } |
| 444 | if c.ghesArtifactCompat { |
| 445 | actionPinsLog.Print("GHES artifact compatibility mode enabled: artifact actions will use v3.x pins") |
| 446 | } |
| 447 | |
| 448 | // Generate lock file name |
| 449 | lockFile := stringutil.MarkdownToLockFile(markdownPath) |
| 450 | |
| 451 | // Sanitize the lock file path to prevent path traversal attacks |
| 452 | lockFile = filepath.Clean(lockFile) |
| 453 | |
| 454 | workflowLog.Printf("Starting compilation: %s -> %s", markdownPath, lockFile) |
| 455 | |
| 456 | // Resolve and cache the baseline manifest only when safe update mode is active. |
| 457 | // This avoids unnecessary git/filesystem reads on compile paths that skip safe update |
| 458 | // enforcement (e.g., --approve or strict: false). |
| 459 | safeUpdateEnabled := c.effectiveSafeUpdate(workflowData) |
| 460 | var oldManifest *GHAWManifest |
| 461 | if safeUpdateEnabled { |
| 462 | // Read the existing lock file to extract the previous gh-aw-manifest for safe update |
| 463 | // enforcement. |
| 464 | // |
| 465 | // Priority (highest to lowest): |
| 466 | // 1. Pre-cached manifest supplied by the caller (e.g. MCP server collected at startup |
| 467 | // before any agent interaction, making it tamper-proof without requiring git access). |
| 468 | // 2. Content from the last git commit (HEAD) – prevents a local agent from modifying |
| 469 | // the .lock.yml file on disk to forge an approved manifest. |