UNPKG

23.7 kBMarkdownView Raw
1# AWS CodeBuild Construct Library
2<!--BEGIN STABILITY BANNER-->
3
4---
5
6![cfn-resources: Stable](https://img.shields.io/badge/cfn--resources-stable-success.svg?style=for-the-badge)
7
8![cdk-constructs: Stable](https://img.shields.io/badge/cdk--constructs-stable-success.svg?style=for-the-badge)
9
10---
11
12<!--END STABILITY BANNER-->
13
14AWS CodeBuild is a fully managed continuous integration service that compiles
15source code, runs tests, and produces software packages that are ready to
16deploy. With CodeBuild, you don’t need to provision, manage, and scale your own
17build servers. CodeBuild scales continuously and processes multiple builds
18concurrently, so your builds are not left waiting in a queue. You can get
19started quickly by using prepackaged build environments, or you can create
20custom build environments that use your own build tools. With CodeBuild, you are
21charged by the minute for the compute resources you use.
22
23## Installation
24
25Install the module:
26
27```console
28$ npm i @aws-cdk/aws-codebuild
29```
30
31Import it into your code:
32
33```ts nofixture
34import * as codebuild from '@aws-cdk/aws-codebuild';
35```
36
37The `codebuild.Project` construct represents a build project resource. See the
38reference documentation for a comprehensive list of initialization properties,
39methods and attributes.
40
41## Source
42
43Build projects are usually associated with a _source_, which is specified via
44the `source` property which accepts a class that extends the `Source`
45abstract base class.
46The default is to have no source associated with the build project;
47the `buildSpec` option is required in that case.
48
49Here's a CodeBuild project with no source which simply prints `Hello,
50CodeBuild!`:
51
52[Minimal Example](./test/integ.defaults.lit.ts)
53
54### `CodeCommitSource`
55
56Use an AWS CodeCommit repository as the source of this build:
57
58```ts
59import * as codecommit from '@aws-cdk/aws-codecommit';
60
61const repository = new codecommit.Repository(this, 'MyRepo', { repositoryName: 'foo' });
62new codebuild.Project(this, 'MyFirstCodeCommitProject', {
63 source: codebuild.Source.codeCommit({ repository }),
64});
65```
66
67### `S3Source`
68
69Create a CodeBuild project with an S3 bucket as the source:
70
71```ts
72const bucket = new s3.Bucket(this, 'MyBucket');
73
74new codebuild.Project(this, 'MyProject', {
75 source: codebuild.Source.s3({
76 bucket: bucket,
77 path: 'path/to/file.zip',
78 }),
79});
80```
81
82The CodeBuild role will be granted to read just the given path from the given `bucket`.
83
84### `GitHubSource` and `GitHubEnterpriseSource`
85
86These source types can be used to build code from a GitHub repository.
87Example:
88
89```ts
90const gitHubSource = codebuild.Source.gitHub({
91 owner: 'awslabs',
92 repo: 'aws-cdk',
93 webhook: true, // optional, default: true if `webhookFilters` were provided, false otherwise
94 webhookTriggersBatchBuild: true, // optional, default is false
95 webhookFilters: [
96 codebuild.FilterGroup
97 .inEventOf(codebuild.EventAction.PUSH)
98 .andBranchIs('master')
99 .andCommitMessageIs('the commit message'),
100 ], // optional, by default all pushes and Pull Requests will trigger a build
101});
102```
103
104To provide GitHub credentials, please either go to AWS CodeBuild Console to connect
105or call `ImportSourceCredentials` to persist your personal access token.
106Example:
107
108```console
109aws codebuild import-source-credentials --server-type GITHUB --auth-type PERSONAL_ACCESS_TOKEN --token <token_value>
110```
111
112### `BitBucketSource`
113
114This source type can be used to build code from a BitBucket repository.
115
116```ts
117const bbSource = codebuild.Source.bitBucket({
118 owner: 'owner',
119 repo: 'repo',
120});
121```
122
123### For all Git sources
124
125For all Git sources, you can fetch submodules while cloing git repo.
126
127```ts
128const gitHubSource = codebuild.Source.gitHub({
129 owner: 'awslabs',
130 repo: 'aws-cdk',
131 fetchSubmodules: true,
132});
133```
134
135## Artifacts
136
137CodeBuild Projects can produce Artifacts and upload them to S3. For example:
138
139```ts
140declare const bucket: s3.Bucket;
141
142const project = new codebuild.Project(this, 'MyProject', {
143 buildSpec: codebuild.BuildSpec.fromObject({
144 version: '0.2',
145 }),
146 artifacts: codebuild.Artifacts.s3({
147 bucket,
148 includeBuildId: false,
149 packageZip: true,
150 path: 'another/path',
151 identifier: 'AddArtifact1',
152 }),
153});
154```
155
156If you'd prefer your buildspec to be rendered as YAML in the template,
157use the `fromObjectToYaml()` method instead of `fromObject()`.
158
159Because we've not set the `name` property, this example will set the
160`overrideArtifactName` parameter, and produce an artifact named as defined in
161the Buildspec file, uploaded to an S3 bucket (`bucket`). The path will be
162`another/path` and the artifact will be a zipfile.
163
164## CodePipeline
165
166To add a CodeBuild Project as an Action to CodePipeline,
167use the `PipelineProject` class instead of `Project`.
168It's a simple class that doesn't allow you to specify `sources`,
169`secondarySources`, `artifacts` or `secondaryArtifacts`,
170as these are handled by setting input and output CodePipeline `Artifact` instances on the Action,
171instead of setting them on the Project.
172
173```ts
174const project = new codebuild.PipelineProject(this, 'Project', {
175 // properties as above...
176})
177```
178
179For more details, see the readme of the `@aws-cdk/@aws-codepipeline-actions` package.
180
181## Caching
182
183You can save time when your project builds by using a cache. A cache can store reusable pieces of your build environment and use them across multiple builds. Your build project can use one of two types of caching: Amazon S3 or local. In general, S3 caching is a good option for small and intermediate build artifacts that are more expensive to build than to download. Local caching is a good option for large intermediate build artifacts because the cache is immediately available on the build host.
184
185### S3 Caching
186
187With S3 caching, the cache is stored in an S3 bucket which is available
188regardless from what CodeBuild instance gets selected to run your CodeBuild job
189on. When using S3 caching, you must also add in a `cache` section to your
190buildspec which indicates the files to be cached:
191
192```ts
193declare const myCachingBucket: s3.Bucket;
194
195new codebuild.Project(this, 'Project', {
196 source: codebuild.Source.bitBucket({
197 owner: 'awslabs',
198 repo: 'aws-cdk',
199 }),
200
201 cache: codebuild.Cache.bucket(myCachingBucket),
202
203 // BuildSpec with a 'cache' section necessary for S3 caching. This can
204 // also come from 'buildspec.yml' in your source.
205 buildSpec: codebuild.BuildSpec.fromObject({
206 version: '0.2',
207 phases: {
208 build: {
209 commands: ['...'],
210 },
211 },
212 cache: {
213 paths: [
214 // The '**/*' is required to indicate all files in this directory
215 '/root/cachedir/**/*',
216 ],
217 },
218 }),
219});
220```
221
222Note that two different CodeBuild Projects using the same S3 bucket will *not*
223share their cache: each Project will get a unique file in the S3 bucket to store
224the cache in.
225
226### Local Caching
227
228With local caching, the cache is stored on the codebuild instance itself. This
229is simple, cheap and fast, but CodeBuild cannot guarantee a reuse of instance
230and hence cannot guarantee cache hits. For example, when a build starts and
231caches files locally, if two subsequent builds start at the same time afterwards
232only one of those builds would get the cache. Three different cache modes are
233supported, which can be turned on individually.
234
235* `LocalCacheMode.SOURCE` caches Git metadata for primary and secondary sources.
236* `LocalCacheMode.DOCKER_LAYER` caches existing Docker layers.
237* `LocalCacheMode.CUSTOM` caches directories you specify in the buildspec file.
238
239```ts
240new codebuild.Project(this, 'Project', {
241 source: codebuild.Source.gitHubEnterprise({
242 httpsCloneUrl: 'https://my-github-enterprise.com/owner/repo',
243 }),
244
245 // Enable Docker AND custom caching
246 cache: codebuild.Cache.local(codebuild.LocalCacheMode.DOCKER_LAYER, codebuild.LocalCacheMode.CUSTOM),
247
248 // BuildSpec with a 'cache' section necessary for 'CUSTOM' caching. This can
249 // also come from 'buildspec.yml' in your source.
250 buildSpec: codebuild.BuildSpec.fromObject({
251 version: '0.2',
252 phases: {
253 build: {
254 commands: ['...'],
255 },
256 },
257 cache: {
258 paths: [
259 // The '**/*' is required to indicate all files in this directory
260 '/root/cachedir/**/*',
261 ],
262 },
263 }),
264});
265```
266
267## Environment
268
269By default, projects use a small instance with an Ubuntu 18.04 image. You
270can use the `environment` property to customize the build environment:
271
272* `buildImage` defines the Docker image used. See [Images](#images) below for
273 details on how to define build images.
274* `certificate` defines the location of a PEM encoded certificate to import.
275* `computeType` defines the instance type used for the build.
276* `privileged` can be set to `true` to allow privileged access.
277* `environmentVariables` can be set at this level (and also at the project
278 level).
279
280## Images
281
282The CodeBuild library supports both Linux and Windows images via the
283`LinuxBuildImage` (or `LinuxArmBuildImage`), and `WindowsBuildImage` classes, respectively.
284
285You can specify one of the predefined Windows/Linux images by using one
286of the constants such as `WindowsBuildImage.WIN_SERVER_CORE_2019_BASE`,
287`WindowsBuildImage.WINDOWS_BASE_2_0`, `LinuxBuildImage.STANDARD_2_0`, or
288`LinuxArmBuildImage.AMAZON_LINUX_2_ARM`.
289
290Alternatively, you can specify a custom image using one of the static methods on
291`LinuxBuildImage`:
292
293* `LinuxBuildImage.fromDockerRegistry(image[, { secretsManagerCredentials }])` to reference an image in any public or private Docker registry.
294* `LinuxBuildImage.fromEcrRepository(repo[, tag])` to reference an image available in an
295 ECR repository.
296* `LinuxBuildImage.fromAsset(parent, id, props)` to use an image created from a
297 local asset.
298* `LinuxBuildImage.fromCodeBuildImageId(id)` to reference a pre-defined, CodeBuild-provided Docker image.
299
300or one of the corresponding methods on `WindowsBuildImage`:
301
302* `WindowsBuildImage.fromDockerRegistry(image[, { secretsManagerCredentials }, imageType])`
303* `WindowsBuildImage.fromEcrRepository(repo[, tag, imageType])`
304* `WindowsBuildImage.fromAsset(parent, id, props, [, imageType])`
305
306or one of the corresponding methods on `LinuxArmBuildImage`:
307
308* `LinuxArmBuildImage.fromEcrRepository(repo[, tag])`
309
310Note that the `WindowsBuildImage` version of the static methods accepts an optional parameter of type `WindowsImageType`,
311which can be either `WindowsImageType.STANDARD`, the default, or `WindowsImageType.SERVER_2019`:
312
313```ts
314declare const ecrRepository: ecr.Repository;
315
316new codebuild.Project(this, 'Project', {
317 environment: {
318 buildImage: codebuild.WindowsBuildImage.fromEcrRepository(ecrRepository, 'v1.0', codebuild.WindowsImageType.SERVER_2019),
319 // optional certificate to include in the build image
320 certificate: {
321 bucket: s3.Bucket.fromBucketName(this, 'Bucket', 'my-bucket'),
322 objectKey: 'path/to/cert.pem',
323 },
324 },
325 // ...
326})
327```
328
329The following example shows how to define an image from a Docker asset:
330
331[Docker asset example](./test/integ.docker-asset.lit.ts)
332
333The following example shows how to define an image from an ECR repository:
334
335[ECR example](./test/integ.ecr.lit.ts)
336
337The following example shows how to define an image from a private docker registry:
338
339[Docker Registry example](./test/integ.docker-registry.lit.ts)
340
341### GPU images
342
343The class `LinuxGpuBuildImage` contains constants for working with
344[AWS Deep Learning Container images](https://aws.amazon.com/releasenotes/available-deep-learning-containers-images):
345
346
347```ts
348new codebuild.Project(this, 'Project', {
349 environment: {
350 buildImage: codebuild.LinuxGpuBuildImage.DLC_TENSORFLOW_2_1_0_INFERENCE,
351 },
352 // ...
353})
354```
355
356One complication is that the repositories for the DLC images are in
357different accounts in different AWS regions.
358In most cases, the CDK will handle providing the correct account for you;
359in rare cases (for example, deploying to new regions)
360where our information might be out of date,
361you can always specify the account
362(along with the repository name and tag)
363explicitly using the `awsDeepLearningContainersImage` method:
364
365```ts
366new codebuild.Project(this, 'Project', {
367 environment: {
368 buildImage: codebuild.LinuxGpuBuildImage.awsDeepLearningContainersImage(
369 'tensorflow-inference', '2.1.0-gpu-py36-cu101-ubuntu18.04', '123456789012'),
370 },
371 // ...
372})
373```
374
375Alternatively, you can reference an image available in an ECR repository using the `LinuxGpuBuildImage.fromEcrRepository(repo[, tag])` method.
376
377## Logs
378
379CodeBuild lets you specify an S3 Bucket, CloudWatch Log Group or both to receive logs from your projects.
380
381By default, logs will go to cloudwatch.
382
383### CloudWatch Logs Example
384
385```ts
386new codebuild.Project(this, 'Project', {
387 logging: {
388 cloudWatch: {
389 logGroup: new logs.LogGroup(this, `MyLogGroup`),
390 }
391 },
392})
393```
394
395### S3 Logs Example
396
397```ts
398new codebuild.Project(this, 'Project', {
399 logging: {
400 s3: {
401 bucket: new s3.Bucket(this, `LogBucket`)
402 }
403 },
404})
405```
406
407## Credentials
408
409CodeBuild allows you to store credentials used when communicating with various sources,
410like GitHub:
411
412```ts
413new codebuild.GitHubSourceCredentials(this, 'CodeBuildGitHubCreds', {
414 accessToken: SecretValue.secretsManager('my-token'),
415});
416// GitHub Enterprise is almost the same,
417// except the class is called GitHubEnterpriseSourceCredentials
418```
419
420and BitBucket:
421
422```ts
423new codebuild.BitBucketSourceCredentials(this, 'CodeBuildBitBucketCreds', {
424 username: SecretValue.secretsManager('my-bitbucket-creds', { jsonField: 'username' }),
425 password: SecretValue.secretsManager('my-bitbucket-creds', { jsonField: 'password' }),
426});
427```
428
429**Note**: the credentials are global to a given account in a given region -
430they are not defined per CodeBuild project.
431CodeBuild only allows storing a single credential of a given type
432(GitHub, GitHub Enterprise or BitBucket)
433in a given account in a given region -
434any attempt to save more than one will result in an error.
435You can use the [`list-source-credentials` AWS CLI operation](https://docs.aws.amazon.com/cli/latest/reference/codebuild/list-source-credentials.html)
436to inspect what credentials are stored in your account.
437
438## Test reports
439
440You can specify a test report in your buildspec:
441
442```ts
443const project = new codebuild.Project(this, 'Project', {
444 buildSpec: codebuild.BuildSpec.fromObject({
445 // ...
446 reports: {
447 myReport: {
448 files: '**/*',
449 'base-directory': 'build/test-results',
450 },
451 },
452 }),
453});
454```
455
456This will create a new test report group,
457with the name `<ProjectName>-myReport`.
458
459The project's role in the CDK will always be granted permissions to create and use report groups
460with names starting with the project's name;
461if you'd rather not have those permissions added,
462you can opt out of it when creating the project:
463
464```ts
465declare const source: codebuild.Source;
466
467const project = new codebuild.Project(this, 'Project', {
468 source,
469 grantReportGroupPermissions: false,
470});
471```
472
473Alternatively, you can specify an ARN of an existing resource group,
474instead of a simple name, in your buildspec:
475
476```ts
477declare const source: codebuild.Source;
478
479// create a new ReportGroup
480const reportGroup = new codebuild.ReportGroup(this, 'ReportGroup');
481
482const project = new codebuild.Project(this, 'Project', {
483 source,
484 buildSpec: codebuild.BuildSpec.fromObject({
485 // ...
486 reports: {
487 [reportGroup.reportGroupArn]: {
488 files: '**/*',
489 'base-directory': 'build/test-results',
490 },
491 },
492 }),
493});
494```
495
496If you do that, you need to grant the project's role permissions to write reports to that report group:
497
498```ts
499declare const project: codebuild.Project;
500declare const reportGroup: codebuild.ReportGroup;
501
502reportGroup.grantWrite(project);
503```
504
505For more information on the test reports feature,
506see the [AWS CodeBuild documentation](https://docs.aws.amazon.com/codebuild/latest/userguide/test-reporting.html).
507
508## Events
509
510CodeBuild projects can be used either as a source for events or be triggered
511by events via an event rule.
512
513### Using Project as an event target
514
515The `@aws-cdk/aws-events-targets.CodeBuildProject` allows using an AWS CodeBuild
516project as a AWS CloudWatch event rule target:
517
518```ts
519// start build when a commit is pushed
520import * as codecommit from '@aws-cdk/aws-codecommit';
521import * as targets from '@aws-cdk/aws-events-targets';
522
523declare const codeCommitRepository: codecommit.Repository;
524declare const project: codebuild.Project;
525
526codeCommitRepository.onCommit('OnCommit', {
527 target: new targets.CodeBuildProject(project),
528});
529```
530
531### Using Project as an event source
532
533To define Amazon CloudWatch event rules for build projects, use one of the `onXxx`
534methods:
535
536```ts
537import * as targets from '@aws-cdk/aws-events-targets';
538declare const fn: lambda.Function;
539declare const project: codebuild.Project;
540
541const rule = project.onStateChange('BuildStateChange', {
542 target: new targets.LambdaFunction(fn)
543});
544```
545
546## CodeStar Notifications
547
548To define CodeStar Notification rules for Projects, use one of the `notifyOnXxx()` methods.
549They are very similar to `onXxx()` methods for CloudWatch events:
550
551```ts
552import * as chatbot from '@aws-cdk/aws-chatbot';
553
554declare const project: codebuild.Project;
555
556const target = new chatbot.SlackChannelConfiguration(this, 'MySlackChannel', {
557 slackChannelConfigurationName: 'YOUR_CHANNEL_NAME',
558 slackWorkspaceId: 'YOUR_SLACK_WORKSPACE_ID',
559 slackChannelId: 'YOUR_SLACK_CHANNEL_ID',
560});
561
562const rule = project.notifyOnBuildSucceeded('NotifyOnBuildSucceeded', target);
563```
564
565## Secondary sources and artifacts
566
567CodeBuild Projects can get their sources from multiple places, and produce
568multiple outputs. For example:
569
570```ts
571import * as codecommit from '@aws-cdk/aws-codecommit';
572declare const repo: codecommit.Repository;
573declare const bucket: s3.Bucket;
574
575const project = new codebuild.Project(this, 'MyProject', {
576 secondarySources: [
577 codebuild.Source.codeCommit({
578 identifier: 'source2',
579 repository: repo,
580 }),
581 ],
582 secondaryArtifacts: [
583 codebuild.Artifacts.s3({
584 identifier: 'artifact2',
585 bucket: bucket,
586 path: 'some/path',
587 name: 'file.zip',
588 }),
589 ],
590 // ...
591});
592```
593
594Note that the `identifier` property is required for both secondary sources and
595artifacts.
596
597The contents of the secondary source is available to the build under the
598directory specified by the `CODEBUILD_SRC_DIR_<identifier>` environment variable
599(so, `CODEBUILD_SRC_DIR_source2` in the above case).
600
601The secondary artifacts have their own section in the buildspec, under the
602regular `artifacts` one. Each secondary artifact has its own section, beginning
603with their identifier.
604
605So, a buildspec for the above Project could look something like this:
606
607```ts
608const project = new codebuild.Project(this, 'MyProject', {
609 // secondary sources and artifacts as above...
610 buildSpec: codebuild.BuildSpec.fromObject({
611 version: '0.2',
612 phases: {
613 build: {
614 commands: [
615 'cd $CODEBUILD_SRC_DIR_source2',
616 'touch output2.txt',
617 ],
618 },
619 },
620 artifacts: {
621 'secondary-artifacts': {
622 'artifact2': {
623 'base-directory': '$CODEBUILD_SRC_DIR_source2',
624 'files': [
625 'output2.txt',
626 ],
627 },
628 },
629 },
630 }),
631});
632```
633
634### Definition of VPC configuration in CodeBuild Project
635
636Typically, resources in an VPC are not accessible by AWS CodeBuild. To enable
637access, you must provide additional VPC-specific configuration information as
638part of your CodeBuild project configuration. This includes the VPC ID, the
639VPC subnet IDs, and the VPC security group IDs. VPC-enabled builds are then
640able to access resources inside your VPC.
641
642For further Information see https://docs.aws.amazon.com/codebuild/latest/userguide/vpc-support.html
643
644**Use Cases**
645VPC connectivity from AWS CodeBuild builds makes it possible to:
646
647* Run integration tests from your build against data in an Amazon RDS database that's isolated on a private subnet.
648* Query data in an Amazon ElastiCache cluster directly from tests.
649* Interact with internal web services hosted on Amazon EC2, Amazon ECS, or services that use internal Elastic Load Balancing.
650* Retrieve dependencies from self-hosted, internal artifact repositories, such as PyPI for Python, Maven for Java, and npm for Node.js.
651* Access objects in an Amazon S3 bucket configured to allow access through an Amazon VPC endpoint only.
652* Query external web services that require fixed IP addresses through the Elastic IP address of the NAT gateway or NAT instance associated with your subnet(s).
653
654Your builds can access any resource that's hosted in your VPC.
655
656**Enable Amazon VPC Access in your CodeBuild Projects**
657
658Pass the VPC when defining your Project, then make sure to
659give the CodeBuild's security group the right permissions
660to access the resources that it needs by using the
661`connections` object.
662
663For example:
664
665```ts
666declare const loadBalancer: elbv2.ApplicationLoadBalancer;
667
668const vpc = new ec2.Vpc(this, 'MyVPC');
669const project = new codebuild.Project(this, 'MyProject', {
670 vpc: vpc,
671 buildSpec: codebuild.BuildSpec.fromObject({
672 // ...
673 }),
674});
675
676project.connections.allowTo(loadBalancer, ec2.Port.tcp(443));
677```
678
679## Project File System Location EFS
680
681Add support for CodeBuild to build on AWS EFS file system mounts using
682the new ProjectFileSystemLocation.
683The `fileSystemLocations` property which accepts a list `ProjectFileSystemLocation`
684as represented by the interface `IFileSystemLocations`.
685The only supported file system type is `EFS`.
686
687For example:
688
689```ts
690new codebuild.Project(this, 'MyProject', {
691 buildSpec: codebuild.BuildSpec.fromObject({
692 version: '0.2',
693 }),
694 fileSystemLocations: [
695 codebuild.FileSystemLocation.efs({
696 identifier: "myidentifier2",
697 location: "myclodation.mydnsroot.com:/loc",
698 mountPoint: "/media",
699 mountOptions: "opts"
700 })
701 ]
702});
703```
704
705Here's a CodeBuild project with a simple example that creates a project mounted on AWS EFS:
706
707[Minimal Example](./test/integ.project-file-system-location.ts)
708
709## Batch builds
710
711To enable batch builds you should call `enableBatchBuilds()` on the project instance.
712
713It returns an object containing the batch service role that was created,
714or `undefined` if batch builds could not be enabled, for example if the project was imported.
715
716```ts
717declare const source: codebuild.Source;
718
719const project = new codebuild.Project(this, 'MyProject', { source, });
720
721if (project.enableBatchBuilds()) {
722 console.log('Batch builds were enabled');
723}
724```
725
726## Timeouts
727
728There are two types of timeouts that can be set when creating your Project.
729The `timeout` property can be used to set an upper limit on how long your Project is able to run without being marked as completed.
730The default is 60 minutes.
731An example of overriding the default follows.
732
733```ts
734new codebuild.Project(this, 'MyProject', {
735 timeout: Duration.minutes(90)
736});
737```
738
739The `queuedTimeout` property can be used to set an upper limit on how your Project remains queued to run.
740There is no default value for this property.
741As an example, to allow your Project to queue for up to thirty (30) minutes before the build fails,
742use the following code.
743
744```ts
745new codebuild.Project(this, 'MyProject', {
746 queuedTimeout: Duration.minutes(30)
747});
748```
749
750## Limiting concurrency
751
752By default if a new build is triggered it will be run even if there is a previous build already in progress.
753It is possible to limit the maximum concurrent builds to value between 1 and the account specific maximum limit.
754By default there is no explicit limit.
755
756```ts
757new codebuild.Project(this, 'MyProject', {
758 concurrentBuildLimit: 1
759});
760```