The Core Engine
Relevant source files
The following files were used as context for generating this wiki page:- iac-recert-engine/internal/engine/engine.go
- iac-recert-engine/cmd/ice/run.go
- iac-recert-engine/internal/config/types.go
- iac-recert-engine/internal/types/types.go
- iac-recert-engine/internal/scan/file_scanner.go
- iac-recert-engine/internal/scan/recert_checker.go
- iac-recert-engine/internal/scan/git_history.go
- iac-recert-engine/internal/strategy/strategy_test.go
- iac-recert-engine/internal/assign/resolver.go
- iac-recert-engine/internal/pr/generator.go
- iac-recert-engine/internal/provider/github.go
- iac-recert-engine/example.config.yaml
The Core Engine is the central orchestrator of the iac-recert-engine. It is responsible for managing the entire recertification workflow, from initialization based on user configuration to the final creation of pull requests. The engine coordinates a series of specialized components to perform tasks such as scanning files, analyzing their history, checking for recertification requirements, grouping files, and assigning reviewers.
The engine is instantiated and executed by the run command, which loads the application configuration, sets up logging, and invokes the engine's main Run method. The engine's behavior is highly configurable through a YAML file, allowing control over aspects like repository targets, file patterns, recertification periods, and pull request generation strategies.
Sources: internal/engine/engine.go, cmd/ice/run.go:16-43
Architecture and Components
The Engine struct encapsulates the application's configuration and holds instances of all major processing components. This design promotes separation of concerns, where the engine acts as a coordinator and delegates specific tasks to its components.
Sources: internal/engine/engine.go:22-34
// iac-recert-engine/internal/engine/engine.go:22-34
type Engine struct {
cfg config.Config
logger *zap.Logger
provider provider.GitProvider
scanner *scan.Scanner
analyzer *scan.HistoryAnalyzer
checker *scan.Checker
strategy strategy.Strategy
resolver *assign.Resolver
prGen *pr.Generator
}
The following diagram illustrates the components managed by the engine.
This diagram shows the Engine and the various components it utilizes to perform the recertification workflow.
Sources: internal/engine/engine.go:22-34
| Component | Responsibility | Source File |
|---|---|---|
GitProvider | Interacts with the Git hosting service (e.g., GitHub, Azure) to fetch history, create branches, commits, and PRs. | internal/provider/github.go |
Scanner | Clones the target repository and scans the filesystem for files matching configured patterns. | internal/scan/file_scanner.go |
HistoryAnalyzer | Enriches file information with Git history, such as the last modification date and author. | internal/scan/git_history.go |
Checker | Compares file modification dates against recertification thresholds defined in patterns. | internal/scan/recert_checker.go |
Strategy | Groups files that need recertification based on a configured strategy (e.g., per_pattern, single_pr). | internal/strategy/strategy_test.go |
Resolver | Determines the assignees and reviewers for a pull request based on the configured assignment strategy. | internal/assign/resolver.go |
PR.Generator | Generates the title, description, and branch name for a new pull request. | internal/pr/generator.go |
Sources: internal/engine/engine.go:40-70
Initialization
The engine is initialized via the NewEngine function, which takes the application configuration (config.Config) and a logger as input. During initialization, it instantiates and wires together all the necessary components. This includes setting up the correct GitProvider based on the configuration and initializing the scanner, analyzer, checker, grouping strategy, assignment resolver, and PR generator.
Sources: internal/engine/engine.go:36-77, cmd/ice/run.go:35-39
Execution Flow
The Run method orchestrates the main recertification process. It executes a sequence of steps to identify files needing review and create pull requests for them. The flow is designed to be linear and fault-tolerant, with logging at each major step.
The overall process is controlled by global configuration settings, most notably dry_run. When dry_run is true, the engine performs all steps up to the point of creating a pull request, but instead of executing the action, it logs what it would have done.
Sources: internal/engine/engine.go:79-133, example.config.yaml:16-17
Main Workflow
The following diagram outlines the high-level steps executed by the Engine.Run method.
This flowchart shows the sequential phases of the engine's run cycle, from scanning files to processing groups and creating pull requests.
Sources: internal/engine/engine.go:81-133
- Scan: The
scanner.Scanmethod is called to clone the repository into a temporary directory and find all files that match the glob patterns defined in thepatternsconfiguration. It returns a list oftypes.FileInfo.
Sources: internal/engine/engine.go:88-91, internal/scan/file_scanner.go:28-111 - Enrich: The
analyzer.Enrichmethod takes the list of files and uses theGitProviderto fetch the last modification date and commit details for each one.
Sources: internal/engine/engine.go:102-106, internal/scan/git_history.go:23-60 - Check: The
checker.Checkmethod iterates through the enriched files, determines if they are due for recertification based on therecertification_daysin their matching pattern, and calculates a priority. It returns a list oftypes.RecertCheckResult.
Sources: internal/engine/engine.go:108-112, internal/scan/recert_checker.go:20-117 - Group: The
strategy.Groupmethod organizes the files that need recertification intotypes.FileGroupcollections. The grouping logic depends on thepr_strategytype (e.g.,per_pattern,per_committer).
Sources: internal/engine/engine.go:114-118, internal/strategy/strategy_test.go:50-81 - Process Groups: The engine iterates over each
FileGroupand callsprocessGroupto handle the PR creation logic for that specific group.
Sources: internal/engine/engine.go:122-131
Group Processing and PR Creation
The processGroup method contains the logic for creating a single pull request from a group of files. It coordinates the assignment resolver, PR generator, and Git provider to perform the necessary actions.
The sequence diagram below details the interactions within processGroup.
This diagram shows the sequence of operations for processing a file group, including resolving assignees, generating PR content, and interacting with the Git provider to create a branch, commit, and pull request.
Sources: internal/engine/engine.go:135-257
Key steps in this sub-process include:
- Resolve Assignment: The
resolver.Resolvemethod is called to determine the assignees and reviewers for the group.
Sources: internal/engine/engine.go:141-145, internal/assign/resolver.go:26-89 - Generate PR Config: The
prGen.Generatemethod creates the pull request title, description, and branch name based on the group's contents and thepr_templateconfiguration.
Sources: internal/engine/engine.go:147-151, internal/pr/generator.go:17-64 - Generate Changes: For each file in the group, the engine reads its content, removes any existing decorator, and prepends a new decorator (e.g.,
# Last Recertification: {timestamp}). This creates atypes.Changeobject.
Sources: internal/engine/engine.go:176-213, example.config.yaml:31 - Interact with Git Provider:
- It checks if the target branch already exists to avoid redundant work.
- It creates the branch if it doesn't exist.
- It creates a commit on the new branch containing all the file changes.
- It checks if an open pull request for that branch already exists.
- Finally, it creates the pull request and adds assignees and reviewers.
Sources: internal/engine/engine.go:216-257, internal/provider/github.go:102-235
Summary
The Core Engine is the heart of the iac-recert-engine, providing a robust and configurable framework for automating the infrastructure-as-code recertification process. By composing a set of specialized components, it executes a clear, multi-stage workflow that transforms a high-level configuration into concrete actions within a Git repository, ultimately resulting in pull requests that drive the review and recertification of aging code. Its design emphasizes modularity and clear separation of concerns, making the system extensible and maintainable.
Sources: internal/engine/engine.go, cmd/ice/run.go