Solution by Layer
Layer-by-layer architecture analysis of the refactored codebase.
For feature-by-feature breakdown, see solution-by-feature.md. For high-level overview, see README.md.
Reference Commit
| State | Commit Hash | Date |
|---|---|---|
| Final | ff74ac8 |
2025-05-12 |
Table of Contents
- Overview
- Complete File Structure
- Folder-by-Folder Analysis
- Design Patterns Applied
- Current State Summary
- Reference
1. Overview
1.1 File Statistics
| Category | Files | Lines (approx) | Status |
|---|---|---|---|
| sharedLibraries/vars/ | 13 | 1,104 | NEW - Pipeline stages |
| sharedLibraries/src/ | 5 | 1,047 | NEW - Core business logic |
| groovy/ | 3 | 1,824 | Legacy (being migrated) |
| DLXJenkins/ | 2 | 286 | Refactored |
| JsJenkins/ | 2 | 743 | Being Refactored |
| PipelineForJenkins/ | 1 | 185 | Being Refactored |
| python/ | 15 | 2,069 | Legacy (to be eliminated) |
| Bash/ | 2 | 330 | Shell scripts |
| tests/ | 5 | 200 | NEW - Unit tests |
| TOTAL | 48 | 7,788 |
1.2 Architecture Summary
The refactored codebase implements a 4-Layer Architecture with clear separation of concerns:
2. Complete File Structure
devops-linux-jenkins/
│
├── sharedLibraries/ [18 files - Core Library]
│ ├── vars/ [13 files - Pipeline Functions]
│ │ ├── logger.groovy - Centralized logging
│ │ ├── shellScriptHelper.groovy - Shell execution wrapper
│ │ ├── bitbucketApiHelper.groovy - Bitbucket API facade
│ │ ├── bitbucketApiLibrary.groovy - API request builder
│ │ ├── stageInitialization.groovy - Pipeline initialization
│ │ ├── stageProjectPrepare.groovy - Project preparation
│ │ ├── stageLintUnity.groovy - Unity linting
│ │ ├── stageLintGroovyJenkinsfile.groovy - Groovy linting
│ │ ├── stageUnityExecution.groovy - Unity test execution
│ │ ├── stageStaticAnalysis.groovy - SonarQube analysis
│ │ ├── stageSendBuildResults.groovy - Build result reporting
│ │ ├── stageDeployBuild.groovy - Build deployment
│ │ └── stageCleanupPRBranchArtifacts.groovy - PR cleanup
│ │
│ └── src/ [5 files - Library Source]
│ ├── resource/
│ │ └── Status.groovy - Status constants
│ │
│ ├── service/general/
│ │ └── HttpApiService.groovy - HTTP client
│ │
│ └── utils/
│ ├── GitLibrary.groovy - Git operations (23 closures)
│ ├── ShellLibrary.groovy - Shell operations (15 closures)
│ └── SSHShellLibrary.groovy - SSH operations (8 closures)
│
├── DLXJenkins/ [2 files - Unity Pipeline]
│ ├── Jenkinsfile
│ └── JenkinsfileDeployment
│
├── JsJenkins/ [2 files - JavaScript Pipeline]
│ ├── Jenkinsfile
│ └── JenkinsfileDeployment
│
├── PipelineForJenkins/ [1 file - Self Pipeline]
│ └── Jenkinsfile
│
├── groovy/ [3 files - Legacy Helpers]
│ ├── generalHelper.groovy - Being migrated
│ ├── jsHelper.groovy - Being migrated
│ └── unityHelper.groovy - Being migrated
│
├── python/ [15 files - Legacy Scripts]
│ └── (to be eliminated)
│
└── tests/ [5 files - Unit Tests]
├── GeneralHelperSpec.groovy
└── src/
├── resource/
│ ├── JenkinsFile.groovy - Mock interface
│ └── StatusSpec.groovy
└── utils/
└── GitLibrarySpec.groovy - Git closure tests
3. Folder-by-Folder Analysis
3.1 sharedLibraries/vars/ - Pipeline Stage Functions
The vars/ directory in Jenkins Global Shared Library defines global functions callable directly from pipelines.
| File | Lines | Purpose |
|---|---|---|
stageInitialization.groovy |
103 | Environment setup, send INPROGRESS status |
stageProjectPrepare.groovy |
186 | Git workspace preparation, branch sync |
stageLintUnity.groovy |
67 | Unity C# linting |
stageLintGroovyJenkinsfile.groovy |
96 | Groovy/Jenkinsfile linting |
stageUnityExecution.groovy |
99 | Unity test execution (EditMode/PlayMode/Coverage/WebGL) |
stageStaticAnalysis.groovy |
87 | SonarQube analysis |
stageSendBuildResults.groovy |
39 | Build result publishing |
stageDeployBuild.groovy |
72 | SSH deployment |
stageCleanupPRBranchArtifacts.groovy |
62 | PR artifact cleanup |
logger.groovy - 3-Level Hierarchical Logging
shellScriptHelper.groovy - Validated Shell Execution
3.2 sharedLibraries/src/ - Core Business Logic
* CPS Constraint Note:
logger.groovy,shellScriptHelper.groovy,bitbucketApiHelper.groovy,bitbucketApiLibrary.groovyare located invars/instead ofsrc/due to Jenkins CPS (Continuation Passing Style) serialization constraints. These files use Jenkins DSL methods (echo,sh,withCredentials) that require CPS-compatible execution context.
3.2.1 vars/ Helpers (CPS-constrained)*
| File | Lines | Purpose | Design Pattern |
|---|---|---|---|
logger.groovy |
83 | 3-level hierarchical logging | Facade |
shellScriptHelper.groovy |
105 | Validated shell execution | Command/Adapter |
bitbucketApiHelper.groovy |
36 | Bitbucket API facade | Facade |
bitbucketApiLibrary.groovy |
69 | API request builder | Builder |
logger.groovy - 3-Level Hierarchical Logging
3.2.2 src/utils/ - Command Libraries
GitLibrary.groovy (23 Closures)
| Category | Closures |
|---|---|
| Fetch | FetchOrigin, FetchBranch |
| Branch | ShowCurrentBranch, CheckoutBranch, GetOriginDefaultBranch, CheckOriginBranchExists, CheckBranchExists |
| Status | CheckUpToDateWithRemote, CheckIsRemoteBranchAncestor |
| Reset/Clean | ResetHardHead, CleanUntracked, RemoveIndexLock |
| Clone/Pull | CloneRepository, Pull, ResetHardOriginBranch |
| Merge | MergeOriginBranch |
| LFS | LfsListUntrackedFiles, LfsFetchAndCheckout |
| Hash | GetRemoteBranchHash |
ShellLibrary.groovy (15 Closures)
| Category | Closures |
|---|---|
| Environment | PrintJenkinsEnv |
| Directory | FindPRJobDirectory, FindProjectDirectory, CreateLintingResultsDir |
| Docker | DockerInfo, GroovyLint |
| Unity | GetUnityExecutable, LintUnity, CopyWebGLBuilder, CopyLintConfig |
| Reporting | ExecutePythonStatusReport, CreateBitbucketBuildReport, CreateBitbucketTestReport |
SSHShellLibrary.groovy (8 Closures)
| Closure | Purpose |
|---|---|
| CheckSSHConnectivity | Test SSH connection |
| CreateDirectoryAndSetPermission | Create remote directory |
| CopyBuildToHostServer | SCP build artifacts |
| UpdateBuildURL | Execute remote script |
| CleanMergedPRBranchFromHostServer | Remove PR artifacts |
| CreateDirectoryAndSetPermissionForEconestogaDlxServer | Econestoga server setup |
| CopyBuildToEconestogaDlxServer | Econestoga deployment |
| UpdateBuildURLForEconestogaDlxServer | Econestoga URL update |
3.2.3 src/service/ - Business Logic Services
HttpApiService.groovy (172 lines)
3.2.4 src/resource/ - Constants
Status.groovy
class Status {
static final Map<String, String> STAGE_STATUS = [
'SUCCESS', 'UNSTABLE', 'FAILURE', 'ABORTED', 'SKIPPED'
]
static final Map<String, String> BUILD_STATUS = [
'SUCCESS', 'UNSTABLE', 'FAILURE', 'ABORTED', 'NOT_BUILT'
]
static final Map<String, String> COMMIT_STATUS = [
'SUCCESSFUL', 'INPROGRESS', 'FAILED', 'STOPPED'
]
}
3.3 DLXJenkins/ - Pipeline Definitions (Refactored)
@Library('global-trusted-shared-library@main') _
import resource.Status
import utils.GitLibrary
pipeline {
stages {
stage('Jenkins Initialization') { steps { stageInitialization() } }
stage('Project Preparation') { steps { stageProjectPrepare() } }
stage('Linting') { steps { stageLintUnity() } }
stage('EditMode Tests') { steps { stageUnityExecution('EditMode') } }
stage('PlayMode Tests') { steps { stageUnityExecution('PlayMode') } }
stage('Build Project') { steps { stageUnityExecution('Webgl') } }
stage('Send Build Results') { steps { stageSendBuildResults() } }
}
post {
always {
script {
dir(env.PROJECT_DIR) {
shellScriptHelper(GitLibrary.ShowCurrentBranch)
shellScriptHelper(GitLibrary.ResetHardHead)
shellScriptHelper(GitLibrary.CleanUntracked)
shellScriptHelper(GitLibrary.CheckoutBranch, [env.DESTINATION_BRANCH])
}
}
}
success { bitbucketApiHelper(bitbucketApiLibrary.createBuildStatusForCommit(...)) }
failure { bitbucketApiHelper(bitbucketApiLibrary.createBuildStatusForCommit(...)) }
}
}
Characteristics:
- No business logic (all delegated to vars/ functions)
- Declarative pipeline structure
- Consistent pattern: steps { stageFunctionName() }
4. Design Patterns Applied
Source: Gang of Four (GoF) - "Design Patterns: Elements of Reusable Object-Oriented Software" (1994) by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides
4.1 Command Pattern (Behavioral)
Definition: Encapsulates a request as an object, allowing parameterization and queuing of requests.
Where: GitLibrary, ShellLibrary, SSHShellLibrary
Why it applies: Each Closure encapsulates a shell command as an object (Map with script, label, returnType). The shellScriptHelper (Invoker) executes these commands without knowing their implementation details.
GitLibrary.CheckoutBranch,
['main'])"] end subgraph Command["Command (GitLibrary)"] CLOSURE["Closure CheckoutBranch
→ returns Map"] end subgraph Invoker["Invoker (shellScriptHelper)"] VALIDATE["validateShMap()"] EXECUTE["execute*()"] end subgraph Receiver["Receiver (Jenkins)"] SH["sh(map)"] end Client -->|"passes Command"| Invoker Invoker -->|"calls"| Command Command -->|"returns Map"| Invoker Invoker -->|"delegates to"| Receiver
4.2 Facade Pattern (Structural)
Definition: Provides a simplified interface to a complex subsystem, reducing dependencies between clients and the subsystems they interact with.
Where: logger, shellScriptHelper
Why it applies: These helpers hide the complexity of Jenkins DSL (echo, sh, error) and internal logic (validation, routing, formatting) behind simple function calls.
stageLintUnity()
stageDeployBuild()"] end subgraph Facade["Facade (vars/)"] LOG["logger
.stepStart()
.stepError()
.stepInfo()"] SSH["shellScriptHelper
(Closure, args)"] end subgraph Subsystem["Subsystem (Hidden)"] ECHO["Jenkins echo()"] SH["Jenkins sh()"] ERR["Jenkins error()"] VALID["validateShMap()"] ROUTE["executeReturn*()"] end Client -->|"uses simple API"| Facade LOG -->|"delegates"| ECHO LOG -->|"delegates"| ERR SSH -->|"internally uses"| VALID SSH -->|"internally uses"| ROUTE SSH -->|"delegates"| SH
4.3 Adapter Pattern (Structural)
Definition: Converts the interface of a class into another interface clients expect, allowing incompatible interfaces to work together.
Where: shellScriptHelper
Why it applies: Converts (Closure, args) interface that Client uses into Map interface that Jenkins sh() expects.
ShellLibrary.CreateLintingResultsDir,
['workDir'])"] end subgraph Adapter["Adapter (shellScriptHelper)"] CONVERT["Closure(*args) → Map"] end subgraph Target["Target (Jenkins sh)"] SH["sh(Map)"] end subgraph Adaptee["Adaptee (ShellLibrary)"] CLOSURE["Closure returns Map"] end Client -->|"(Closure, args)"| Adapter Adapter -->|"calls"| Adaptee Adaptee -->|"returns Map"| Adapter Adapter -->|"Map"| Target
Note:
shellScriptHelperis both Adapter and Facade. Adapter for interface conversion, Facade for hiding internal complexity (validation, routing, logging).
5. Current State Summary
| Principle | Implementation |
|---|---|
| Separation of Concerns | vars/: orchestration, service/: business logic, utils/: commands, resource/: constants |
| Reusability | 46 shell commands available to all stages, single logger instance |
| Maintainability | Change logging → edit logger.groovy only, Add Git op → add 1 closure |
| Testability | Mock-friendly constructors, Spock framework integration |
6. Reference
Repository
- GitHub:
https://github.com/JindoKimKor/devops-jenkins-linux
Related Documents
- solution-by-feature.md - Feature-by-feature breakdown
- logger-system-design-integration.md - Logger System design
- domain-driven-analysis.md - DDD pattern analysis