MILTON.GitOperations Architecture

The MILTON.GitOperations service is responsible for asynchronously cloning Git repositories and uploading their contents to object storage (S3) for downstream processing. It has been structured following a Clean Architecture approach to ensure separation of concerns and maintainability.

Architectural Layers

1. Application Layer (Application/)

Contains the core use cases, business logic orchestration, and interface definitions.

  • Contracts (Application/Contracts/GitMessages.cs): Defines the message schemas used for inter-service communication over RabbitMQ via Wolverine.
  • Interfaces (Application/Interfaces/IGitCloneService.cs): Abstractions for external infrastructure services.
  • Handlers (Application/Handlers/CloneRepositoriesHandler.cs): The Wolverine message handler that processes incoming CloneRepositoriesCommand messages. It orchestrates the cloning process using IGitCloneService and returns the aggregated results.

2. Infrastructure Layer (Infrastructure/)

Contains implementations of the interfaces defined in the Application layer.

  • Services (Infrastructure/Services/GitCloneService.cs): Implements IGitCloneService. Responsible for interacting with LibGit2Sharp to clone repositories to the local file system and using IRepoFileStore to upload the cloned contents to S3 storage.

Message Contracts

The service communicates asynchronously using the following Wolverine message contracts:

CloneRepositoriesCommand

Published By: API
Consumed By: MILTON.GitOperations
Identity: [MessageIdentity("clone-repositories")]
Command to clone all repositories for a project. Contains:

  • TenantId (Guid)
  • ProjectId (int)
  • Repositories (List of CloneRepositoryRequest)

CloneRepositoryRequest

Represents an individual repository clone request:

  • RepositoryUrl (string)
  • GitToken (string?) - Optional OAuth token for authentication.
  • FileExclusions (List of string) - Glob patterns for files to exclude during S3 upload.

GitCloneResult

Represents the result of a single repository clone operation:

  • RepositoryUrl (string)
  • Success (bool)
  • LocalPath (string?)
  • ErrorMessage (string?)
  • RepositoryName (string?)
  • FileExclusions (List of string)

CloneRepositoriesResult

The final result returned by the handler, aggregating the individual clone results:

  • ProjectId (int)
  • TotalRepositories (int)
  • SuccessfulClones (int)
  • FailedClones (int)
  • Results (List of GitCloneResult)

Data Flow

  1. API publishes CloneRepositoriesCommand to the git-operations RabbitMQ queue.
  2. Wolverine routes the message to CloneRepositoriesHandler.Handle.
  3. The handler loops through the repositories and delegates to GitCloneService.
  4. GitCloneService uses LibGit2Sharp to clone the code into a local repos/{TenantId}/{ProjectId}/{RepoName} directory.
  5. The service uploads the contents of the local repository to S3 using IRepoFileStore.UploadRepositoryAsync, applying the configured file exclusions.
  6. A CloneRepositoriesResult is returned, summarizing the operation.