Build a Deployment Pipeline Engine
Difficulty: Expert · Category: Task Scheduler · Languages: Java 17, Python 3.11, Go 1.22, Node.js 20, TypeScript 5.x
Deployment Pipeline Engine
Background
Modern software delivery relies on automated deployment pipelines that orchestrate the progression of code through multiple stages — build, test, staging, and production. Each stage must pass before the next begins. If a problem is detected, the deployment must be rolled back or cancelled quickly.
Tools like Jenkins, GitLab CI/CD, and Spinnaker implement this pattern. In this problem you will build the core orchestration engine from scratch.
Your Task
Implement the DeploymentPipelineContract interface. Your implementation must:
- Persist all state — pipelines, deployments, and history must survive restarts.
- Support named pipelines with an ordered list of stages.
- Trigger deployments that start at the first stage and advance sequentially.
- Enforce at most one active deployment per pipeline at a time.
- Support rollback at any stage, marking the deployment as ROLLED_BACK.
- Support cancellation of PENDING or IN_PROGRESS deployments.
- Maintain a deployment history per pipeline, ordered most recent first.
- Be thread-safe for concurrent operations.
Recommended infrastructure:
redis+postgres— Redis for fast state access, PostgreSQL for durable storage, but you may use any available systems.
How It Works
The platform injects your chosen infrastructure SDK(s) via constructor. For example, if you select PostgreSQL and Redis:
public class MyDeploymentPipeline implements DeploymentPipelineContract {
private final PostgresClient db;
private final RedisClient redis;
public MyDeploymentPipeline(PostgresClient db, RedisClient redis) {
this.db = db;
this.redis = redis;
}
// ... implement methods using db.execute(), redis.set(), etc.
}
See the SDK Docs tab for the full API reference of your chosen system.
Interface
public interface DeploymentPipelineContract {
void createPipeline(String name, List<String> stages);
String triggerDeployment(String pipelineName, String version);
DeploymentStatus getDeploymentStatus(String deploymentId);
boolean advanceStage(String deploymentId);
boolean rollback(String deploymentId);
List<DeploymentStatus> getHistory(String pipelineName, int limit);
boolean cancelDeployment(String deploymentId);
}
Deployment Status Lifecycle
PENDING → IN_PROGRESS → COMPLETED
→ ROLLED_BACK
→ CANCELLED
PENDING → CANCELLED
DeploymentStatus Record
record DeploymentStatus(
String id, String pipelineName, String version,
String currentStage, String status,
long startedAt, Long completedAt
)
Constraints
- Pipeline names and versions are non-null, non-empty strings
- A pipeline must have at least one stage
triggerDeploymentthrowsIllegalArgumentExceptionif the pipeline does not existtriggerDeploymentthrowsIllegalStateExceptionif a deployment is already IN_PROGRESSadvanceStagereturnsfalseif the deployment is not IN_PROGRESSrollbackreturnsfalseif the deployment is not IN_PROGRESScancelDeploymentreturnsfalseif the deployment is already terminal- History
limitmust be ≥ 1
Example Walkthrough
// 1. Setup — define a pipeline with four stages
createPipeline("prod", ["build", "test", "staging", "deploy"])
// 2. Trigger and advance a deployment (then rollback)
id1 = triggerDeployment("prod", "v1.0.0")
getDeploymentStatus(id1)
→ DeploymentStatus(id1, "prod", "v1.0.0", "build", "IN_PROGRESS", ...)
advanceStage(id1) → true // build → test
advanceStage(id1) → true // test → staging
rollback(id1) → true
getDeploymentStatus(id1).status() → "ROLLED_BACK"
// 3. Trigger a new deployment and complete it successfully
id2 = triggerDeployment("prod", "v1.0.1")
advanceStage(id2) → true // build → test
advanceStage(id2) → true // test → staging
advanceStage(id2) → true // staging → deploy
advanceStage(id2) → true // deploy → COMPLETED
getDeploymentStatus(id2).status() → "COMPLETED"
// 4. Query history — most recent first
getHistory("prod", 10) → [id2-status, id1-status]
Hints
- Use a key-value structure for pipelines and deployments for fast lookups.
- Use
UUID.randomUUID().toString()for deployment IDs. - Record
System.currentTimeMillis()forstartedAtandcompletedAt. - Track the current stage index for each deployment to simplify advancement.
- Use per-pipeline synchronization when checking for active deployments.
Infrastructure your code runs against
- PostgreSQL 16
- Redis 7.x
How your solution is graded
Your score combines functional correctness (60%), performance (20%) and code quality (20%).
- Target throughput: 2,000 operations/second
- Target p99 latency: 20 ms
- Load test concurrency: 4 concurrent clients
- Load test duration: 10 seconds
- Maximum error rate: 0.5%