Synctos is an open source project. Contributions, whether as bug reports, feature requests or code, are welcomed and encouraged. Before you begin, please take a few moments to read and understand the guidelines for contribution below.
Every bug or feature request should have a corresponding issue logged in the GitHub project's Issues tab.
For bugs, be sure to include clear steps to reproduce the issue, including which versions of synctos are affected, as well as which versions of Couchbase Server and Sync Gateway the issue is reproducible with. When a bug has been reviewed by a project maintainer, it will be assigned the bug label.
For feature requests, describe the desired behaviour and provide examples of valid and invalid document definition configuration, where applicable. When a feature request has been reviewed and accepted by a project maintainer, it will be assigned the enhancement label.
This section contains information on how to implement new features or fix bugs in the project.
- Install Node.js (the latest Long Term Support release or better is recommended) to build and run the project
- Fork the synctos repository on GitHub
- Clone your fork of the synctos repository
- Install the project's local dependencies (run from the project root directory):
npm install
- Execute the project's tests (also run from the project root directory):
npm test
Files in the project are organized into the following directories:
/
: Reserved for project configuration files (e.g..gitignore
,.travis.yml
,package.json
), documentation (e.g.README.md
,CHANGELOG.md
,LICENSE
) and executable command line scripts that are part of the package's public interface (e.g.make-sync-function
,validate-document-definitions
).etc
: Any development script or other type of file that is not part of the package's public interface (e.g. build scripts).lib
: Reserved for external packages (i.e. libraries) to be embedded as static dependencies in the project.samples
: A collection of document definitions that are purely for example purposes. Specifications for these document definitions are stored in the top leveltest
directory. Code must be written to the ECMAScript 3 specification for compatibility with Sync Gateway 1.x.src
: JavaScript code that is executable by Node.js. Specifications should be stored in files alongside the code under test in this directory. Code may be written to the subset of the ECMAScript 2015 and later specifications that is supported by Node.js v8.9.0.templates
: JavaScript templates for sync functions/document definitions. Notably, the code in this directory is not intended to be executable by Node.js. Specifications are stored in the top leveltest
directory. Code must be written to the ECMAScript 3 specification for compatibility with Sync Gateway 1.x.test
: Test cases for document definition configuration elements from the top leveltemplates
directory and example document definitions from the top levelsamples
directory. Code may be written to the subset of the ECMAScript 2015 and later specifications that is supported by Node.js v8.9.0.
Individual commits for an issue should reference the GitHub issue's ticket number in the commit message and provide a brief description of what has changed. For example:
Issue #199: Allow only date strings that can be parsed by Date.parse
Every change should include comprehensive test cases. There are two different categories for specifications/tests in the project:
- Document definition configuration: Specifications for configuration elements that are defined in the
templates
directory are stored in thetest
directory. Document definitions that are to be referenced in such test cases should be stored in thetest/resources
directory. For example, the specifications for themustEqual
constraint are stored attest/must-equal.spec.js
and the corresponding test document definitions are stored attest/resources/must-equal-doc-definitions.js
. Be sure to make use of the built-in test-fixture-maker module to simplify test cases wherever possible. See the synctos Testing documentation for more info. - Node.js supporting code: Specifications for Node.js code that is defined in the
src
directory are stored alongside the corresponding source code files in thesrc
directory. Except in special cases, the specifications file's name should match that of the file under test. For example, the specifications forsrc/loading/sync-function-loader.js
are stored atsrc/loading/sync-function-loader.spec.js
.
In either case, specification files must be denoted by the .spec.js
filename suffix to be executed by the Mocha test runner. Test cases should use the Chai assertion library's expect assertion style.
To execute the full test suite and lint the project's JS files with JSHint, run npm test
from the project's root directory. A detailed, human-readable code coverage report is generated at build/coverage/lcov-report/index.html
.
Whenever configuration elements are added or updated, the document definitions schema (see the src/validation/document-definition-schema
and src/validation/property-validator-schema
modules) must also be updated for use by the document-definitions-validator module. The schema is defined according to the Joi library's API. See the project's official API documentation for more info.
Where possible, make use of the importSyncFunctionFragment
macro to split new type validation logic out of the templates/sync-function/validation-module
module into its own submodule. Furthermore, the addition of a new property/element validation type must be accompanied by an entry in the src/testing/validation-error-formatter
module's getTypeDescription
function.
The project includes comprehensive end user documentation and, to ensure it stays that way over time, every new feature must be described in detail in the project's README.md
. In many cases (e.g. when adding a new validation type) you should be able to simply follow the documentation examples provided for existing features. Be sure to update the table of contents whenever new headings are added and include code/configuration samples wherever it is appropriate to do so.
Bugs do not generally need to be documented in README.md
unless there is some caveat that users should be aware of. For example, the need to double-escape backslashes in document definitions for older versions of Sync Gateway (see sync_gateway issue #1866).
A change that addresses a GitHub issue with either of the bug or enhancement labels must include an entry in CHANGELOG.md
's "Unreleased" section according to the guidelines at Keep a Changelog. Whenever a component is marked for deprecation, its name must be listed under the "Deprecated" heading (e.g. "src/testing/test-helper
module"). Likewise, when a component has been deleted, its name must be listed under the "Removed" heading. Other issue types that do not have a functional impact on the application's behaviour (e.g. a task) generally should not be listed in the changelog.
The project's samples
directory contains a number of document definitions as examples for end users (originally based on Kashoo's official document definitions). Configuration elements introduced by new features should also be added as examples to these sample document definitions for illustrative purposes.
The project's public API will evolve over time, but it is important to avoid changes that break the behaviour of validation types, document type definition properties, helper functions, etc. that are referenced in README.md
and the functions and variables that are defined in the package's main module (i.e. index.js
) and any other Node.js modules that may be introduced as public components over time. Only under special circumstances and with prior deliberation and approval from official project maintainers will breaking changes be considered for inclusion.
The project does not and should not include any external Node.js package dependencies. In fact, in most cases it should not be necessary to add any new dependencies since the project is constrained to run within the limited JavaScript context provided by Sync Gateway, which does not allow for external packages to be imported. But in those cases where a particular utility is absolutely critical, it should be embedded statically in the project's lib
directory, as long as it is available under a license that is compatible with this project's MIT license (e.g. Apache License 2.0, BSD, Mozilla Public License 2.0).
In that event, create a new directory for the dependency in the lib
directory and be sure to include an unaltered copy of the dependency's license file, a new file called VERSION
that specifies the exact version number of the dependency, a new file called REPOSITORY
that specifies the URL of the source code repository, along with only the files from the dependency that are absolutely necessary for the desired feature to work correctly in synctos (e.g. don't include .gitignore
, package.json
, README
, etc.). If upgrading an existing embedded dependency, be sure to update the VERSION
file as well. See lib/indent.js
and lib/simple-mock
for examples.
Note that development dependencies (i.e. devDependencies
in package.json
) may be allowed since they are not transitive, but one should exercise good judgement and only include dependencies that provide vital and non-trivial functionality.
Dependencies of either type may be rejected at the discretion of official project maintainers if they are deemed unnecessary.
The project follows the principle of Semantic Versioning. However, the package's version is updated only as part of the release process. Commits for bugs and features should not modify the "version" property in package.json
. In other words, unless you are personally responsible for publishing a release of synctos, leave the version number as is.
Each change must be implemented in its own feature branch and submitted via a GitHub pull request for code review by a synctos project maintainer. Generally, unless you are a project maintainer with write access to the repo, this will require you to fork the repo, create a new branch for the feature/bug, commit the changes to the branch on your fork and then open a pull request on the original synctos repo from your fork's branch.
The project's Travis CI build job will be triggered automatically to execute all test cases and lint the code whenever there is a new or updated pull request. If the build fails, it is your responsibility to fix the problem and update the pull request with new commits.
Once a change has been posted as a GitHub pull request, a synctos project maintainer other than the change's author needs to examine the code for style, correctness, test coverage, documentation and semantics. As part of your due diligence, verify that the Travis CI build job successfully ran to completion for the pull request.
Special care should be taken to ensure that each submission is captured as a GitHub issue, thoroughly documented in README.md
and in CHANGELOG.md
's "Unreleased" section, comprehensively covered by test cases, includes examples in the sample document definitions directory, does not introduce breaking changes to public APIs, does not introduce new package dependencies and does not make use of advanced JavaScript/ECMAScript language features that are not supported by the version of the otto JavaScript engine/interpreter that is used by Sync Gateway.
If/when a change is deemed satisfactory, it is the responsibility of the reviewer to merge the pull request and delete its feature branch, where possible. Be sure to close the corresponding GitHub issue if its requirements have been fully satisfied by the pull request's changes.
When it is time to publish a new release, a project maintainer should follow these steps:
- Create a GitHub issue/ticket for the release (e.g. #272) with the task label and assigned to your own GitHub user
- Create a release branch (e.g.
v2.2.1-release
) - Create a GitHub release candidate tag (e.g.
v2.2.1-rc.1
) from the HEAD of the release branch; include the version's changelog content in the description and mark it as a "pre-release" - Validate the release candidate with kashoo-document-definitions, for example, by changing the package's "synctos" dependency version to target the release candidate tag (e.g. "git@github.com:Kashoo/synctos.git#v2.2.1-rc.1") and then running
npm install && npm test
. Confirm that a generated sync function also works with live instances of both Sync Gateway 1.x and 2.x. - Create a new branch (e.g.
272-prep-release-2.2.1
) based off of the release branch, rather than the master branch:- Modify the "Unreleased" section of
CHANGELOG.md
to display the new version number and date stamp. Be sure to also create a new range comparison link for the new version (e.g.[2.2.1]: https://github.com/Kashoo/synctos/compare/v2.2.0...v2.2.1
) and update the range comparison link for the "Unreleased" section (e.g.[Unreleased]: https://github.com/Kashoo/synctos/compare/v2.2.1...HEAD
) at the bottom of the file. - Update the "version" property in
package.json
and then regenerate the package lock file usingnpm install
- Upgrade the project's npm development dependencies (i.e. the "devDependencies" property in
package.json
) as necessary - Create a pull request that targets the release branch, rather than the master branch (e.g. #273)
- Modify the "Unreleased" section of
- After the pull request is reviewed and merged, create a GitHub release tag (e.g.
v2.2.1
) from the HEAD of the release branch; include the version's changelog content in the description - Publish the new version to npm:
git checkout <release_branch_name> && git reset --hard && git pull && npm publish
- Create a new branch (e.g.
272-post-release-2.2.1
) based off of the release branch, rather than the master branch- Restore the "Unreleased" section to
CHANGELOG.md
in the master branch. Ensure that the range comparison link at the bottom of the file for the "Unreleased" section is accurate (e.g.[Unreleased]: https://github.com/Kashoo/synctos/compare/v2.2.1...HEAD
). - Upgrade the project's runtime dependencies (i.e. the contents of the
lib
directory) as necessary - Create a pull request that targets the release branch, rather than the master branch (e.g. #309)
- Restore the "Unreleased" section to
- Merge the release branch into the master branch
- Delete the release branch
- Post a release announcement to the official Couchbase forum: https://forums.couchbase.com/t/utility-to-make-building-sync-functions-for-sync-gateway-easier/9107
- Close the GitHub issue/ticket for the release