This document describes how to set up a development environment and submit contributions to this project.
- Setup a Development Environment
- Work your magic. Here are some guidelines:
- Every change requires a unit test
- Make sure you update CHANGELOG under “[Unreleased]” if the feature/bug is worthy of a mention
- Make sure to indicate both in the CHANGELOG and in the commit message if the change is BREAKING. A good indication that a change is breaking is if you had to change old tests to “work” after this change.
- Try to maintain a single feature/bugfix per pull request. It's okay to introduce a little bit of housekeeping changes along the way, but try to avoid conflating multiple features. Eventually all these are going to go into a single commit, so you can use that to frame your scope.
- Push to a fork or to a branch (naming convention:
<user>/<feature-bug-name>
) - Submit a Pull Requests on GitHub. When authoring your pull request
description:
- Think about your code reviewers and what information they need in order to have fun with your changes. If it's a big commit (hopefully not), try to provide some good entry points so it will be easier to follow.
- Ideally, associate with an issue (
fixes #<issue>
), which describes more details about motivation and the design process. - Shout out to collaborators.
- If not obvious (i.e. from unit tests), describe how you verified that your change works.
- Assign the PR for a review to the "awslabs/aws-cdk" team.
- Discuss review comments and iterate until you get at least one “Approve”. When iterating, push new commits to the same branch. Usually all these are going to be squashed when you merge to master. The commit messages should be hints for you when you finalize your merge commit message.
- Make sure your PR builds successfully (we have CodeBuild setup to automatically build all PRs)
- Once approved and tested, squash-merge to master via GitHub. This is your opportunity to author a beautiful commit message which describes the motivation and design considerations of your change. Here are some tips from Chris Beams.
This is a monorepo which uses lerna.
The CDK depends on jsii, which is still not
published to npm. Therefore, the jsii tarballs are checked-in to this repository
under ./local-npm
and the install script will install them in the repo-global
node_modules
directory.
Since this repo produces artifacts for multiple programming languages using jsii, it relies on the following toolchains:
When building on CodeBuild, these toolchains are all included in the superchain docker image. This image can also be used locally as follows:
eval $(aws ecr get-login --no-include-email)
IMAGE=260708760616.dkr.ecr.us-east-1.amazonaws.com/superchain:latest
docker pull ${IMAGE}
docker run --net=host -it -v $PWD:$PWD -w $PWD ${IMAGE}
This will get you into an interactive docker shell. You can then run
./install.sh
and ./build.sh
as described below.
Also install the git-secrets tool
and activate it on your working copy of the aws-cdk
repository.
- Clone this repository (or run
git clean -fdx
to clean up all build artifacts). - Run
./install.sh
- this will install all repo-level dependencies, includinglerna
and the unpublished modules from local-npm. - Run
./build.sh
- this will invokelerna bootstrap
andlerna run test
. All external dependencies will be installed and internal deps will be cross-linked.
If you only want to work on a subset of the repo, you can use scripts/buildup
and
scripts/builddown
to build a package and all it's dependencies (up) or
dependents (down).
Make sure to run ./install.sh
from the root to make sure all modules are installed.
It is useful to add the ./scripts
directory to your PATH.
Then, change the working directory to any package in the repo and run:
buildup # will also build all dependencies
Or:
builddown # will also build all consumers
After you've bootstrapped the repo, you would probably want to work on individual packages.
All packages in the repo have a two useful scripts: prepare
and watch
. In order to execute
these scripts, use lerna run --stream --scope <package> <script>
.
The reason you can't use "npm" is because dev tools are installed at the repository level and they are needed in the PATH when executing most of the package scripts.
A useful shell alias would use the directory name as a scope:
# add to your ~/.zshrc or ~/.bashrc
alias lr='lerna run --stream --scope $(basename $PWD)'
# more sugar
alias lw='lr watch &'
alias lp='lr prepare'
Then, you could just go into any of the package directories and use "lr" to run scripts. For example:
cd packages/aws-cdk-s3
lr watch
The script ./link-all.sh
can be used to generate symlinks to all modules in
this repository under some node_module
directory. This can be used to develop
against this repo as a local dependency.
One can use the postinstall
script to symlink this repo:
{
"scripts": {
"postinstall": "../aws-cdk/link-all.sh"
}
}
This assumes this repo is a sibling of the target repo and will install the CDK as a linked dependency during npm install.
The pkglint
tool normalizes all packages in the repo. It verifies package.json
is normalized and adheres to the set of rules. To evaluate (and potentially fix)
all package linting issues in the repo, run the following command from the root
of the repository (after boostrapping):
npm run pkglint
The CDK uses jsii to vend the framework to multiple programming languages. Since jsii is still not published to npm, we consume it as a bundled dependency.
Download an official jsii zip bundle and replace the file under ./vendor
.
Any added dependencies, they will need to be added to the root package.json
.
If you are making changes locally to jsii itself and wish to bind this repository to
a local jsii repository, the best way we currently have is to use npm link
to link
various jsii modules from the other repository into the root of this repository.
For example, if you wish to link against the jsii
module:
- Go to
jsii/packages/jsii
- Run
npm link .
- Go to
aws-cdk/
- Run
npm link jsii
.
The CDK uses jsii to generate language bindings for CDK classes, which proxy interaction to a node.js child process in runtime.
To vend another language for the CDK (given there's jsii support for it):
- Create a directory
packages/aws-cdk-xxx
(where "xxx" is the language). - Look at
aws-cdk-java/package.json
as a reference on how to setup npm build that uses pacmak to generate the code for all CDK modules and then compile and wrap the package up. - Edit bundle-beta.sh and add CDK and jsii artifacts for
your language under
repo/xxx
- Add a cdk init template for your language (see packages/aws-cdk/lib/init-templates).
- Edit getting-started.rst and make there there's a getting started sections and examples for the new language.
The root package.json includes global devDependencies (see lerna docs) on the topic.
- To add a global dependency, run
npm i --save-dev <dep>
at the root. - To add a dependency for a specific module, run
npm i <dep>
inside the module's directory.
Guidelines:
- We cannot accept dependencies that use non-permissive open source licenses (Apache, MIT, etc).
- Make sure dependencies are defined using caret
ranges (e.g.
^1.2.3
). This enables non-breaking updates to automatically be picked up. - Make sure
package-lock.json
files are included in your commit.
You can use find-cycles
to print a list of internal dependency cycles:
$ scripts/find-cycles.sh
Cycle: @aws-cdk/aws-iam => @aws-cdk/assert => aws-cdk => @aws-cdk/aws-s3 => @aws-cdk/aws-kms => @aws-cdk/aws-iam
Cycle: @aws-cdk/assert => aws-cdk => @aws-cdk/aws-s3 => @aws-cdk/aws-kms => @aws-cdk/assert
Cycle: @aws-cdk/aws-iam => @aws-cdk/assert => aws-cdk => @aws-cdk/aws-s3 => @aws-cdk/aws-iam
Cycle: @aws-cdk/assert => aws-cdk => @aws-cdk/aws-s3 => @aws-cdk/assert
Cycle: @aws-cdk/assert => aws-cdk => @aws-cdk/aws-cloudformation => @aws-cdk/assert
Cycle: @aws-cdk/aws-iam => @aws-cdk/assert => aws-cdk => @aws-cdk/util => @aws-cdk/aws-iam
Cycle: @aws-cdk/aws-sns => @aws-cdk/aws-lambda => @aws-cdk/aws-codecommit => @aws-cdk/aws-sns
Cycle: @aws-cdk/aws-sns => @aws-cdk/aws-lambda => @aws-cdk/aws-codecommit => @aws-cdk/aws-codepipeline => @aws-cdk/aws-sns
We use npm update
to
- Obtain a fresh clone from “master”
- Run
./install.sh
and./build.sh
to make sure the current HEAD is not broken (should never be...). - Once build succeeded, run:
$ npm update # to update the root deps $ lerna exec npm update # to update deps in all modules
- This will probably install some new versions and update
package.json
andpackage-lock.json
files. - Now, run
./build.sh
again to verify all tests pass. - Submit a Pull Request.