Refactor CompileWorkflowData into smaller, testable functions#14402
Refactor CompileWorkflowData into smaller, testable functions#14402
Conversation
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Refactors CompileWorkflowData() into smaller methods to improve testability and reduce complexity, with accompanying unit tests for each extracted phase.
Changes:
- Extracted
validateWorkflowData(),generateAndValidateYAML(), andwriteWorkflowOutput()fromCompileWorkflowData() - Reworked
CompileWorkflowData()into an orchestration method that delegates to the extracted functions - Added unit tests for each extracted function, including an “output unchanged” case
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| pkg/workflow/compiler.go | Splits CompileWorkflowData() into focused validation/generation/output helpers and updates the main orchestration flow. |
| pkg/workflow/compiler_test.go | Adds new unit tests targeting the extracted helper methods and key success/error paths. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // Write same content again | ||
| compiler := NewCompiler() | ||
| err = compiler.writeWorkflowOutput(lockFile, yamlContent, markdownPath) | ||
| require.NoError(t, err) | ||
|
|
||
| // Check that modification time hasn't changed (file wasn't rewritten) | ||
| finalInfo, err := os.Stat(lockFile) | ||
| require.NoError(t, err) | ||
| finalModTime := finalInfo.ModTime() | ||
|
|
||
| assert.Equal(t, initialModTime, finalModTime, "File should not be rewritten if content is unchanged") |
There was a problem hiding this comment.
This test can be unreliable because filesystem mtime resolution can be coarse; a rewrite that happens quickly may not change ModTime(), causing the test to pass even if the file was rewritten. To make this robust, introduce a delay sufficient to exceed typical mtime granularity before the second write attempt (then assert modtime is unchanged), or alternatively assert a stronger signal of rewrite avoidance (e.g., compare inode/file ID where available, or instrument the write path via an injectable file-writer in tests).
| tests := []struct { | ||
| name string | ||
| yamlContent string | ||
| noEmit bool | ||
| quiet bool | ||
| shouldError bool | ||
| checkFileSize bool | ||
| }{ |
There was a problem hiding this comment.
The field name checkFileSize is misleading because the test logic checks file existence and content, not size. Consider renaming it to something like expectFileWritten / verifyFileWritten / checkFileWritten to better match its usage.
The
CompileWorkflowData()function was 343 lines, mixing validation, YAML generation, and file I/O. This made individual phases difficult to test and increased cyclomatic complexity.Changes
Extracted three focused methods:
validateWorkflowData()(177 lines) - Expression safety, feature flags, permissions, sandbox config, GitHub MCP toolsets, dispatch-workflow validationgenerateAndValidateYAML()(81 lines) - YAML generation, expression size validation, template injection checks, schema validation, container/runtime/firewall validationwriteWorkflowOutput()(53 lines) - Lock file writing with change detection, file size validation, console output formattingRefactored main function (53 lines, down from 343) - Now orchestrates initialization and calls the three methods in sequence
Added test coverage - Independent tests for each extracted function covering success and error cases
Before/After
No functional changes.
Original prompt
💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.