Repository: cdklabs/cdk-pipelines-github
Pull request #9 (2021-08-31 14:26:00)

feat: customize build job
Allow specifying pre- and post- steps as well as container options for build jobs




Patch:
diff --git a/API.md b/API.md
index 95923d7..9b4ab61 100644
--- a/API.md
+++ b/API.md
@@ -11,7 +11,7 @@ Name|Description
 
 Name|Description
 ----|-----------
-[AwsCredentialsSecertNames](#cdk-pipelines-github-awscredentialssecertnames)|*No description*
+[AwsCredentialsSecrets](#cdk-pipelines-github-awscredentialssecrets)|Names of secrets for AWS credentials.
 [CheckRunOptions](#cdk-pipelines-github-checkrunoptions)|Check run options.
 [CheckSuiteOptions](#cdk-pipelines-github-checksuiteoptions)|Check suite options.
 [ContainerCredentials](#cdk-pipelines-github-containercredentials)|Credentials to use to authenticate to Docker registries.
@@ -84,8 +84,11 @@ new GitHubWorkflow(scope: Construct, id: string, props: GitHubWorkflowProps)
 * **id** (<code>string</code>)  *No description*
 * **props** (<code>[GitHubWorkflowProps](#cdk-pipelines-github-githubworkflowprops)</code>)  *No description*
   * **synth** (<code>[IFileSetProducer](#aws-cdk-pipelines-ifilesetproducer)</code>)  The build step that produces the CDK Cloud Assembly. 
-  * **awsCredentials** (<code>[AwsCredentialsSecertNames](#cdk-pipelines-github-awscredentialssecertnames)</code>)  Names of GitHub repository secrets that include AWS credentials for deployment. __*Default*__: `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`.
+  * **awsCredentials** (<code>[AwsCredentialsSecrets](#cdk-pipelines-github-awscredentialssecrets)</code>)  Names of GitHub repository secrets that include AWS credentials for deployment. __*Default*__: `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`.
+  * **buildContainer** (<code>[ContainerOptions](#cdk-pipelines-github-containeroptions)</code>)  Build container options. __*Default*__: GitHub defaults
   * **cdkCliVersion** (<code>string</code>)  Version of the CDK CLI to use. __*Default*__: automatic
+  * **postBuildSteps** (<code>Array<[JobStep](#cdk-pipelines-github-jobstep)></code>)  GitHub workflow steps to execute after build. __*Default*__: []
+  * **preBuildSteps** (<code>Array<[JobStep](#cdk-pipelines-github-jobstep)></code>)  GitHub workflow steps to execute before build. __*Default*__: []
   * **preSynthed** (<code>boolean</code>)  Indicates if the repository already contains a synthesized `cdk.out` directory, in which case we will simply checkout the repo in jobs that require `cdk.out`. __*Default*__: false
   * **workflowName** (<code>string</code>)  Name of the workflow. __*Default*__: "deploy"
   * **workflowPath** (<code>string</code>)  File path for the GitHub workflow. __*Default*__: ".github/workflows/deploy.yml"
@@ -118,10 +121,10 @@ protected doBuildPipeline(): void
 
 
 
-## struct AwsCredentialsSecertNames  <a id="cdk-pipelines-github-awscredentialssecertnames"></a>
-
+## struct AwsCredentialsSecrets  <a id="cdk-pipelines-github-awscredentialssecrets"></a>
 
 
+Names of secrets for AWS credentials.
 
 
 
@@ -244,8 +247,11 @@ Props for `GitHubWorkflow`.
 Name | Type | Description 
 -----|------|-------------
 **synth** | <code>[IFileSetProducer](#aws-cdk-pipelines-ifilesetproducer)</code> | The build step that produces the CDK Cloud Assembly.
-**awsCredentials**? | <code>[AwsCredentialsSecertNames](#cdk-pipelines-github-awscredentialssecertnames)</code> | Names of GitHub repository secrets that include AWS credentials for deployment.<br/>__*Default*__: `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`.
+**awsCredentials**? | <code>[AwsCredentialsSecrets](#cdk-pipelines-github-awscredentialssecrets)</code> | Names of GitHub repository secrets that include AWS credentials for deployment.<br/>__*Default*__: `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`.
+**buildContainer**? | <code>[ContainerOptions](#cdk-pipelines-github-containeroptions)</code> | Build container options.<br/>__*Default*__: GitHub defaults
 **cdkCliVersion**? | <code>string</code> | Version of the CDK CLI to use.<br/>__*Default*__: automatic
+**postBuildSteps**? | <code>Array<[JobStep](#cdk-pipelines-github-jobstep)></code> | GitHub workflow steps to execute after build.<br/>__*Default*__: []
+**preBuildSteps**? | <code>Array<[JobStep](#cdk-pipelines-github-jobstep)></code> | GitHub workflow steps to execute before build.<br/>__*Default*__: []
 **preSynthed**? | <code>boolean</code> | Indicates if the repository already contains a synthesized `cdk.out` directory, in which case we will simply checkout the repo in jobs that require `cdk.out`.<br/>__*Default*__: false
 **workflowName**? | <code>string</code> | Name of the workflow.<br/>__*Default*__: "deploy"
 **workflowPath**? | <code>string</code> | File path for the GitHub workflow.<br/>__*Default*__: ".github/workflows/deploy.yml"
diff --git a/src/pipeline.ts b/src/pipeline.ts
index a16ce9d..3c418fe 100644
--- a/src/pipeline.ts
+++ b/src/pipeline.ts
@@ -58,7 +58,25 @@ export interface GitHubWorkflowProps extends PipelineBaseProps {
    *
    * @default - `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`.
    */
-  readonly awsCredentials?: AwsCredentialsSecertNames;
+  readonly awsCredentials?: AwsCredentialsSecrets;
+
+  /**
+   * Build container options.
+   * @default - GitHub defaults
+   */
+  readonly buildContainer?: github.ContainerOptions;
+
+  /**
+   * GitHub workflow steps to execute before build.
+   * @default []
+   */
+  readonly preBuildSteps?: github.JobStep[];
+
+  /**
+   * GitHub workflow steps to execute after build.
+   * @default []
+   */
+  readonly postBuildSteps?: github.JobStep[];
 }
 
 /**
@@ -70,14 +88,21 @@ export class GitHubWorkflow extends PipelineBase {
 
   private readonly workflowTriggers: github.Triggers;
   private readonly preSynthed: boolean;
-  private readonly awsCredentials: AwsCredentialsSecertNames;
+  private readonly awsCredentials: AwsCredentialsSecrets;
   private readonly cdkCliVersion?: string;
+  private readonly buildContainer?: github.ContainerOptions;
+  private readonly preBuildSteps: github.JobStep[];
+  private readonly postBuildSteps: github.JobStep[];
 
   constructor(scope: Construct, id: string, props: GitHubWorkflowProps) {
     super(scope, id, props);
 
     this.cdkCliVersion = props.cdkCliVersion;
     this.preSynthed = props.preSynthed ?? false;
+    this.buildContainer = props.buildContainer;
+    this.preBuildSteps = props.preBuildSteps ?? [];
+    this.postBuildSteps = props.postBuildSteps ?? [];
+
     this.awsCredentials = props.awsCredentials ?? {
       accessKeyId: 'AWS_ACCESS_KEY_ID',
       secretAccessKey: 'AWS_SECRET_ACCESS_KEY',
@@ -304,13 +329,16 @@ export class GitHubWorkflow extends PipelineBase {
         runsOn: RUNS_ON,
         needs: this.renderDependencies(node),
         env: step.env,
+        container: this.buildContainer,
         steps: [
           ...this.stepsToCheckout(),
+          ...this.preBuildSteps,
           ...installSteps,
           {
             name: 'Build',
             run: step.commands.join('\n'),
           },
+          ...this.postBuildSteps,
           ...this.stepsToUploadAssembly(cdkOut.directory),
         ],
       },
@@ -485,7 +513,10 @@ function snakeCaseKeys<T = unknown>(obj: T, sep = '-'): T {
   return result as any;
 }
 
-export interface AwsCredentialsSecertNames {
+/**
+ * Names of secrets for AWS credentials.
+ */
+export interface AwsCredentialsSecrets {
   /**
    * @default "AWS_ACCESS_KEY_ID"
    */


Test patch:
diff --git a/test/__snapshots__/github.test.ts.snap b/test/__snapshots__/github.test.ts.snap
index 5cc534e..cc118a7 100644
--- a/test/__snapshots__/github.test.ts.snap
+++ b/test/__snapshots__/github.test.ts.snap
@@ -15,11 +15,17 @@ jobs:
     runs-on: ubuntu-latest
     needs: []
     env: {}
+    container:
+      image: alpine
     steps:
       - name: Checkout
         uses: actions/checkout@v2
+      - uses: actions/setup-node@v2
+        with:
+          node-version: \\"14\\"
       - name: Build
         run: echo \\"nothing to do (cdk.out is committed)\\"
+      - run: echo post-build
   Assets-FileAsset1:
     name: Publish Assets Assets-FileAsset1
     needs:
@@ -310,6 +316,7 @@ jobs:
     runs-on: ubuntu-latest
     needs: []
     env: {}
+    container: null
     steps:
       - name: Checkout
         uses: actions/checkout@v2
@@ -340,6 +347,7 @@ jobs:
     runs-on: ubuntu-latest
     needs: []
     env: {}
+    container: null
     steps:
       - name: Checkout
         uses: actions/checkout@v2
diff --git a/test/example-app.ts b/test/example-app.ts
index 254025c..3b306c1 100644
--- a/test/example-app.ts
+++ b/test/example-app.ts
@@ -66,6 +66,16 @@ export class GitHubExampleApp extends App {
       }),
       workflowPath: path.join(workflowsDir, 'deploy.yml'),
       preSynthed: true,
+      buildContainer: { image: 'alpine' },
+      preBuildSteps: [
+        {
+          uses: 'actions/setup-node@v2',
+          with: { nodeVersion: '14' },
+        },
+      ],
+      postBuildSteps: [
+        { run: 'echo post-build' },
+      ],
     });
 
     pipeline.addStage(new MyStage(this, 'StageA', { env: EnvironmentUtils.parse(props.envA) }));