Skip to content

Latest commit

 

History

History
130 lines (81 loc) · 15.8 KB

CONTRIBUTING.md

File metadata and controls

130 lines (81 loc) · 15.8 KB

Introduction

Couchster 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.

Requesting Changes

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 couchster are affected, as well as which version of Apache CouchDB 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.

Implementing Changes

This section contains information on how to implement new features or fix bugs in the project.

Getting Started

  1. Install Node.js (the latest Long Term Support release or better is recommended) to build and run the project
  2. Fork the couchster repository on GitHub
  3. Clone your fork of the couchster repository
  4. Install the project's local dependencies (run from the project root directory): npm install
  5. Execute the project's tests (also run from the project root directory): npm test

Project Structure

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-validation-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 level test directory. Code must be written to the ECMAScript 5 specification for compatibility with CouchDB.
  • 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.11.0.
  • templates: JavaScript templates for document validation functions/document definitions. Notably, the code in this directory is not intended to be executable by Node.js. Specifications are stored in the top level test directory. Code must be written to the ECMAScript 5 specification for compatibility with CouchDB.
  • test: Test cases for document definition configuration elements from the top level templates directory and example document definitions from the top level samples directory. Code may be written to the subset of the ECMAScript 2015 and later specifications that is supported by Node.js v8.11.0.

Commits

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 #6: Pass DB name to dynamic authorization constraints

Testing

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 the test directory. Document definitions that are to be referenced in such test cases should be stored in the test/resources directory. For example, the specifications for the mustEqual constraint are stored at test/must-equal.spec.js and the corresponding test document definitions are stored at test/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 couchster 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 the src directory. Except in special cases, the specifications file's name should match that of the file under test. For example, the specifications for src/loading/validation-function-loader.js are stored at src/loading/validation-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.

Document definitions schema validator

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.

Content validation

Where possible, make use of the importSyncFunctionFragment macro to split new type validation logic out of the templates/validation-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.

Documentation

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.

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. "etc/validation-error-message-formatter.js 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.

Example document definitions

The project's samples directory contains a number of document definitions as examples for end users. Configuration elements introduced by new features should also be added as examples to these sample document definitions for illustrative purposes.

Backward compatibility

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.

Package dependencies

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 CouchDB, 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 couchster (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.

Package versioning

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 couchster, leave the version number as is.

Pull requests

Each change must be implemented in its own feature branch and submitted via a GitHub pull request for code review by a couchster 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 couchster 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.

Reviewing Changes

Once a change has been posted as a GitHub pull request, a couchster 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 SpiderMonkey JavaScript engine/interpreter that is used by CouchDB.

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.

Publishing

When it is time to publish a new release, a project maintainer should follow these steps:

  1. Create a GitHub issue/ticket for the release (e.g. #30) with the task label and assigned to your own GitHub user
  2. Create a release branch (e.g. v1.1.0-release)
  3. Create a GitHub release candidate tag (e.g. v1.1.0-rc.1) from the HEAD of the release branch, rather than the master branch; include the version's changelog content in the description and mark it as a "pre-release"
  4. Validate the release candidate with a real project, for example, by changing the package's "couchster" dependency version to target the release candidate tag (e.g. "[email protected]:OldSneerJaw/couchster.git#v1.1.0-rc.1") and then running npm install && npm test. Confirm that a generated validation function also works with a live CouchDB instance.
  5. Create a new branch (e.g. issue-30-release-1.1.0) based off of the release branch, rather than the master branch:
    1. 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. [1.1.0]: https://github.com/OldSneerJaw/couchster/compare/v1.0.0...v1.1.0) and update the range comparison link for the "Unreleased" section (e.g. [Unreleased]: https://github.com/OldSneerJaw/couchster/compare/v1.1.0...HEAD) at the bottom of the file.
    2. Update the "version" property in package.json and then regenerate the package lock file using npm install
    3. Upgrade the project's npm development dependencies (i.e. the "devDependencies" property in package.json) as necessary
    4. Create a pull request that targets the release branch, rather than the master branch (e.g. #31)
  6. After the pull request is reviewed and merged, create a GitHub release tag (e.g. v1.1.0) from the HEAD of the release branch; include the version's changelog content in the description
  7. Publish the new version to npm: git checkout <release_branch_name> && git reset --hard && git pull && npm publish
  8. Create a new branch (e.g. issue-30-post-1.1.0-release) based off of the release branch, rather than the master branch:
    1. Restore the "Unreleased" section to CHANGELOG.md. Ensure that the range comparison link at the bottom of the file for the "Unreleased" section is accurate (e.g. [Unreleased]: https://github.com/OldSneerJaw/couchster/compare/v1.1.0...HEAD).
    2. Upgrade the project's runtime dependencies (i.e. the contents of the lib directory) as necessary
    3. Create a pull request that targets the release branch, rather than the master branch (e.g. #32)
  9. Merge the release branch into the master branch
  10. Delete the release branch
  11. Post a release announcement to the official Apache CouchDB mailing list: https://mail-archives.apache.org/mod_mbox/couchdb-user/
  12. Close the GitHub issue/ticket for the release