Tekton Pipelines in Java: Building CI/CD Pipelines Programmatically

Tekton is a powerful Kubernetes-native framework for creating CI/CD systems. While Tekton pipelines are typically defined using YAML, you can manage and interact with them programmatically using Java.

Core Concepts

Tekton Components

  • Pipeline: Defines a series of tasks
  • Task: Individual step in a pipeline
  • PipelineRun: Instance of a pipeline execution
  • TaskRun: Instance of a task execution
  • PipelineResource: Inputs and outputs for pipelines

Java Client Setup

Dependencies

<!-- Kubernetes Java Client --> <dependency> <groupId>io.kubernetes</groupId> <artifactId>client-java</artifactId> <version>18.0.0</version> </dependency> <!-- Tekton Models --> <dependency> <groupId>io.fabric8</groupId> <artifactId>tekton-client</artifactId> <version>5.12.0</version> </dependency> <!-- YAML Processing --> <dependency> <groupId>com.fasterxml.jackson.dataformat</groupId> <artifactId>jackson-dataformat-yaml</artifactId> <version>2.15.0</version> </dependency> <!-- HTTP Client --> <dependency> <groupId>org.apache.httpcomponents.client5</groupId> <artifactId>httpclient5</artifactId> <version>5.2.1</version> </dependency>

Core Tekton Client Implementation

Example 1: Tekton Client Factory and Configuration

@Component @Slf4j public class TektonClientFactory { private final TektonClient tektonClient; private final ObjectMapper yamlMapper; public TektonClientFactory(@Value("${kube.config.path:}") String kubeConfigPath) { this.yamlMapper = new ObjectMapper(new YAMLFactory()); this.tektonClient = createTektonClient(kubeConfigPath); } private TektonClient createTektonClient(String kubeConfigPath) { try { Config config; if (kubeConfigPath != null && !kubeConfigPath.isEmpty()) { config = Config.fromKubeconfig(null, Files.readString(Path.of(kubeConfigPath)), null); } else { // Use in-cluster config or default config = new ConfigBuilder().build(); } return new DefaultTektonClient(config); } catch (Exception e) { log.error("Failed to create Tekton client", e); throw new TektonClientException("Tekton client initialization failed", e); } } public TektonClient getClient() { return tektonClient; } public ObjectMapper getYamlMapper() { return yamlMapper; } public boolean isClusterAvailable() { try { tektonClient.v1().tasks().inAnyNamespace().list(); return true; } catch (Exception e) { log.warn("Kubernetes cluster not available", e); return false; } } } // Custom exceptions class TektonClientException extends RuntimeException { public TektonClientException(String message) { super(message); } public TektonClientException(String message, Throwable cause) { super(message, cause); } } // Configuration properties @ConfigurationProperties(prefix = "tekton") @Data public class TektonProperties { private String namespace = "default"; private String serviceAccount = "tekton-bot"; private int timeoutMinutes = 60; private Retry retry = new Retry(); @Data public static class Retry { private int maxAttempts = 3; private long backoffMs = 5000; private double backoffMultiplier = 2.0; } }

Example 2: Pipeline Management Service

@Service @Slf4j public class PipelineManagementService { private final TektonClient tektonClient; private final TektonProperties properties; private final ObjectMapper yamlMapper; public PipelineManagementService(TektonClientFactory clientFactory, TektonProperties properties) { this.tektonClient = clientFactory.getClient(); this.properties = properties; this.yamlMapper = clientFactory.getYamlMapper(); } // Pipeline Definition DTOs @Data public static class PipelineDefinition { private String name; private String description; private List<TaskDefinition> tasks; private Map<String, String> parameters; private Map<String, String> labels; private Map<String, String> annotations; public PipelineDefinition(String name) { this.name = name; this.tasks = new ArrayList<>(); this.parameters = new HashMap<>(); this.labels = new HashMap<>(); this.annotations = new HashMap<>(); } public PipelineDefinition withTask(TaskDefinition task) { this.tasks.add(task); return this; } public PipelineDefinition withParameter(String name, String value) { this.parameters.put(name, value); return this; } public PipelineDefinition withLabel(String key, String value) { this.labels.put(key, value); return this; } public PipelineDefinition withAnnotation(String key, String value) { this.annotations.put(key, value); return this; } } @Data public static class TaskDefinition { private String name; private String taskRef; private Map<String, String> parameters; private List<String> runAfter; private Map<String, String> workspaces; private Map<String, String> labels; public TaskDefinition(String name, String taskRef) { this.name = name; this.taskRef = taskRef; this.parameters = new HashMap<>(); this.runAfter = new ArrayList<>(); this.workspaces = new HashMap<>(); this.labels = new HashMap<>(); } public TaskDefinition withParameter(String name, String value) { this.parameters.put(name, value); return this; } public TaskDefinition runAfter(String taskName) { this.runAfter.add(taskName); return this; } public TaskDefinition withWorkspace(String name, String workspace) { this.workspaces.put(name, workspace); return this; } public TaskDefinition withLabel(String key, String value) { this.labels.put(key, value); return this; } } public Pipeline createPipeline(PipelineDefinition definition) { try { log.info("Creating pipeline: {}", definition.getName()); Pipeline pipeline = buildPipelineFromDefinition(definition); Pipeline created = tektonClient.v1().pipelines() .inNamespace(properties.getNamespace()) .createOrReplace(pipeline); log.info("Successfully created pipeline: {}", created.getMetadata().getName()); return created; } catch (Exception e) { log.error("Failed to create pipeline: {}", definition.getName(), e); throw new PipelineException("Pipeline creation failed", e); } } public Pipeline updatePipeline(PipelineDefinition definition) { try { log.info("Updating pipeline: {}", definition.getName()); Pipeline pipeline = buildPipelineFromDefinition(definition); Pipeline updated = tektonClient.v1().pipelines() .inNamespace(properties.getNamespace()) .withName(definition.getName()) .patch(pipeline); log.info("Successfully updated pipeline: {}", updated.getMetadata().getName()); return updated; } catch (Exception e) { log.error("Failed to update pipeline: {}", definition.getName(), e); throw new PipelineException("Pipeline update failed", e); } } public boolean deletePipeline(String pipelineName) { try { log.info("Deleting pipeline: {}", pipelineName); boolean deleted = tektonClient.v1().pipelines() .inNamespace(properties.getNamespace()) .withName(pipelineName) .delete(); if (deleted) { log.info("Successfully deleted pipeline: {}", pipelineName); } else { log.warn("Pipeline not found: {}", pipelineName); } return deleted; } catch (Exception e) { log.error("Failed to delete pipeline: {}", pipelineName, e); throw new PipelineException("Pipeline deletion failed", e); } } public Pipeline getPipeline(String pipelineName) { try { return tektonClient.v1().pipelines() .inNamespace(properties.getNamespace()) .withName(pipelineName) .get(); } catch (Exception e) { log.error("Failed to get pipeline: {}", pipelineName, e); throw new PipelineException("Pipeline retrieval failed", e); } } public List<Pipeline> listPipelines() { try { return tektonClient.v1().pipelines() .inNamespace(properties.getNamespace()) .list() .getItems(); } catch (Exception e) { log.error("Failed to list pipelines", e); throw new PipelineException("Pipeline listing failed", e); } } public List<Pipeline> listPipelinesByLabel(String labelSelector) { try { return tektonClient.v1().pipelines() .inNamespace(properties.getNamespace()) .withLabelSelector(labelSelector) .list() .getItems(); } catch (Exception e) { log.error("Failed to list pipelines with selector: {}", labelSelector, e); throw new PipelineException("Pipeline listing failed", e); } } private Pipeline buildPipelineFromDefinition(PipelineDefinition definition) { return new PipelineBuilder() .withNewMetadata() .withName(definition.getName()) .withNamespace(properties.getNamespace()) .withLabels(definition.getLabels()) .withAnnotations(definition.getAnnotations()) .endMetadata() .withNewSpec() .withParams(buildParams(definition.getParameters())) .withTasks(buildPipelineTasks(definition.getTasks())) .endSpec() .build(); } private List<ParamSpec> buildParams(Map<String, String> parameters) { return parameters.entrySet().stream() .map(entry -> new ParamSpecBuilder() .withName(entry.getKey()) .withType("string") .withDescription("Parameter: " + entry.getKey()) .build()) .collect(Collectors.toList()); } private List<PipelineTask> buildPipelineTasks(List<TaskDefinition> taskDefinitions) { List<PipelineTask> tasks = new ArrayList<>(); for (TaskDefinition taskDef : taskDefinitions) { PipelineTask task = new PipelineTaskBuilder() .withName(taskDef.getName()) .withNewTaskRef() .withName(taskDef.getTaskRef()) .endTaskRef() .withParams(buildTaskParams(taskDef.getParameters())) .withWorkspaces(buildTaskWorkspaces(taskDef.getWorkspaces())) .withRunAfter(taskDef.getRunAfter()) .build(); tasks.add(task); } return tasks; } private List<Param> buildTaskParams(Map<String, String> parameters) { return parameters.entrySet().stream() .map(entry -> new ParamBuilder() .withName(entry.getKey()) .withNewValue(entry.getValue()) .build()) .collect(Collectors.toList()); } private List<WorkspacePipelineTaskBinding> buildTaskWorkspaces(Map<String, String> workspaces) { return workspaces.entrySet().stream() .map(entry -> new WorkspacePipelineTaskBindingBuilder() .withName(entry.getKey()) .withWorkspace(entry.getValue()) .build()) .collect(Collectors.toList()); } public Pipeline createPipelineFromYaml(String yamlContent) { try { Pipeline pipeline = yamlMapper.readValue(yamlContent, Pipeline.class); Pipeline created = tektonClient.v1().pipelines() .inNamespace(properties.getNamespace()) .createOrReplace(pipeline); log.info("Created pipeline from YAML: {}", created.getMetadata().getName()); return created; } catch (Exception e) { log.error("Failed to create pipeline from YAML", e); throw new PipelineException("YAML pipeline creation failed", e); } } public String exportPipelineToYaml(String pipelineName) { try { Pipeline pipeline = getPipeline(pipelineName); return yamlMapper.writeValueAsString(pipeline); } catch (Exception e) { log.error("Failed to export pipeline to YAML: {}", pipelineName, e); throw new PipelineException("Pipeline export failed", e); } } } class PipelineException extends RuntimeException { public PipelineException(String message) { super(message); } public PipelineException(String message, Throwable cause) { super(message, cause); } }

Example 3: PipelineRun Management Service

@Service @Slf4j public class PipelineRunService { private final TektonClient tektonClient; private final TektonProperties properties; private final ObjectMapper yamlMapper; private final ScheduledExecutorService monitorExecutor; public PipelineRunService(TektonClientFactory clientFactory, TektonProperties properties) { this.tektonClient = clientFactory.getClient(); this.properties = properties; this.yamlMapper = clientFactory.getYamlMapper(); this.monitorExecutor = Executors.newScheduledThreadPool(3); } @Data public static class PipelineRunRequest { private String pipelineName; private String runName; private Map<String, String> parameters; private Map<String, String> workspaces; private Map<String, String> labels; private Map<String, String> annotations; private String serviceAccountName; public PipelineRunRequest(String pipelineName) { this.pipelineName = pipelineName; this.runName = pipelineName + "-run-" + System.currentTimeMillis(); this.parameters = new HashMap<>(); this.workspaces = new HashMap<>(); this.labels = new HashMap<>(); this.annotations = new HashMap<>(); this.serviceAccountName = "default"; } public PipelineRunRequest withParameter(String name, String value) { this.parameters.put(name, value); return this; } public PipelineRunRequest withWorkspace(String name, String pvc) { this.workspaces.put(name, pvc); return this; } public PipelineRunRequest withLabel(String key, String value) { this.labels.put(key, value); return this; } public PipelineRunRequest withAnnotation(String key, String value) { this.annotations.put(key, value); return this; } public PipelineRunRequest withServiceAccount(String serviceAccount) { this.serviceAccountName = serviceAccount; return this; } } @Data public static class PipelineRunResult { private PipelineRun pipelineRun; private PipelineRunStatus status; private List<TaskRunInfo> taskRuns; private Instant startTime; private Instant completionTime; private Duration duration; private boolean success; private String errorMessage; public static PipelineRunResult fromPipelineRun(PipelineRun pipelineRun) { PipelineRunResult result = new PipelineRunResult(); result.setPipelineRun(pipelineRun); result.setStatus(pipelineRun.getStatus()); if (pipelineRun.getStatus() != null) { result.setStartTime(parseTimestamp(pipelineRun.getStatus().getStartTime())); result.setCompletionTime(parseTimestamp(pipelineRun.getStatus().getCompletionTime())); if (result.getStartTime() != null && result.getCompletionTime() != null) { result.setDuration(Duration.between(result.getStartTime(), result.getCompletionTime())); } result.setSuccess(isPipelineRunSuccessful(pipelineRun)); if (pipelineRun.getStatus().getConditions() != null) { Optional<Condition> failedCondition = pipelineRun.getStatus().getConditions().stream() .filter(c -> "Failed".equals(c.getType())) .findFirst(); if (failedCondition.isPresent()) { result.setErrorMessage(failedCondition.get().getMessage()); } } } return result; } private static Instant parseTimestamp(String timestamp) { if (timestamp == null) return null; try { return Instant.parse(timestamp); } catch (Exception e) { return null; } } private static boolean isPipelineRunSuccessful(PipelineRun pipelineRun) { if (pipelineRun.getStatus() == null || pipelineRun.getStatus().getConditions() == null) { return false; } return pipelineRun.getStatus().getConditions().stream() .filter(c -> "Succeeded".equals(c.getType())) .map(Condition::getStatus) .anyMatch("True"::equals); } } @Data public static class TaskRunInfo { private String name; private String taskName; private String status; private Instant startTime; private Instant completionTime; private Duration duration; private List<StepInfo> steps; private boolean success; private String errorMessage; } @Data public static class StepInfo { private String name; private String container; private String image; private String status; private Instant startTime; private Instant completionTime; private Duration duration; private boolean success; private String errorMessage; } public PipelineRun createPipelineRun(PipelineRunRequest request) { try { log.info("Creating PipelineRun: {} for pipeline: {}", request.getRunName(), request.getPipelineName()); PipelineRun pipelineRun = buildPipelineRun(request); PipelineRun created = tektonClient.v1().pipelineRuns() .inNamespace(properties.getNamespace()) .createOrReplace(pipelineRun); log.info("Successfully created PipelineRun: {}", created.getMetadata().getName()); return created; } catch (Exception e) { log.error("Failed to create PipelineRun: {}", request.getRunName(), e); throw new PipelineRunException("PipelineRun creation failed", e); } } public PipelineRun createPipelineRunFromYaml(String yamlContent) { try { PipelineRun pipelineRun = yamlMapper.readValue(yamlContent, PipelineRun.class); PipelineRun created = tektonClient.v1().pipelineRuns() .inNamespace(properties.getNamespace()) .createOrReplace(pipelineRun); log.info("Created PipelineRun from YAML: {}", created.getMetadata().getName()); return created; } catch (Exception e) { log.error("Failed to create PipelineRun from YAML", e); throw new PipelineRunException("YAML PipelineRun creation failed", e); } } private PipelineRun buildPipelineRun(PipelineRunRequest request) { return new PipelineRunBuilder() .withNewMetadata() .withName(request.getRunName()) .withNamespace(properties.getNamespace()) .withLabels(request.getLabels()) .withAnnotations(request.getAnnotations()) .endMetadata() .withNewSpec() .withNewPipelineRef() .withName(request.getPipelineName()) .endPipelineRef() .withParams(buildPipelineRunParams(request.getParameters())) .withWorkspaces(buildPipelineRunWorkspaces(request.getWorkspaces())) .withServiceAccountName(request.getServiceAccountName()) .withTimeouts(buildTimeouts()) .endSpec() .build(); } private List<Param> buildPipelineRunParams(Map<String, String> parameters) { return parameters.entrySet().stream() .map(entry -> new ParamBuilder() .withName(entry.getKey()) .withNewValue(entry.getValue()) .build()) .collect(Collectors.toList()); } private List<WorkspaceBinding> buildPipelineRunWorkspaces(Map<String, String> workspaces) { return workspaces.entrySet().stream() .map(entry -> new WorkspaceBindingBuilder() .withName(entry.getKey()) .withNewPersistentVolumeClaim() .withClaimName(entry.getValue()) .endPersistentVolumeClaim() .build()) .collect(Collectors.toList()); } private TimeoutFields buildTimeouts() { return new TimeoutFieldsBuilder() .withPipeline(Duration.ofMinutes(properties.getTimeoutMinutes()).toString()) .build(); } public PipelineRun getPipelineRun(String runName) { try { return tektonClient.v1().pipelineRuns() .inNamespace(properties.getNamespace()) .withName(runName) .get(); } catch (Exception e) { log.error("Failed to get PipelineRun: {}", runName, e); throw new PipelineRunException("PipelineRun retrieval failed", e); } } public PipelineRunResult getPipelineRunResult(String runName) { try { PipelineRun pipelineRun = getPipelineRun(runName); PipelineRunResult result = PipelineRunResult.fromPipelineRun(pipelineRun); // Enrich with TaskRun details result.setTaskRuns(getTaskRunInfos(pipelineRun)); return result; } catch (Exception e) { log.error("Failed to get PipelineRun result: {}", runName, e); throw new PipelineRunException("PipelineRun result retrieval failed", e); } } private List<TaskRunInfo> getTaskRunInfos(PipelineRun pipelineRun) { List<TaskRunInfo> taskRunInfos = new ArrayList<>(); if (pipelineRun.getStatus() == null || pipelineRun.getStatus().getTaskRuns() == null) { return taskRunInfos; } for (Map.Entry<String, PipelineRunTaskRunStatus> entry : pipelineRun.getStatus().getTaskRuns().entrySet()) { TaskRunInfo taskRunInfo = new TaskRunInfo(); taskRunInfo.setName(entry.getKey()); PipelineRunTaskRunStatus status = entry.getValue(); if (status.getStatus() != null) { taskRunInfo.setTaskName(status.getPipelineTaskName()); taskRunInfo.setStatus(status.getStatus().getConditions().toString()); taskRunInfo.setStartTime(parseTimestamp(status.getStatus().getStartTime())); taskRunInfo.setCompletionTime(parseTimestamp(status.getStatus().getCompletionTime())); if (taskRunInfo.getStartTime() != null && taskRunInfo.getCompletionTime() != null) { taskRunInfo.setDuration(Duration.between( taskRunInfo.getStartTime(), taskRunInfo.getCompletionTime())); } // Extract step information taskRunInfo.setSteps(extractStepInfos(status.getStatus())); // Determine success taskRunInfo.setSuccess(isTaskRunSuccessful(status.getStatus())); // Extract error message if any taskRunInfo.setErrorMessage(extractErrorMessage(status.getStatus())); } taskRunInfos.add(taskRunInfo); } return taskRunInfos; } private List<StepInfo> extractStepInfos(TaskRunStatus status) { List<StepInfo> steps = new ArrayList<>(); if (status.getSteps() == null) return steps; for (StepState stepState : status.getSteps()) { StepInfo stepInfo = new StepInfo(); stepInfo.setName(stepState.getName()); stepInfo.setContainer(stepState.getContainer()); stepInfo.setImage(stepState.getImageID()); stepInfo.setStatus(stepState.getTerminated() != null ? "Terminated" : "Running"); stepInfo.setStartTime(parseTimestamp(stepState.getTerminated() != null ? stepState.getTerminated().getStartedAt() : null)); stepInfo.setCompletionTime(parseTimestamp(stepState.getTerminated() != null ? stepState.getTerminated().getFinishedAt() : null)); if (stepInfo.getStartTime() != null && stepInfo.getCompletionTime() != null) { stepInfo.setDuration(Duration.between( stepInfo.getStartTime(), stepInfo.getCompletionTime())); } stepInfo.setSuccess(stepState.getTerminated() != null && stepState.getTerminated().getExitCode() == 0); if (stepState.getTerminated() != null && stepState.getTerminated().getExitCode() != 0) { stepInfo.setErrorMessage("Exit code: " + stepState.getTerminated().getExitCode()); } steps.add(stepInfo); } return steps; } private boolean isTaskRunSuccessful(TaskRunStatus status) { if (status == null || status.getConditions() == null) return false; return status.getConditions().stream() .filter(c -> "Succeeded".equals(c.getType())) .map(Condition::getStatus) .anyMatch("True"::equals); } private String extractErrorMessage(TaskRunStatus status) { if (status == null || status.getConditions() == null) return null; Optional<Condition> failedCondition = status.getConditions().stream() .filter(c -> "Failed".equals(c.getType())) .findFirst(); return failedCondition.map(Condition::getMessage).orElse(null); } private Instant parseTimestamp(String timestamp) { if (timestamp == null) return null; try { return Instant.parse(timestamp); } catch (Exception e) { return null; } } public CompletableFuture<PipelineRunResult> runPipelineAndWait(PipelineRunRequest request) { return runPipelineAndWait(request, Duration.ofMinutes(properties.getTimeoutMinutes())); } public CompletableFuture<PipelineRunResult> runPipelineAndWait(PipelineRunRequest request, Duration timeout) { return CompletableFuture.supplyAsync(() -> { try { // Create the PipelineRun PipelineRun pipelineRun = createPipelineRun(request); String runName = pipelineRun.getMetadata().getName(); log.info("Waiting for PipelineRun completion: {}", runName); // Wait for completion with timeout PipelineRun completedRun = waitForPipelineRunCompletion(runName, timeout); // Get detailed result PipelineRunResult result = getPipelineRunResult(runName); log.info("PipelineRun completed: {} - Success: {}", runName, result.isSuccess()); return result; } catch (Exception e) { log.error("PipelineRun execution failed", e); throw new PipelineRunException("PipelineRun execution failed", e); } }); } private PipelineRun waitForPipelineRunCompletion(String runName, Duration timeout) { long endTime = System.currentTimeMillis() + timeout.toMillis(); while (System.currentTimeMillis() < endTime) { try { PipelineRun pipelineRun = getPipelineRun(runName); if (pipelineRun.getStatus() != null) { boolean isCompleted = pipelineRun.getStatus().getCompletionTime() != null; boolean hasConditions = pipelineRun.getStatus().getConditions() != null; if (isCompleted && hasConditions) { return pipelineRun; } } // Wait before checking again Thread.sleep(5000); // 5 seconds } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new PipelineRunException("PipelineRun wait interrupted", e); } catch (Exception e) { log.warn("Error checking PipelineRun status, retrying...", e); try { Thread.sleep(10000); // 10 seconds on error } catch (InterruptedException ie) { Thread.currentThread().interrupt(); throw new PipelineRunException("PipelineRun wait interrupted", ie); } } } throw new PipelineRunException("PipelineRun timed out after " + timeout); } public List<PipelineRun> listPipelineRuns() { try { return tektonClient.v1().pipelineRuns() .inNamespace(properties.getNamespace()) .list() .getItems(); } catch (Exception e) { log.error("Failed to list PipelineRuns", e); throw new PipelineRunException("PipelineRun listing failed", e); } } public List<PipelineRun> listPipelineRunsByPipeline(String pipelineName) { try { return tektonClient.v1().pipelineRuns() .inNamespace(properties.getNamespace()) .withLabel("tekton.dev/pipeline", pipelineName) .list() .getItems(); } catch (Exception e) { log.error("Failed to list PipelineRuns for pipeline: {}", pipelineName, e); throw new PipelineRunException("PipelineRun listing failed", e); } } public boolean deletePipelineRun(String runName) { try { log.info("Deleting PipelineRun: {}", runName); boolean deleted = tektonClient.v1().pipelineRuns() .inNamespace(properties.getNamespace()) .withName(runName) .delete(); if (deleted) { log.info("Successfully deleted PipelineRun: {}", runName); } else { log.warn("PipelineRun not found: {}", runName); } return deleted; } catch (Exception e) { log.error("Failed to delete PipelineRun: {}", runName, e); throw new PipelineRunException("PipelineRun deletion failed", e); } } @PreDestroy public void cleanup() { monitorExecutor.shutdown(); try { if (!monitorExecutor.awaitTermination(30, TimeUnit.SECONDS)) { monitorExecutor.shutdownNow(); } } catch (InterruptedException e) { monitorExecutor.shutdownNow(); Thread.currentThread().interrupt(); } } } class PipelineRunException extends RuntimeException { public PipelineRunException(String message) { super(message); } public PipelineRunException(String message, Throwable cause) { super(message, cause); } }

Example 4: Task Management Service

```java
@Service
@Slf4j
public class TaskManagementService {

private final TektonClient tektonClient; private final TektonProperties properties; private final ObjectMapper yamlMapper; public TaskManagementService(TektonClientFactory clientFactory, TektonProperties properties) { this.tektonClient = clientFactory.getClient(); this.properties = properties; this.yamlMapper = clientFactory.getYamlMapper(); } @Data public static class TaskDefinition { private String name; private String description; private List<TaskStep> steps; private List<ParamSpec> parameters; private List<WorkspaceDeclaration> workspaces; private Map<String, String> labels; private Map<String, String> annotations; public TaskDefinition(String name) { this.name = name; this.steps = new ArrayList<>(); this.parameters = new ArrayList<>(); this.workspaces = new ArrayList<>(); this.labels = new HashMap<>(); this.annotations = new HashMap<>(); } public TaskDefinition withStep(TaskStep step) { this.steps.add(step); return this; } public TaskDefinition withParameter(ParamSpec parameter) { this.parameters.add(parameter); return this; } public TaskDefinition withWorkspace(WorkspaceDeclaration workspace) { this.workspaces.add(workspace); return this; } public TaskDefinition withLabel(String key, String value) { this.labels.put(key, value); return this; } public TaskDefinition withAnnotation(String key, String value) { this.annotations.put(key, value); return this; } } @Data public static class TaskStep { private String name; private String image; private List<String> command; private List<String> args; private List<String> script; private Map<String, String> env; private String workingDir; private Map<String, String> volumeMounts; public TaskStep(String name, String image) { this.name = name; this.image = image; this.command = new ArrayList<>(); this.args = new ArrayList<>(); this.script = new ArrayList<>(); this.env = new HashMap<>(); this.volumeMounts = new HashMap<>(); } public TaskStep withCommand(String... commands) { this.command.addAll(Arrays.asList(commands)); return this; } public TaskStep withArg(String... arguments) { this.args.addAll(Arrays.asList(arguments)); return this; } public TaskStep withScriptLine(String line) { this.script.add(line); return this; } public TaskStep withEnv(String key, String value) { this.env.put(key, value); return this; } public TaskStep withVolumeMount(String name, String mountPath) { this.volumeMounts.put(name, mountPath); return this; } } public Task createTask(TaskDefinition definition) { try { log.info("Creating task: {}", definition.getName()); Task task = buildTaskFromDefinition(definition); Task created = tektonClient.v1().tasks() .inNamespace(properties.getNamespace()) .createOrReplace(task); log.info("Successfully created task: {}", created.getMetadata().getName()); return created; } catch (Exception e) { log.error("Failed to create task: {}", definition.getName(), e); throw new TaskException("Task creation failed", e); } } public Task updateTask(TaskDefinition definition) { try { log.info("Updating task: {}", definition.getName()); Task task = buildTaskFromDefinition(definition); Task updated = tektonClient.v1().tasks() .inNamespace(properties.getNamespace()) .withName(definition.getName()) .patch(task); log.info("Successfully updated task: {}", updated.getMetadata().getName()); return updated; } catch (Exception e) { log.error("Failed to update task: {}", definition.getName(), e); throw new TaskException("Task update failed", e); } } public boolean deleteTask(String taskName) { try { log.info("Deleting task: {}", taskName); boolean deleted = tektonClient.v1().tasks() .inNamespace(properties.getNamespace()) .withName(taskName) .delete(); if (deleted) { log.info("Successfully deleted task: {}", taskName); } else { log.warn("Task not found: {}", taskName); } return deleted; } catch (Exception e) { log.error("Failed to delete task: {}", taskName, e); throw new TaskException("Task deletion failed", e); } } public Task getTask(String taskName) { try { return tektonClient.v1().tasks() .inNamespace(properties.getNamespace()) .withName(taskName) .get(); } catch (Exception e) { log.error("Failed to get task: {}", taskName, e); throw new TaskException("Task retrieval failed", e); } } public List<Task> listTasks() { try { return tektonClient.v1().tasks() .inNamespace(properties.getNamespace()) .list() .getItems(); } catch (Exception e) { log.error("Failed to list tasks", e); throw new TaskException("Task listing failed", e); } } private Task buildTaskFromDefinition(TaskDefinition definition) { TaskBuilder builder = new TaskBuilder() .withNewMetadata() .withName(definition.getName()) .withNamespace(properties.getNamespace()) .withLabels(definition.getLabels()) .withAnnotations(definition.getAnnotations()) .endMetadata() .withNewSpec(); // Add steps for (TaskStep step : definition.getSteps()) { builder.addNewStep() .withName(step.getName()) .withImage(step.getImage()) .withCommand(step.getCommand()) .withArgs(step.getArgs()) .withScript(step.getScript() != null && !step.getScript().isEmpty() ? String.join("\n", step.getScript()) : null) .withEnv(step.getEnv().entrySet().stream() .map(entry -> new EnvVarBuilder() .withName(entry.getKey()) .withValue(entry.getValue()) .build()) .collect(Collectors.toList())) .withWorkingDir(step.getWorkingDir()) .endStep(); } // Add parameters if (!definition.getParameters().isEmpty()) { builder.withParams(definition.getParameters()); } // Add workspaces if (!definition.getWorkspaces().isEmpty()) { builder.withWorkspaces(definition.getWorkspaces()); } return builder.endSpec().build(); } public Task createTaskFromYaml(String yamlContent) { try { Task task = yamlMapper.readValue(yamlContent, Task.class

Leave a Reply

Your email address will not be published. Required fields are marked *


Macro Nepal Helper