Skip to content
7 changes: 7 additions & 0 deletions pkg/workflow/compiler.go
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,13 @@ func (c *Compiler) CompileWorkflowData(workflowData *WorkflowData, markdownPath
oldManifest = &GHAWManifest{Version: currentGHAWManifestVersion}
}
}
// Keep the first baseline seen by this compiler instance.
// This intentionally does not overwrite an existing cache entry so repeated
// compiles in the same process continue to compare against the same trusted
// baseline rather than a just-generated local lock file.
if _, ok := c.priorManifests[lockFile]; !ok {
c.priorManifests[lockFile] = oldManifest
}

// Validate workflow data
if err := c.validateWorkflowData(workflowData, markdownPath); err != nil {
Expand Down
32 changes: 32 additions & 0 deletions pkg/workflow/compiler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,38 @@ Test content
require.NoError(t, err, "Lock file should be created")
}

func TestCompileWorkflow_CachesResolvedManifestBaseline(t *testing.T) {
tmpDir := testutil.TempDir(t, "compiler-manifest-cache")
testFile := filepath.Join(tmpDir, "test-workflow.md")
testContent := `---
on: push
engine: copilot
strict: false
---

# Test Workflow

Caching baseline manifest data should not change behavior.
`
require.NoError(t, os.WriteFile(testFile, []byte(testContent), 0644))

compiler := NewCompiler(WithNoEmit(true))
manifestCache := map[string]*GHAWManifest{}
compiler.SetPriorManifests(manifestCache)

require.NoError(t, compiler.CompileWorkflow(testFile))

lockFile := filepath.Clean(stringutil.MarkdownToLockFile(testFile))
firstBaseline, ok := manifestCache[lockFile]
require.True(t, ok, "baseline manifest should be cached after first compile")
require.NotNil(t, firstBaseline, "new workflows should cache an empty baseline manifest")

require.NoError(t, compiler.CompileWorkflow(testFile))
secondBaseline, ok := manifestCache[lockFile]
require.True(t, ok, "cached baseline should remain available after second compile")
require.NotNil(t, secondBaseline, "cached baseline should be non-nil")
}

// TestCompileWorkflow_LockFileSize tests that generated lock files don't exceed size limits
func TestCompileWorkflow_LockFileSize(t *testing.T) {
tmpDir := testutil.TempDir(t, "compiler-size-test")
Expand Down
4 changes: 4 additions & 0 deletions pkg/workflow/compiler_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ func NewCompiler(opts ...CompilerOption) *Compiler {
stepOrderTracker: NewStepOrderTracker(),
artifactManager: NewArtifactManager(),
actionPinWarnings: make(map[string]bool), // Initialize warning cache
priorManifests: make(map[string]*GHAWManifest),
gitRoot: gitRoot, // Auto-detected git root
}

Expand Down Expand Up @@ -328,6 +329,9 @@ func (c *Compiler) GetSafeUpdateWarnings() []string {

// SetPriorManifests replaces the entire pre-cached manifest map.
func (c *Compiler) SetPriorManifests(manifests map[string]*GHAWManifest) {
if manifests == nil {
manifests = make(map[string]*GHAWManifest)
}
c.priorManifests = manifests
}

Expand Down
Loading