Refactor compile_orchestrator.go: split 1200-line file into focused modules #8246
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
✅ Refactoring Complete: compile_orchestrator.go (1200 → 262 lines)
Successfully refactored the large
compile_orchestrator.gofile into focused modules following the repository's established patterns.Refactoring Summary
Before:
compile_orchestrator.go: 1,200 lines (monolithic file with 195+ control structures)After:
compile_orchestrator.go: 262 lines (78% reduction) ✅compile_orchestration.go: 480 lines (main compilation logic)compile_output_formatter.go: 65 lines (output formatting wrappers)compile_compiler_setup.go: 140 lines (compiler setup & configuration)compile_workflow_processor.go: 221 lines (workflow file processing)compile_batch_operations.go: 274 lines (batch operations & file cleanup)compile_post_processing.go: 177 lines (post-compilation processing)Total: 1,619 lines across 7 focused files
Recent Changes (Linting Fixes)
Fixed all linting issues identified by golangci-lint:
All tests pass ✅
All linting checks pass ✅
Build succeeds ✅
Module Responsibilities
1. compile_orchestrator.go (262 lines)
CompileWorkflows()function (simplified to ~70 lines)getRepositoryRelativePath()helperrenderGeneratedCampaignOrchestratorMarkdown()for campaign renderinggenerateAndCompileCampaignOrchestrator()for campaign generation2. compile_orchestration.go (480 lines)
compileSpecificFiles()- orchestrates specific file compilationcompileAllFilesInDirectory()- orchestrates directory-wide compilation3. compile_output_formatter.go (65 lines)
formatCompilationSummary()- format compilation statisticsformatValidationOutput()- format validation results as JSONformatActionlintOutput()- display actionlint summaryformatStatsTable()- display workflow statistics table4. compile_compiler_setup.go (140 lines)
createAndConfigureCompiler()- create compiler with full configconfigureCompilerFlags()- set validation, strict mode, trial modesetupActionMode()- configure action script inlining modesetupRepositoryContext()- set repository slug for schedule scatteringvalidateActionModeConfig()- validate action mode configuration5. compile_workflow_processor.go (221 lines)
compileWorkflowFile()- compile a single workflow markdown fileprocessCampaignSpec()- process a campaign spec file6. compile_batch_operations.go (274 lines)
runBatchActionlint()- run actionlint on multiple lock filespurgeOrphanedLockFiles()- remove orphaned .lock.yml filespurgeInvalidFiles()- remove .invalid.yml filespurgeOrphanedCampaignOrchestrators()- remove orphaned .campaign.g.md filespurgeOrphanedCampaignOrchestratorLockFiles()- remove orphaned .campaign.g.lock.yml files7. compile_post_processing.go (177 lines)
generateDependabotManifestsWrapper()- generate Dependabot manifestsgenerateMaintenanceWorkflowWrapper()- generate maintenance workflowvalidateCampaignsWrapper()- validate campaign specscollectWorkflowStatisticsWrapper()- collect workflow statisticsupdateGitAttributes()- update .gitattributes filesaveActionCache()- save action cacheTesting Results
TestGetRepositoryRelativePath*) ✅make build) ✅make lint) ✅compile_orchestrator_stability_test.gopasses ✅Benefits Achieved
✅ 78% reduction in main orchestrator file size (1200 → 262 lines)
✅ 7 focused files with clear single responsibilities
✅ Improved maintainability - easier to understand and modify
✅ Better testability - focused unit tests for each module
✅ No breaking changes - public API remains unchanged
✅ Follows repository patterns - consistent with other CLI files
✅ Reduced complexity - smaller functions with fewer control structures
✅ Clean linting - all golangci-lint checks pass
Code Organization Patterns Followed
compile_*.gofor consistency with existing filescli:filenamepattern (e.g.,cli:compile_orchestration)Campaign Status Update
Files Over 800-Line Threshold: Now 16 files (reduced from 17)
This refactor successfully reduces the count of large files and improves overall codebase health.
Campaign: Go File Size Reduction
Metrics Date: 2025-12-31
Status: ✅ Complete
Original prompt
This section details on the original issue you should resolve
<issue_title>[file-diet] Refactor Large Go File: pkg/cli/compile_orchestrator.go (1200 lines)</issue_title>
<issue_description>## Overview
The file
pkg/cli/compile_orchestrator.gohas grown to 1200 lines, making it difficult to maintain and test. The mainCompileWorkflowsfunction alone contains over 1000 lines with 195+ control structures, indicating high complexity and the need for refactoring into smaller, focused files with improved test coverage.Current State
pkg/cli/compile_orchestrator.goCompileWorkflowsis monolithic (1000+ lines)Campaign Status
Files Over 800-Line Threshold: 17 files currently exceed healthy limits
This refactor will reduce the count and improve overall codebase health.
Refactoring Strategy
The
CompileWorkflowsfunction is doing too much. Based on semantic analysis, split into focused modules:Proposed File Splits
1.
compile_config_validator.govalidateCompileConfig()- Configuration validationvalidateWorkflowDirectory()- Workflow directory setupresolveWorkflowFile()- File resolution logic2.
compile_compiler_setup.gocreateCompiler()- Compiler initializationconfigureCompilerFlags()- Set validation, strict mode, trial modesetupActionMode()- Action mode detection and configurationsetupRepositoryContext()- Repository slug and git root setup3.
compile_workflow_processor.goprocessWorkflowFile()- Single workflow compilation logicprocessCampaignSpec()- Campaign spec handlingcollectLockFilesForLinting()- Lock file collection4.
compile_batch_operations.gorunBatchActionlint()- Batch actionlint executionrunBatchZizmor()- Batch security lintingrunBatchPoutine()- Batch supply chain analysispurgeOrphanedFiles()- Clean up orphaned .lock.yml and .invalid.yml files5.
compile_output_formatter.goprintCompilationSummary()- Already exists, move heredisplayStatsTable()- Already exists, move heredisplayActionlintSummary()- Already exists, move hereformatValidationResults()- JSON output formattingsanitizeValidationResults()- Security sanitization6.
compile_post_processing.gogenerateDependabotManifests()- Dependabot generation wrappergenerateMaintenanceWorkflow()- Maintenance workflow generationvalidateCampaignSpecs()- Campaign validation wrappercollectWorkflowStatistics()- Stats collection7.
compile_orchestrator.go(Refactored)CompileWorkflows()- Main orchestrator (dramatically simplified)getRepositoryRelativePath()- Keep helperrenderGeneratedCampaignOrchestratorMarkdown()- Keep campaign renderinggenerateAndCompileCampaignOrchestrator()- Keep campaign generationShared Utilities
Extract common functionality into existing files:
git_helpers.go: Git root finding, repository slug extraction (may already exist)file_helpers.go: File path resolution, glob operationsInterface Abstractions
Consider introducing interfaces to reduce coupling:
WorkflowProcessorinterface: For processing different file types (workflows vs campaigns)LinterRunnerinterface: For running different linters (actionlint, zizmor, poutine)OutputFormatterinterface: For different output formats (text, JSON, stats)Test Coverage Plan
Add comprehensive tests for each new file:
1.
compile_config_validator_test.go💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.