Skip to content

Commit 7cda567

Browse files
feat(codebuild): adds file asset support to build-spec (#24289)
Adds `fromAsset` to the `BuildSpec` class to allow referencing local files as a project's buildspec. Uploads the file to s3 and references the object arn in the `buildSpec` property of `Codebuild.Project`. `isImmediate` is true for AssetBuildSpec because it's actual meaning is not can be defined at synth time, but it exsists somewhere other than the project's source code, which in this case is true. Requires referencing of the project so adds `scope` as an optional parameter to `toBuildSpec` method. fixes: #1138 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent 34d4c18 commit 7cda567

15 files changed

+3262
-6
lines changed

packages/@aws-cdk/aws-codebuild/README.md

+52-3
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,58 @@ const gitHubSource = codebuild.Source.gitHub({
114114
});
115115
```
116116

117+
## BuildSpec
118+
119+
The build spec can be provided from a number of different sources
120+
121+
### File path relative to the root of the source
122+
123+
You can specify a specific filename that exists within the project's source artifact to use as the buildspec.
124+
125+
```ts
126+
const project = new codebuild.Project(this, 'MyProject', {
127+
buildSpec: codebuild.BuildSpec.fromSourceFileName('my-buildspec.yml'),
128+
source: codebuild.Source.gitHub({
129+
owner: 'awslabs',
130+
repo: 'aws-cdk',
131+
})
132+
});
133+
```
134+
135+
This will use `my-buildspec.yml` file within the `awslabs/aws-cdk` repository as the build spec.
136+
137+
### File within the CDK project codebuild
138+
139+
You can also specify a file within your cdk project directory to use as the buildspec.
140+
141+
```ts
142+
const project = new codebuild.Project(this, 'MyProject', {
143+
buildSpec: codebuild.BuildSpec.fromAsset('my-buildspec.yml'),
144+
});
145+
```
146+
147+
This file will be uploaded to S3 and referenced from the codebuild project.
148+
149+
### Inline object
150+
151+
```ts
152+
const project = new codebuild.Project(this, 'MyProject', {
153+
buildSpec: codebuild.BuildSpec.fromObject({
154+
version: '0.2',
155+
}),
156+
});
157+
```
158+
159+
This will result in the buildspec being rendered as JSON within the codebuild project, if you prefer it to be rendered as YAML, use `fromObjectToYaml`.
160+
161+
```ts
162+
const project = new codebuild.Project(this, 'MyProject', {
163+
buildSpec: codebuild.BuildSpec.fromObjectToYaml({
164+
version: '0.2',
165+
}),
166+
});
167+
```
168+
117169
## Artifacts
118170

119171
CodeBuild Projects can produce Artifacts and upload them to S3. For example:
@@ -135,9 +187,6 @@ const project = new codebuild.Project(this, 'MyProject', {
135187
});
136188
```
137189

138-
If you'd prefer your buildspec to be rendered as YAML in the template,
139-
use the `fromObjectToYaml()` method instead of `fromObject()`.
140-
141190
Because we've not set the `name` property, this example will set the
142191
`overrideArtifactName` parameter, and produce an artifact named as defined in
143192
the Buildspec file, uploaded to an S3 bucket (`bucket`). The path will be

packages/@aws-cdk/aws-codebuild/lib/build-spec.ts

+50-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1+
import * as s3_assets from '@aws-cdk/aws-s3-assets';
12
import { IResolveContext, Lazy, Stack } from '@aws-cdk/core';
3+
import { Construct } from 'constructs';
24
import * as yaml_cfn from './private/yaml-cfn';
5+
import { Project } from './project';
36

47
/**
58
* BuildSpec for CodeBuild projects
@@ -27,6 +30,15 @@ export abstract class BuildSpec {
2730
return new FilenameBuildSpec(filename);
2831
}
2932

33+
/**
34+
* Use the contents of a local file as the build spec string
35+
*
36+
* Use this if you have a local .yml or .json file that you want to use as the buildspec
37+
*/
38+
public static fromAsset(path: string): BuildSpec {
39+
return new AssetBuildSpec(path);
40+
}
41+
3042
/**
3143
* Whether the buildspec is directly available or deferred until build-time
3244
*/
@@ -38,7 +50,43 @@ export abstract class BuildSpec {
3850
/**
3951
* Render the represented BuildSpec
4052
*/
41-
public abstract toBuildSpec(): string;
53+
public abstract toBuildSpec(scope?: Construct): string;
54+
}
55+
56+
/**
57+
* BuildSpec that just returns the contents of a local file
58+
*/
59+
class AssetBuildSpec extends BuildSpec {
60+
public readonly isImmediate: boolean = true;
61+
public asset?: s3_assets.Asset;
62+
63+
constructor(public readonly path: string, private readonly options: s3_assets.AssetOptions = { }) {
64+
super();
65+
}
66+
67+
public toBuildSpec(scope?: Project): string {
68+
if (!scope) {
69+
throw new Error('`AssetBuildSpec` requires a `scope` argument');
70+
}
71+
72+
// If the same AssetCode is used multiple times, retain only the first instantiation.
73+
if (!this.asset) {
74+
this.asset = new s3_assets.Asset(scope, 'Code', {
75+
path: this.path,
76+
...this.options,
77+
});
78+
} else if (Stack.of(this.asset) !== Stack.of(scope)) {
79+
throw new Error(`Asset is already associated with another stack '${Stack.of(this.asset).stackName}'. ` +
80+
'Create a new BuildSpec instance for every stack.');
81+
}
82+
83+
this.asset.grantRead(scope);
84+
return this.asset.bucket.arnForObjects(this.asset.s3ObjectKey);
85+
}
86+
87+
public toString() {
88+
return `<buildspec file: ${this.path}>`;
89+
}
4290
}
4391

4492
/**
@@ -208,4 +256,4 @@ function mergeDeep(lhs: any, rhs: any): any {
208256
}
209257

210258
return rhs;
211-
};
259+
};

packages/@aws-cdk/aws-codebuild/lib/project.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1090,7 +1090,7 @@ export class Project extends ProjectBase {
10901090
description: props.description,
10911091
source: {
10921092
...sourceConfig.sourceProperty,
1093-
buildSpec: buildSpec && buildSpec.toBuildSpec(),
1093+
buildSpec: buildSpec && buildSpec.toBuildSpec(this),
10941094
},
10951095
artifacts: artifactsConfig.artifactsProperty,
10961096
serviceRole: this.role.roleArn,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
version: 0.2
2+
3+
phases:
4+
build:
5+
commands:
6+
- echo running stuff
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
{
2+
"version": "30.1.0",
3+
"files": {
4+
"73c20a669c041469f7fc3fc03d574b093b5b97e7c716f76c1e8117e6163e4dc4": {
5+
"source": {
6+
"path": "asset.73c20a669c041469f7fc3fc03d574b093b5b97e7c716f76c1e8117e6163e4dc4.bundle",
7+
"packaging": "zip"
8+
},
9+
"destinations": {
10+
"current_account-current_region": {
11+
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
12+
"objectKey": "73c20a669c041469f7fc3fc03d574b093b5b97e7c716f76c1e8117e6163e4dc4.zip",
13+
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
14+
}
15+
}
16+
},
17+
"c6d793ffaa5add8fe777815df3019dfa5848c214e42229f568e035859171a1b8": {
18+
"source": {
19+
"path": "AssetBuildSpecTestDefaultTestDeployAssertC826AACC.template.json",
20+
"packaging": "file"
21+
},
22+
"destinations": {
23+
"current_account-current_region": {
24+
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
25+
"objectKey": "c6d793ffaa5add8fe777815df3019dfa5848c214e42229f568e035859171a1b8.json",
26+
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
27+
}
28+
}
29+
}
30+
},
31+
"dockerImages": {}
32+
}

0 commit comments

Comments
 (0)