diff --git a/API.md b/API.md
index b72452d..97c1333 100644
--- a/API.md
+++ b/API.md
@@ -3321,6 +3321,7 @@ new TaskBuilder(scope: Construct, id: string)
| **Name** | **Description** |
| --- | --- |
| buildTask
| Builds the `Task`. |
+| specifyRunAfter
| Allows you to specify the names of which task(s), if any, the 'Task' should run after in a pipeline. |
| withAnnotation
| Adds an annotation to the `Task` `metadata` with the provided key and value. |
| withDescription
| Sets the `description` of the `Task` being built. |
| withLabel
| Adds a label to the `Task` with the provided label key and value. |
@@ -3340,6 +3341,24 @@ public buildTask(): void
Builds the `Task`.
+##### `specifyRunAfter`
+
+```typescript
+public specifyRunAfter(taskArray: string[]): TaskBuilder
+```
+
+Allows you to specify the names of which task(s), if any, the 'Task' should run after in a pipeline.
+
+An empty array as input indicates the 'Task' yaml
+should have no runAfter field.
+By default, the value of runAfter is set to the preceeding 'Task' in the pipeline.
+
+###### `taskArray`Required
+
+- *Type:* string[]
+
+---
+
##### `withAnnotation`
```typescript
@@ -3490,9 +3509,10 @@ Adds the specified workspace to the `Task`.
| **Name** | **Type** | **Description** |
| --- | --- | --- |
| logicalID
| string
| *No description.* |
-| description
| string
| Gets the `description` of the `Task`. |
| name
| string
| Gets the name of the `Task` in the context of a pipeline. |
+| description
| string
| Gets the `description` of the `Task`. |
| parameters
| ParameterBuilder[]
| *No description.* |
+| runAfter
| string[]
| Gets the list of task names for the runAfter value of the `Task`. |
| workspaces
| WorkspaceBuilder[]
| Gets the workspaces for the `Task`. |
---
@@ -3507,27 +3527,29 @@ public readonly logicalID: string;
---
-##### `description`Optional
+##### `name`Required
```typescript
-public readonly description: string;
+public readonly name: string;
```
- *Type:* string
-Gets the `description` of the `Task`.
+Gets the name of the `Task` in the context of a pipeline.
+
+If not set, the 'Task' id is used.
---
-##### `name`Optional
+##### `description`Optional
```typescript
-public readonly name: string;
+public readonly description: string;
```
- *Type:* string
-Gets the name of the `Task` in the context of a pipeline.
+Gets the `description` of the `Task`.
---
@@ -3541,6 +3563,18 @@ public readonly parameters: ParameterBuilder[];
---
+##### `runAfter`Optional
+
+```typescript
+public readonly runAfter: string[];
+```
+
+- *Type:* string[]
+
+Gets the list of task names for the runAfter value of the `Task`.
+
+---
+
##### `workspaces`Optional
```typescript
diff --git a/src/builders.ts b/src/builders.ts
index b8b9121..166e188 100644
--- a/src/builders.ts
+++ b/src/builders.ts
@@ -664,6 +664,7 @@ export class TaskBuilder {
private _labels?: {
[key: string]: string;
};
+ private _runafter?: string[];
/**
* Creates a new instance of the `TaskBuilder` using the given `scope` and
@@ -717,9 +718,10 @@ export class TaskBuilder {
/**
* Gets the name of the `Task` in the context of a pipeline.
+ * If not set, the 'Task' id is used.
*/
- public get name(): string | undefined {
- return this._name;
+ public get name(): string {
+ return this._name || this._id;
}
/**
@@ -807,6 +809,25 @@ export class TaskBuilder {
return this;
}
+ /**
+ * Allows you to specify the names of which task(s), if any, the 'Task' should
+ * run after in a pipeline. An empty array as input indicates the 'Task' yaml
+ * should have no runAfter field.
+ * By default, the value of runAfter is set to the preceeding 'Task' in the pipeline.
+ * @param taskArray
+ */
+ public specifyRunAfter(taskArray: string[]): TaskBuilder {
+ this._runafter = taskArray;
+ return this;
+ }
+
+ /**
+ * Gets the list of task names for the runAfter value of the `Task`.
+ */
+ public get runAfter(): string[] | undefined {
+ return this._runafter;
+ }
+
/**
* Builds the `Task`.
*/
@@ -1019,7 +1040,7 @@ export class PipelineBuilder {
this._tasks?.forEach((t, i) => {
- const taskName = t.name || t.logicalID;
+ const taskName = t.name;
if (taskNames.find(it => {
return it == taskName;
})) {
@@ -1044,7 +1065,19 @@ export class PipelineBuilder {
});
});
- const pt = createOrderedPipelineTask(t, ((i > 0) ? (this._tasks![i - 1].name || this._tasks![i - 1].logicalID) : ''), taskParams, taskWorkspaces);
+ const after = [];
+ if (t.runAfter != undefined) {
+ t.runAfter.forEach(name => {
+ if (!this._tasks?.find(it => {return (it.name) == name;})) {
+ throw new Error(`'${name}' supplied as value for runAfter but no such task found in pipeline.`);
+ }
+ after.push(name);
+ });
+ } else if (i > 0) {
+ after.push(this._tasks![i - 1].name);
+ }
+
+ const pt = createOrderedPipelineTask(t, after, taskParams, taskWorkspaces);
pipelineTasks.push(pt);
@@ -1076,20 +1109,20 @@ export class PipelineBuilder {
}
}
-function createOrderedPipelineTask(t: TaskBuilder, after: string, params: TaskParam[], ws: TaskWorkspace[]): PipelineTask {
- if (after) {
+function createOrderedPipelineTask(t: TaskBuilder, after: string[], params: TaskParam[], ws: TaskWorkspace[]): PipelineTask {
+ if (after.length) {
return {
- name: t.name || t.logicalID,
+ name: t.name,
taskRef: {
name: t.logicalID,
},
- runAfter: [after],
+ runAfter: after,
params: params,
workspaces: ws,
};
}
return {
- name: t.name || t.logicalID,
+ name: t.name,
taskRef: {
name: t.logicalID,
},
diff --git a/test/__snapshots__/pipelinebuilder.test.ts.snap b/test/__snapshots__/pipelinebuilder.test.ts.snap
index 8e60bbe..fa3c47d 100644
--- a/test/__snapshots__/pipelinebuilder.test.ts.snap
+++ b/test/__snapshots__/pipelinebuilder.test.ts.snap
@@ -229,6 +229,87 @@ exports[`PipelineBuilderTest PipelineBuilderWithParameters 1`] = `
]
`;
+exports[`PipelineBuilderTest PipelineBuilderWithRunAfter 1`] = `
+[
+ {
+ "apiVersion": "tekton.dev/v1",
+ "kind": "Task",
+ "metadata": {
+ "annotations": undefined,
+ "labels": undefined,
+ "name": "print-readme",
+ },
+ "spec": {
+ "description": undefined,
+ "params": [],
+ "results": [],
+ "steps": [],
+ "workspaces": [],
+ },
+ },
+ {
+ "apiVersion": "tekton.dev/v1",
+ "kind": "Task",
+ "metadata": {
+ "annotations": undefined,
+ "labels": undefined,
+ "name": "git-clone",
+ },
+ "spec": {
+ "description": undefined,
+ "params": [],
+ "results": [],
+ "steps": [],
+ "workspaces": [],
+ },
+ },
+ {
+ "apiVersion": "tekton.dev/v1",
+ "kind": "Pipeline",
+ "metadata": {
+ "name": "clone-read",
+ },
+ "spec": {
+ "description": undefined,
+ "params": [],
+ "tasks": [
+ {
+ "name": "cat-readme",
+ "params": [],
+ "runAfter": [
+ "fetch-again",
+ ],
+ "taskRef": {
+ "name": "print-readme",
+ },
+ "workspaces": [],
+ },
+ {
+ "name": "fetch-source",
+ "params": [],
+ "taskRef": {
+ "name": "git-clone",
+ },
+ "workspaces": [],
+ },
+ {
+ "name": "fetch-again",
+ "params": [],
+ "runAfter": [
+ "fetch-source",
+ ],
+ "taskRef": {
+ "name": "git-clone",
+ },
+ "workspaces": [],
+ },
+ ],
+ "workspaces": [],
+ },
+ },
+]
+`;
+
exports[`PipelineBuilderTest PipelineBuilderWithSimilarTasks 1`] = `
[
{
diff --git a/test/pipelinebuilder.test.ts b/test/pipelinebuilder.test.ts
index 55618e3..c969499 100644
--- a/test/pipelinebuilder.test.ts
+++ b/test/pipelinebuilder.test.ts
@@ -309,6 +309,43 @@ class MyTestChartWithSimilarTasks extends Chart {
}
}
+class MyTestChartWithRunAfter extends Chart {
+ constructor(scope: Construct, id: string, props?: ChartProps) {
+ super(scope, id, props);
+
+ const firstTask = new TaskBuilder(this, 'git-clone')
+ .withName('fetch-source')
+ .specifyRunAfter([]);
+
+ const secondTask = new TaskBuilder(this, 'git-clone')
+ .withName('fetch-again');
+
+ const thirdTask = new TaskBuilder(this, 'print-readme')
+ .withName('cat-readme')
+ .specifyRunAfter(['fetch-again']);
+
+ new PipelineBuilder(this, 'clone-read')
+ .withTask(thirdTask)
+ .withTask(firstTask)
+ .withTask(secondTask)
+ .buildPipeline({ includeDependencies: true });
+ }
+}
+
+class MyTestChartWithRunAfterError extends Chart {
+ constructor(scope: Construct, id: string, props?: ChartProps) {
+ super(scope, id, props);
+
+ const myTask = new TaskBuilder(this, 'print-readme')
+ .withName('cat-readme')
+ .specifyRunAfter(['fetch-source']);
+
+ new PipelineBuilder(this, 'clone-read')
+ .withTask(myTask)
+ .buildPipeline({ includeDependencies: true });
+ }
+}
+
describe('PipelineBuilderTest', () => {
test('PipelineRunBuilder', () => {
const app = Testing.app();
@@ -383,4 +420,19 @@ describe('PipelineBuilderTest', () => {
const results = Testing.synth(chart);
expect(results).toMatchSnapshot();
});
+
+ test('PipelineBuilderWithRunAfter', () => {
+ const app = Testing.app();
+ const chart = new MyTestChartWithRunAfter(app, 'test-chart');
+ const results = Testing.synth(chart);
+ expect(results).toMatchSnapshot();
+ });
+
+ test('PipelineBuilderWithRunAfterError', () => {
+ const app = Testing.app();
+ const f = () => {
+ new MyTestChartWithRunAfterError(app, 'test-chart');
+ };
+ expect(f).toThrowError('\'fetch-source\' supplied as value for runAfter but no such task found in pipeline.');
+ });
});