The following describes the steps involved to initialize a CDF development environment from scratch, to build, run and test a project, then finally on how to commit modifications to the source code.
Due to the scripts used as part of both the build and deployment steps, only linux type environments (including macOS) are officially supported.
The following is a one-time setup to configure the CDF development environment.
-
Ensure that you have all development prerequisites installed.
-
Clone the project:
> git clone https://github.com/aws/aws-connected-device-framework.git
> cd aws-connected-device-framework/source
- Optionally switch to a specific release tag:
aws-connected-device-framework/source> git switch -c tags/<release>
The CDF monorepo is managed by rush which under the covers is configured to use pnpm as its package manager. The following is a brief introduction of how to use rush:
# If this is your first time at using Rush for this project, remove any node_modules
# that may have been installed as part of a non-Rush (npm/pnpm) release:
aws-connected-device-framework/source> rm -rf node_modules
# One time setup only, install pinned dependencies based on shrinkwrapped
aws-connected-device-framework/source> rush install
# When running the `clean`, `build`, `lint` or `test` commands you have the option to
# run globally (for all packages), or for a specific package. To run for all packages
# run as follows:
#
# rush <command>
#
# To run for a specific package you can either provide a target filter as follows:
#
# rush <command> -t <package_name>
#
# or alternatively run the following within the package's directory (which is a shortcut
# for `rush <command> -t .`):
#
# rushx <command>
#
# Taking the above comments into consideration, to build run the following. Note that the first build
# may take time, but subsequent builds will be quicker delta builds:
aws-connected-device-framework/source> rush build
# To lint:
aws-connected-device-framework/source> rush lint
# And to run unit tests:
aws-connected-device-framework/source> rush test
# If you experience issues and need to reset everything you have the following 2 commands available:
# To remove all build artifacts:
aws-connected-device-framework/source> rush purge # to purge all node_modules:
aws-connected-device-framework/source> rush clean # perform a deep clean
aws-connected-device-framework/source> rush install # refresh dependencies again
Each module uses dotenv-flow to manage its application configuration. When a module is deployed, the installer module takes care of injecting the configuration into the environment. But when running locally, this configration needs to be provided.
The easiest way to generate this configuration is to use the config-to-env
command of the installer module, If you need to manually generate the configuration file, or understand the available configuration, refer to the modules own docs/configuration.md
help file.
Once you have the configuration file, you can start a module as follows:
aws-connected-device-framework> cd source/packages/services/<module_name>
aws-connected-device-framework/source/packages/services/<module_name>> export CONFIG_LOCATION=<path-to-env-file>; npm run start
We adhere to what is known as a GitHub flow as far as our approach to branching is concerned. Basically this boils down to:
- The
main
branch always represents a working version of the code, including latest (maybe unofficially released) updates, that may be deployed to a production environment - Under no circumstances ever commit directly to
main
! - When starting a new feature or fixing a bug, create a new branch from
main
. Name the branchfeat_***
for new features orfix_***
for hotfixes:
aws-connected-device-framework> git switch -c <new_branch_name>
Switched to a new branch '<new_branch_name>'
- At suitable points, commit your work by running the following, and following the prompts to describe your commit. Note that you must run
rush commit
inside thesource/
directory whereas you can run thegit
commands anywhere within the repo.
aws-connected-device-framework> git add -A
aws-connected-device-framework> cd source
aws-connected-device-framework/source> rush commit
-
When you have finished with your implementation, and ensured that all existing unit tests pass as well as creating any new tests, the following steps are required:
- Merge changes with the
main
branch:
- Merge changes with the
# pull in main into your branch
aws-connected-device-framework> git merge origin/main
# once any conflicts have been resolved, test
aws-connected-device-framework> cd source
aws-connected-device-framework/source> rush test
# commit changes
aws-connected-device-framework/source> git add -A
aws-connected-device-framework/source> rush commit
-
- Generate release notes. the
rush change
command will analyze all commits on the branch, filter out the projects that changed, then prompt you to enter release notes for the updated project:
- Generate release notes. the
# generate release notes
aws-connected-device-framework/source> rush change
# commit release notes
aws-connected-device-framework/source> git add -A
aws-connected-device-framework/source> rush commit
-
- Push the branch to the git repo
aws-connected-device-framework> git push
-
- Create a pull request
-
Once your pull request has been reviewed, and any issues addressed, merge your implementation back into the main code branch.
If your code changes include changes to the dependencies listed in a package.json
file. you need to update the repo-wide "shrinkwrap" file. This file contains the resolved and pinned dependencies for all CDF packages:
rush update
git add source/common/config/rush/pnpm-lock.yaml
git add source/common/config/rush/repo-state.json
Note that these two files cannot be merged. If your branch feat_branch
has a merge conflict with main
, the steps to resolve are:
- Merge
main
intofeat_branch
. - Resolve all other merge conflicts, discard all changes in
pnpm-lock.yaml
andrepo-state.json
. - Run
rush update
again. - Commit the resulting
pnpm-lock.yaml
andrepo-state.json
to your branch.
Directory | Description |
---|---|
source/cicd/ | The CloudFormation template to deploy the cicd pipeline, along with the related CodeBuild scripts |
source/common/ | All build and package manager related files |
source/docs/ | CDF core related documentation |
source/infrastructure/ | The main deployment script for deploying the CDF core modules, along with CloudFormation templates that are not specific to any module |
source/packages/integration-tests/ | BDD related automated integration tests |
source/packages/libraries/ | All internal libraries, as well as CDF client libraries |
source/packages/services/ | Deployable modules, such as the Asset Library |
-
"Why do I have to use
rush commit
to commit my work instead of the usualgit commit
?"rush commit
is configured to run the commitizen command line utility which forces you to describe commits using a specific format. This is vitally important, as there are steps in our CI/CD pipeline that analyze all git commits since the last release, use these specially formatted messages to intelligently increment the version numbers (e.g. understand if there's a breaking change), and finally auto generates a change log for the release. -
"What is the need for using (
rush
) and (pnpm
package manager)? What's wrong with justnpm
?" Theaws-connected-device-framework
git repo is what is known as a monorepo, a large single repository that contains many different projects.The decision to migrate CDF to a monorepo was made to:
- simplify the development environment by removing the need for an npm private repo (e.g. verdaccio)
- simplify the dependency management across projects (reduced the development environment footprint from >6GB to 300MB)
- allow for atomic commits spanning multiple projects, simplifying branching, merging and code reviews
pnmp
in conjunction withrush
have features that allow us to efficiently work with monorepos, while still being able to bundle individual modules in the way required by AWS Lambda.