diff --git a/API.md b/API.md
index 2d41ff3..b069b65 100644
--- a/API.md
+++ b/API.md
@@ -774,6 +774,8 @@ Returns the apiVersion and kind for "Task".
### BuilderOptions
+The options for builders for the `buildXX()` methods.
+
#### Initializer
```typescript
@@ -786,18 +788,37 @@ const builderOptions: BuilderOptions = { ... }
| **Name** | **Type** | **Description** |
| --- | --- | --- |
-| buildDependencies
| boolean
| *No description.* |
+| includeDependencies
| boolean
| If true, all the dependent objects are generated with the build. |
+| includeRuns
| boolean
| If true, the builder will also synth associated runs. |
---
-##### `buildDependencies`Required
+##### `includeDependencies`Optional
```typescript
-public readonly buildDependencies: boolean;
+public readonly includeDependencies: boolean;
```
- *Type:* boolean
+If true, all the dependent objects are generated with the build.
+
+This is
+designed to run on as minimal cluster as possible, with as few pre steps
+as possible.
+
+---
+
+##### `includeRuns`Optional
+
+```typescript
+public readonly includeRuns: boolean;
+```
+
+- *Type:* boolean
+
+If true, the builder will also synth associated runs.
+
---
### NamedResource
@@ -2405,6 +2426,8 @@ public readonly name: string;
### TaskStepBuilder
+Creates a `Step` in a `Task`.
+
#### Initializers
```typescript
@@ -2423,6 +2446,7 @@ new TaskStepBuilder()
| **Name** | **Description** |
| --- | --- |
| buildTaskStep
| *No description.* |
+| fromScriptData
| If supplied, uses the provided script data as-is for the script value. |
| fromScriptObject
| If supplied, uses the cdk8s `ApiObject` supplied as the body of the `script` for the `Task`. |
| fromScriptUrl
| If supplied, uses the content found at the given URL for the `script` value of the step. |
| withArgs
| The args to use with the `command`. |
@@ -2440,6 +2464,25 @@ new TaskStepBuilder()
public buildTaskStep(): TaskStep
```
+##### `fromScriptData`
+
+```typescript
+public fromScriptData(data: string): TaskStepBuilder
+```
+
+If supplied, uses the provided script data as-is for the script value.
+
+Use this when you have the script data from a source other than a file or
+an object. Use the other methods, such as `fromScriptUrl` (when the script
+is in a file) or `scriptFromObject` (when the script is a CDK8s object)
+rather than resolving those yourself.
+
+###### `data`Required
+
+- *Type:* string
+
+---
+
##### `fromScriptObject`
```typescript
@@ -2577,8 +2620,7 @@ The `workingDir` of the `Task`.
| command
| string[]
| Gets the command used for the `Step` on the `Task`. |
| image
| string
| The name of the container `image` used to execute the `Step` of the `Task`. |
| name
| string
| The name of the `Step` of the `Task`. |
-| scriptObj
| cdk8s.ApiObject
| Gets the object that is used for the `script` value, if there is one defined. |
-| scriptUrl
| string
| Gets the URL from which the script data should be loaded, if it is defined. |
+| scriptData
| string
| *No description.* |
| workingDir
| string
| *No description.* |
---
@@ -2631,28 +2673,14 @@ The name of the `Step` of the `Task`.
---
-##### `scriptObj`Optional
-
-```typescript
-public readonly scriptObj: ApiObject;
-```
-
-- *Type:* cdk8s.ApiObject
-
-Gets the object that is used for the `script` value, if there is one defined.
-
----
-
-##### `scriptUrl`Optional
+##### `scriptData`Optional
```typescript
-public readonly scriptUrl: string;
+public readonly scriptData: string;
```
- *Type:* string
-Gets the URL from which the script data should be loaded, if it is defined.
-
---
##### `workingDir`Optional
@@ -2668,6 +2696,8 @@ public readonly workingDir: string;
### WorkspaceBuilder
+Builds the Workspaces for use by Tasks and Pipelines.
+
#### Initializers
```typescript
@@ -2726,9 +2756,9 @@ public withName(name: string): WorkspaceBuilder
| **Name** | **Type** | **Description** |
| --- | --- | --- |
-| description
| string
| *No description.* |
-| logicalID
| string
| *No description.* |
-| name
| string
| *No description.* |
+| description
| string
| Gets the description of the workspace. |
+| logicalID
| string
| Gets the logical ID of the `Workspace`. |
+| name
| string
| Gets the name of the workspace. |
---
@@ -2740,6 +2770,8 @@ public readonly description: string;
- *Type:* string
+Gets the description of the workspace.
+
---
##### `logicalID`Optional
@@ -2750,6 +2782,8 @@ public readonly logicalID: string;
- *Type:* string
+Gets the logical ID of the `Workspace`.
+
---
##### `name`Optional
@@ -2760,6 +2794,8 @@ public readonly name: string;
- *Type:* string
+Gets the name of the workspace.
+
---
diff --git a/src/builders.ts b/src/builders.ts
index 43ddcff..281b868 100644
--- a/src/builders.ts
+++ b/src/builders.ts
@@ -4,33 +4,70 @@
import * as fs from 'fs';
-import { ApiObject, Yaml } from 'cdk8s';
+import { Yaml } from 'cdk8s';
import { Construct } from 'constructs';
import { buildParam } from './common';
import { Pipeline, PipelineParam, PipelineTask, PipelineTaskWorkspace, PipelineWorkspace } from './pipelines';
import { Task, TaskEnvValueSource, TaskParam, TaskProps, TaskSpecParam, TaskStep, TaskStepEnv, TaskWorkspace } from './tasks';
+/**
+ * The options for builders for the `buildXX()` methods.
+ */
export interface BuilderOptions {
- readonly buildDependencies: boolean;
+ /**
+ * If true, all the dependent objects are generated with the build. This is
+ * designed to run on as minimal cluster as possible, with as few pre steps
+ * as possible.
+ */
+ readonly includeDependencies?: boolean;
+ /**
+ * If true, the builder will also synth associated runs.
+ */
+ readonly includeRuns?: boolean;
}
+/**
+ * The default options for the builders.
+ */
+export const DefaultBuilderOptions: BuilderOptions = {
+ includeDependencies: false,
+ includeRuns: false,
+};
+
+/**
+ * Builds the Workspaces for use by Tasks and Pipelines.
+ */
export class WorkspaceBuilder {
private _logicalID: string;
private _name?: string;
private _description?: string;
+ /**
+ * Creates the `WorkspaceBuilder`, using the given `id` as the logical ID for
+ * the workspace.
+ * @param id
+ */
constructor(id: string) {
this._logicalID = id;
}
+ /**
+ * Gets the logical ID of the `Workspace`.
+ */
public get logicalID(): string | undefined {
return this._logicalID;
}
+ /**
+ * Gets the name of the workspace.
+ */
public get name(): string | undefined {
return this._name;
}
+ /**
+ * Gets the description of the workspace.
+ */
public get description(): string {
return this._description || '';
}
@@ -155,20 +192,105 @@ export class ParameterBuilder {
/**
* Returns true if this parameter expects input at the pipeline level.
*/
- public get requiresPipelineParameter() : boolean {
+ public get requiresPipelineParameter(): boolean {
return this._requiresPipelineParam;
}
}
+/**
+ * Resolves the `script` through different means.
+ */
+interface ScriptResolver {
+ /**
+ * Gets the body of the script.
+ * @returns string The script.
+ */
+ scriptData(): string;
+}
+
+/**
+ * Resolves the provided object into a YAML string.
+ */
+class ObjScriptResolver implements ScriptResolver {
+ readonly _obj: any;
+
+ /**
+ * Creates an instance of the `ObjScriptResolver`.
+ * @param obj The object to serialize to YAML for the script.
+ */
+ constructor(obj: any) {
+ this._obj = obj;
+ }
+
+ /**
+ * Gets the body of the script as a YAML representation of the object.
+ */
+ public scriptData(): string {
+ return Yaml.stringify(this._obj);
+ }
+}
+
+/**
+ * Gets the content from the provided URL and returns it as the script data.
+ */
+class UrlScriptResolver implements ScriptResolver {
+ readonly _url: string;
+
+ /**
+ * Creates an instance of the `UrlScriptResolver` with the provided URL.
+ * @param url
+ */
+ constructor(url: string) {
+ this._url = url;
+ }
+
+ /**
+ * Gets the body of the script from the provided URL.
+ * @return string Script data.
+ */
+ public scriptData(): string {
+ const data = fs.readFileSync(this._url, {
+ encoding: 'utf8',
+ flag: 'r',
+ });
+
+ return data.replace(/\n/g, '\\n');
+ }
+}
+
+/**
+ * Gets the content from the static value provided.
+ */
+class StaticScriptResolver implements ScriptResolver {
+ readonly _script: string;
+
+ /**
+ * Creates an instance of the `StaticScriptResolver`.
+ * @param data
+ */
+ constructor(data: string) {
+ this._script = data;
+ }
+
+ /**
+ * Returns the static value provided.
+ */
+ public scriptData(): string {
+ return this._script;
+ }
+}
+
+/**
+ * Creates a `Step` in a `Task`.
+ */
export class TaskStepBuilder {
- private _url?: string;
- private _obj?: any;
private _name?: string;
private _dir?: string;
private _image?: string;
private _cmd?: string[];
private _args?: string[];
private _env?: TaskStepEnv[];
+ private _script?: ScriptResolver;
/**
*
@@ -192,19 +314,8 @@ export class TaskStepBuilder {
return this._image;
}
- /**
- * Gets the URL from which the script data should be loaded, if it is defined.
- */
- public get scriptUrl(): string | undefined {
- return this._url;
- }
-
- /**
- * Gets the object that is used for the `script` value, if there is one
- * defined.
- */
- public get scriptObj(): ApiObject | undefined {
- return this._obj;
+ public get scriptData(): string | undefined {
+ return this._script?.scriptData();
}
/**
@@ -267,7 +378,7 @@ export class TaskStepBuilder {
* @param url
*/
public fromScriptUrl(url: string): TaskStepBuilder {
- this._url = url;
+ this._script = new UrlScriptResolver(url);
return this;
}
@@ -281,7 +392,22 @@ export class TaskStepBuilder {
* @param obj
*/
public fromScriptObject(obj: any): TaskStepBuilder {
- this._obj = obj;
+ this._script = new ObjScriptResolver(obj);
+ return this;
+ }
+
+ /**
+ * If supplied, uses the provided script data as-is for the script value.
+ *
+ * Use this when you have the script data from a source other than a file or
+ * an object. Use the other methods, such as `fromScriptUrl` (when the script
+ * is in a file) or `scriptFromObject` (when the script is a CDK8s object)
+ * rather than resolving those yourself.
+ *
+ * @param data
+ */
+ public fromScriptData(data: string): TaskStepBuilder {
+ this._script = new StaticScriptResolver(data);
return this;
}
@@ -306,40 +432,14 @@ export class TaskStepBuilder {
}
public buildTaskStep(): TaskStep | undefined {
- if (this.scriptUrl) {
- if (this.scriptObj) {
- throw new Error('Cannot specify both a URL source and an object source for the script.');
- }
- // Load the script from the URL location and use it
- const data = fs.readFileSync(this.scriptUrl, {
- encoding: 'utf8',
- flag: 'r',
- });
-
- const lines = data.replace(/\n/g, '\\n');
- if (data) {
- return {
- name: this.name,
- image: this.image,
- script: lines,
- workingDir: this.workingDir,
- env: this._env,
- };
- }
- } else if (this.scriptObj) {
- if (this.scriptUrl) {
- throw new Error('Cannot specify both an object source and a URL source for the script');
- }
- const yamlData = Yaml.stringify(this.scriptObj);
- if (yamlData) {
- return {
- name: this.name,
- image: this.image,
- script: yamlData,
- workingDir: this.workingDir,
- env: this._env,
- };
- }
+ if (this._script) {
+ return {
+ name: this.name,
+ image: this.image,
+ script: this.scriptData,
+ workingDir: this.workingDir,
+ env: this._env,
+ };
} else {
return {
name: this.name,
@@ -352,8 +452,6 @@ export class TaskStepBuilder {
}
return undefined;
}
-
-
}
/**
@@ -557,7 +655,7 @@ export class PipelineBuilder {
* Builds the actual [Pipeline]() from the settings configured using the
* fluid syntax.
*/
- public buildPipeline(opts: BuilderOptions = { buildDependencies: false }): void {
+ public buildPipeline(opts: BuilderOptions = DefaultBuilderOptions): void {
// TODO: validate the object
const pipelineParams = new Map();
@@ -613,7 +711,7 @@ export class PipelineBuilder {
workspaces: taskWorkspaces,
});
- if (opts.buildDependencies) {
+ if (opts.includeDependencies) {
// Build the task if the user has asked for the dependencies to be
// built along with the pipeline.
t.buildTask();
diff --git a/test/__snapshots__/taskbuilder.test.ts.snap b/test/__snapshots__/taskbuilder.test.ts.snap
index 629431a..f6daa11 100644
--- a/test/__snapshots__/taskbuilder.test.ts.snap
+++ b/test/__snapshots__/taskbuilder.test.ts.snap
@@ -149,6 +149,33 @@ request and populate the pr workspace with the state of the pull request, includ
]
`;
+exports[`TaskBuilderTest ScriptDataBuilder 1`] = `
+[
+ {
+ "apiVersion": "tekton.dev/v1beta1",
+ "kind": "Task",
+ "metadata": {
+ "name": "ansible-runner",
+ },
+ "spec": {
+ "description": "Task to run Ansible playbooks using Ansible Runner",
+ "params": [],
+ "steps": [
+ {
+ "env": undefined,
+ "image": "docker.io/hello-world",
+ "name": "requirements",
+ "script": "#!/usr/bin/env bash
+echo this is my script data",
+ "workingDir": undefined,
+ },
+ ],
+ "workspaces": [],
+ },
+ },
+]
+`;
+
exports[`TaskBuilderTest TaskBuilderBasic 1`] = `
[
{
diff --git a/test/pipelinebuilder.test.ts b/test/pipelinebuilder.test.ts
index b028438..c807975 100644
--- a/test/pipelinebuilder.test.ts
+++ b/test/pipelinebuilder.test.ts
@@ -19,7 +19,7 @@ class MyTestChart extends Chart {
.withName('clone-build-push')
.withDescription('This pipeline closes a repository, builds a Docker image, etc.')
.withTask(myTask)
- .buildPipeline({ buildDependencies: true });
+ .buildPipeline({ includeDependencies: true });
}
}
diff --git a/test/taskbuilder.test.ts b/test/taskbuilder.test.ts
index 72017b4..392395f 100644
--- a/test/taskbuilder.test.ts
+++ b/test/taskbuilder.test.ts
@@ -100,6 +100,22 @@ class TestBasicTaskBuildFromObject extends Chart {
}
}
+class TestBasicTaskBuildFromScriptData extends Chart {
+
+ constructor(scope: Construct, id: string, props?: ChartProps) {
+ super(scope, id, props);
+
+ new TaskBuilder(this, 'my-task')
+ .withName('ansible-runner')
+ .withDescription('Task to run Ansible playbooks using Ansible Runner')
+ .withStep(new TaskStepBuilder()
+ .withName('requirements')
+ .withImage('docker.io/hello-world')
+ .fromScriptData('#!/usr/bin/env bash\necho this is my script data'))
+ .buildTask();
+ }
+}
+
class TestPullRequestTaskBuild extends Chart {
constructor(scope: Construct, id: string, props?: ChartProps) {
super(scope, id, props);
@@ -168,4 +184,10 @@ describe('TaskBuilderTest', () => {
const results = Testing.synth(chart);
expect(results).toMatchSnapshot();
});
+ test('ScriptDataBuilder', () => {
+ const app = Testing.app();
+ const chart = new TestBasicTaskBuildFromScriptData(app, 'apply-object');
+ const results = Testing.synth(chart);
+ expect(results).toMatchSnapshot();
+ });
});