id | title | hide_title |
---|---|---|
contributing |
Contributing |
true |
Thanks for your interest in contributing to faast.js! The information on this page explains how to contribute, and provides setup instructions for a development environment to hack on faast.js.
Sign up for our Slack channel. If you're already signed up, log in.
Also check out the faast.js
tag on StackOverflow.
There are a many ways to contribute to faast.js:
-
File an issue on GitHub for an issue you're having using faast.js. Please check for duplicates when filing.
-
Fix an open issue.
-
Contribute a pull request with new functionality. Before doing this, please open a new issue to discuss the feature so we can align on what / when / how before you put in a ton of work.
Prerequisites:
- Node version 8+. Versions of node from OS package managers are often out of date; it is preferable to install directly from nodejs.org or use a node version manager. Consider n, which can be easily installed with n-install.
Included in package.json
:
-
AVA - test runner.
-
Docusaurus - documentation and website.
-
API-extractor - API documentation generator and more.
-
semantic-release - automatic changelog and release generation.
-
commitizen - commit message formatting
External tools that may be useful:
To install node, see tooling.
$ node -v
Ensure you're using Node version 8+.
Then build:
$ npm install
$ npm run build
The output is placed in dist/
.
Running in watch mode can be useful for compiling on the fly as changes are made:
$ npm run watch
The full testsuite requires both AWS and Google Cloud accounts to be set up. See instructions to setup accounts on AWS and Google Cloud.
$ npm run test
npm run test-aws
npm run test-google
$ npm run test-local
There are two documentation sources: the markdown files in docs/*.md
and generated API documentation from the source code. The generated API documentation is output to docs/api/*
and is checked into the repository.
API documentation generation uses API-extractor and API-documenter.
To perform a clean build that includes building API documentation:
$ npm run build
This takes a little time, and unfortunately the documentation generator lacks a watch mode, so is not automatically updated when using npm run watch
. To occassionally update the documentation without running a full build:
$ npm run doc
This will execute the documentation builder script doc.ts.
Every exported symbol is in index.ts
in the root of the repository. Each of these symbols needs to have a @public
annotation and some documentation. Review the documentation tags specified by API-extractor.
Faast.js also uses an API review file generated by API-extractor in etc/faastjs.api.md
. This file contains a summary of the public exported API for faast.js. It is generated automatically when you run npm run doc
or npm run build
. When this file changes, it means the public API has changed, and this warrants careful review.
When reviewing the API review file, all undefined types should be part of declarations marked as @internal (except for those referencing AWS, Google, or WebPack dependency types used for special case options). Any changes to the public API should be inspected for possible semantic version changes. All public apis should be documented (i.e. ensure there are no "undocumented" comments on APIs in the API review file).
Faast.js follows semantic versioning. We use the semantic-release tool to automatically generate releases from the master branch on github. Semantic-release automatically increments version numbers, generates changelogs, and performs npm publish
based on commit messages.
When creating pull requests, you can format your messages with the following command:
$ npm run commit
This will run commitizen, prompting you to answer some questions about your changes. Don't worry, we will fix your commit messages (if needed) before accepting your pull request.
Faast.js uses docusaurus to generate a static website that includes the generated documentation as an API in docs/api/*.md
, along with the manual you are currently reading in docs/*.md
.
Docusaurus has a built-in server:
$ cd website
$ npm install
$ npm start
This should open your browser allowing you to see a live preview. Note that you'll need to npm run doc
to get updated API docs.
AVA is designed to run all tests within a file concurrently. This is a different architecture than most other JavaScript test frameworks, and it is especially suited to faast.js. The faast.js testsuite needs to create many lambda functions and other infrastructure in the cloud. Performing these operations can take some time, but can be done in parallel easily. Google Cloud Functions takes an especially long time (sometimes > 1min) for common operations like function creation.
In addition, faast.js has to execute the same tests across a test matrix of cloud providers and configurations:
{CloudProviders} x {Configurations} x {Tests}
The most natural way to write these tests is as follows:
for (const provider of providers) {
for (const config of configs) {
test(...);
}
}
With Jest and most other JavaScript test frameworks, this style of writing tests will result in serialization of each test. Splitting the elements of the test matrix into different files causes the test structure to become more complex than it needs to be because the common test code needs to be factored out, and separate test files need to be created for each cloud provider and possible each configuration in order to achieve sufficient test concurrency.
Faast.js focuses mostly on integration tests, not unit tests. Faast.js tests on live cloud services in addition to locally. We've found that this test philosophy maximizes ROI on test effort.
Tests are located in test/\*.test.ts
.
You can run AVA directly to use more advanced filtering, etc:
$ npx ava
For example, to run only AWS tests that test garbage collection:
$ npx ava -m='*aws*garbage*'
The benefit of AVA is that you have more control over test concurrency. The drawback is that tests need to be written so they don't interfere with each other. This takes some effort and diligence, but basically it boils down to the following:
-
Most tests should be written as macros. See basic.test.ts for an example.
-
Each test should create its own faast instance and properly clean it up in a
finally
clause. -
Don't share resources between tests. This includes global or shared variables, objects, files, etc.
-
Each test should have a unique test title that is descriptive enough to make filtering easy.
-
Don't ignore intermittent test failures. They may indicate a race condition.
Test titles are important. Please following the following rules to ensure the CI tests continue to work as expected:
-
Test titles that require network access should begin with
`remote ${provider}`
-
Use the
title()
utility function to help ensure you have the right prefix for test titles.
See .circleci/config.yml
. On CircleCI's project settings page, you need to set environment variables to run tests on the cloud providers:
environment variable | value |
---|---|
AWS_ACCESS_KEY_ID |
An AWS IAM user access key ID. See AWS CLI. |
AWS_SECRET_ACCESS_KEY |
An AWS IAM user access key secret. See AWS CLI. |
GOOGLE_APPLICATION_CREDENTIALS |
gcp-key.json |
GOOGLE_KEY_VALUE |
The contents of a Google service account key (a JSON file) |
CODECOV_TOKEN |
The project token for codecov, available in web console. |
GH_TOKEN |
Github token (for semantic-release) |
NPM_TOKEN |
NPM publish token (for semantic-release) |
Google requires pointing to a file on disk for credentials. To get around this, the run script npm run set-gcp-key
copies the contents of the GOOGLE_KEY_VALUE
environment variable into the file gcp-key.json
in the current working directory. Therefore setting GOOGLE_APPLICATION_CREDENTIALS
to gcp-key.json
allows Google authentication to work. The circleci yaml configuration already performs these steps so only the environment variables need to be set.
The codecov token can be retrieved from the web console in a codecov account. Code coverage is optional.
We'd love your help in adding more cloud providers! Please reach out on Slack to discuss.