From fab93c63ba68c6398499e7df87a56a70d854ab88 Mon Sep 17 00:00:00 2001 From: Janario Oliveira Date: Mon, 22 Mar 2021 16:50:10 +0100 Subject: [PATCH] fix(codebuild): Fixed build spec file format to return yaml (#13445) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-amplify/README.md | 2 +- .../@aws-cdk/aws-amplify/test/app.test.ts | 4 +-- packages/@aws-cdk/aws-codebuild/README.md | 3 ++ .../@aws-cdk/aws-codebuild/lib/build-spec.ts | 25 +++++++++++++++++ packages/@aws-cdk/aws-codebuild/package.json | 2 ++ .../aws-codebuild/test/test.project.ts | 28 +++++++++++++++++++ 6 files changed, 61 insertions(+), 3 deletions(-) diff --git a/packages/@aws-cdk/aws-amplify/README.md b/packages/@aws-cdk/aws-amplify/README.md index b8e3bd91c2306..a706cb73bb39b 100644 --- a/packages/@aws-cdk/aws-amplify/README.md +++ b/packages/@aws-cdk/aws-amplify/README.md @@ -38,7 +38,7 @@ const amplifyApp = new amplify.App(this, 'MyApp', { repository: '', oauthToken: cdk.SecretValue.secretsManager('my-github-token') }), - buildSpec: codebuild.BuildSpec.fromObject({ // Alternatively add a `amplify.yml` to the repo + buildSpec: codebuild.BuildSpec.fromObjectToYaml({ // Alternatively add a `amplify.yml` to the repo version: '1.0', frontend: { phases: { diff --git a/packages/@aws-cdk/aws-amplify/test/app.test.ts b/packages/@aws-cdk/aws-amplify/test/app.test.ts index 8cff8e3d5b66d..a9b91f01976df 100644 --- a/packages/@aws-cdk/aws-amplify/test/app.test.ts +++ b/packages/@aws-cdk/aws-amplify/test/app.test.ts @@ -17,7 +17,7 @@ test('create an app connected to a GitHub repository', () => { repository: 'aws-cdk', oauthToken: SecretValue.plainText('secret'), }), - buildSpec: codebuild.BuildSpec.fromObject({ + buildSpec: codebuild.BuildSpec.fromObjectToYaml({ version: '1.0', frontend: { phases: { @@ -34,7 +34,7 @@ test('create an app connected to a GitHub repository', () => { // THEN expect(stack).toHaveResource('AWS::Amplify::App', { Name: 'App', - BuildSpec: '{\n \"version\": \"1.0\",\n \"frontend\": {\n \"phases\": {\n \"build\": {\n \"commands\": [\n \"npm run build\"\n ]\n }\n }\n }\n}', + BuildSpec: 'version: \"1.0\"\nfrontend:\n phases:\n build:\n commands:\n - npm run build\n', IAMServiceRole: { 'Fn::GetAtt': [ 'AppRole1AF9B530', diff --git a/packages/@aws-cdk/aws-codebuild/README.md b/packages/@aws-cdk/aws-codebuild/README.md index cdc3d9f59b665..c0e82f9a6b708 100644 --- a/packages/@aws-cdk/aws-codebuild/README.md +++ b/packages/@aws-cdk/aws-codebuild/README.md @@ -152,6 +152,9 @@ const project = codebuild.Project(stack, 'MyProject', { }); ``` +If you'd prefer your buildspec to be rendered as YAML in the template, +use the `fromObjectToYaml()` method instead of `fromObject()`. + Because we've not set the `name` property, this example will set the `overrideArtifactName` parameter, and produce an artifact named as defined in the Buildspec file, uploaded to an S3 bucket (`bucket`). The path will be diff --git a/packages/@aws-cdk/aws-codebuild/lib/build-spec.ts b/packages/@aws-cdk/aws-codebuild/lib/build-spec.ts index 5f33babced96a..d7e89355a5151 100644 --- a/packages/@aws-cdk/aws-codebuild/lib/build-spec.ts +++ b/packages/@aws-cdk/aws-codebuild/lib/build-spec.ts @@ -1,4 +1,5 @@ import { IResolveContext, Lazy, Stack } from '@aws-cdk/core'; +import * as yaml_cfn from '@aws-cdk/yaml-cfn'; /** * BuildSpec for CodeBuild projects @@ -8,6 +9,15 @@ export abstract class BuildSpec { return new ObjectBuildSpec(value); } + /** + * Create a buildspec from an object that will be rendered as YAML in the resulting CloudFormation template. + * + * @param value the object containing the buildspec that will be rendered as YAML + */ + public static fromObjectToYaml(value: {[key: string]: any}): BuildSpec { + return new YamlBuildSpec(value); + } + /** * Use a file from the source as buildspec * @@ -70,6 +80,21 @@ class ObjectBuildSpec extends BuildSpec { } } +/** + * BuildSpec that exports into YAML format + */ +class YamlBuildSpec extends BuildSpec { + public readonly isImmediate: boolean = true; + + constructor(public readonly spec: {[key: string]: any}) { + super(); + } + + public toBuildSpec(): string { + return yaml_cfn.serialize(this.spec); + } +} + /** * Merge two buildspecs into a new BuildSpec * diff --git a/packages/@aws-cdk/aws-codebuild/package.json b/packages/@aws-cdk/aws-codebuild/package.json index 7b268062d474f..e09f4f68e5264 100644 --- a/packages/@aws-cdk/aws-codebuild/package.json +++ b/packages/@aws-cdk/aws-codebuild/package.json @@ -100,6 +100,7 @@ "@aws-cdk/aws-secretsmanager": "0.0.0", "@aws-cdk/core": "0.0.0", "@aws-cdk/region-info": "0.0.0", + "@aws-cdk/yaml-cfn": "0.0.0", "constructs": "^3.2.0" }, "homepage": "https://github.com/aws/aws-cdk", @@ -118,6 +119,7 @@ "@aws-cdk/aws-secretsmanager": "0.0.0", "@aws-cdk/core": "0.0.0", "@aws-cdk/region-info": "0.0.0", + "@aws-cdk/yaml-cfn": "0.0.0", "constructs": "^3.2.0" }, "engines": { diff --git a/packages/@aws-cdk/aws-codebuild/test/test.project.ts b/packages/@aws-cdk/aws-codebuild/test/test.project.ts index 159511589ead7..3d7f8e726fd69 100644 --- a/packages/@aws-cdk/aws-codebuild/test/test.project.ts +++ b/packages/@aws-cdk/aws-codebuild/test/test.project.ts @@ -53,6 +53,34 @@ export = { test.done(); }, + 'can use yamlbuildspec literal'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + + // WHEN + new codebuild.Project(stack, 'Project', { + buildSpec: codebuild.BuildSpec.fromObjectToYaml({ + text: 'text', + decimal: 10, + list: ['say hi'], + obj: { + text: 'text', + decimal: 10, + list: ['say hi'], + }, + }), + }); + + // THEN + expect(stack).to(haveResourceLike('AWS::CodeBuild::Project', { + Source: { + BuildSpec: 'text: text\ndecimal: 10\nlist:\n - say hi\nobj:\n text: text\n decimal: 10\n list:\n - say hi\n', + }, + })); + + test.done(); + }, + 'must supply buildspec when using nosource'(test: Test) { // GIVEN const stack = new cdk.Stack();