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


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:

flowchart TB subgraph Layer1["Layer 1: Entry Point"] JF[Jenkinsfile] end subgraph Layer2["Layer 2: Orchestration (vars/)"] STAGES[Stage Functions] end subgraph Layer3["Layer 3: Services"] subgraph L3_SRC["src/service/"] HTTP[HttpApiService] end subgraph L3_VARS["vars/ (CPS Constraint)"] SSH[shellScriptHelper] BAH[bitbucketApiHelper] end end subgraph Layer4["Layer 4: Utilities (src/utils/ + src/resource/)"] GIT[GitLibrary] SHELL[ShellLibrary] SSHLIB[SSHShellLibrary] STATUS[Status Constants] subgraph L4_CC["Cross-Cutting (vars/)"] LOGGER[logger] BAL[bitbucketApiLibrary] end end JF --> STAGES STAGES --> SSH STAGES --> BAH STAGES -.-> LOGGER SSH --> GIT SSH --> SHELL SSH --> SSHLIB SSH -.-> LOGGER BAH --> BAL BAH --> HTTP STAGES --> STATUS HTTP --> STATUS

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

flowchart TB subgraph Level1["Level 1: Stage"] SS[stageStart] SE[stageEnd] end subgraph Level2["Level 2: Steps Group"] SGS[stepsGroupStart] SGE[stepsGroupEnd] end subgraph Level3["Level 3: Step"] SSTART[stepStart ➡️] SINFO[stepInfo 💬] SPROC[stepProcessing 🏃] SSUC[stepSuccess ✅] SWARN[stepWarning ⚠️] SFAIL[stepFailed ❌] SERR[stepError 🔥] end SS --> SGS SGS --> SSTART SGS --> SINFO SGS --> SPROC SGS --> SSUC SGS --> SWARN SGS --> SFAIL SGS --> SERR SGE --> SE

shellScriptHelper.groovy - Validated Shell Execution

flowchart LR subgraph Input CL[Closure from Library] ARGS[Arguments List] end subgraph Validation V1[Non-null script] V2[Non-null label] V3[Mutually exclusive flags] end subgraph Execution RS[returnStatus → int] RO[returnStdout → String] RV[returnVoid → void] end subgraph Output LOG[Logger Integration] RES[Result] end CL --> V1 ARGS --> V1 V1 --> V2 V2 --> V3 V3 --> RS V3 --> RO V3 --> RV RS --> LOG RO --> LOG RV --> LOG LOG --> RES

3.2 sharedLibraries/src/ - Core Business Logic

* CPS Constraint Note: logger.groovy, shellScriptHelper.groovy, bitbucketApiHelper.groovy, bitbucketApiLibrary.groovy are located in vars/ instead of src/ 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)
flowchart TB subgraph API["HttpApiService"] GET[get] POST[post] PUT[put] DELETE[delete] end subgraph Execution EXEC[executeRequest] end subgraph ErrorHandling["Error Handling"] UH[UnknownHostException] CE[ConnectException] ST[SocketTimeoutException] SSL[SSLHandshakeException] CC[ConnectionClosedException] IO[IOException] end subgraph Response RES["[statusCode, success, body]"] end GET --> EXEC POST --> EXEC PUT --> EXEC DELETE --> EXEC EXEC --> UH EXEC --> CE EXEC --> ST EXEC --> SSL EXEC --> CC EXEC --> IO EXEC --> RES

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.

flowchart LR subgraph Client["Client (stage*.groovy)"] CALL["shellScriptHelper(
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.

flowchart TB subgraph Client["Client (stage*.groovy)"] STAGE["stageProjectPrepare()
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.

flowchart LR subgraph Client["Client (stage*.groovy)"] CALL["shellScriptHelper(
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: shellScriptHelper is 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