Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Module Lead Maintainers Protocol #301

Merged
merged 10 commits into from
May 1, 2018
233 changes: 138 additions & 95 deletions js-code-guidelines.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Guidelines for JavaScript projects
=================================
Guidelines for the InterPlanetary JavaScript Projects
=====================================================

These guidelines reflect our shared consensus on protocol and etiquette from what we've built so far. Every single item that is presented here is the result of lots of experimentation. However, that doesn't mean that there isn't a better way to do things. What we have below is simply what we've found to work best for us. In this document you will find notes about:

Expand All @@ -10,56 +10,52 @@ These guidelines reflect our shared consensus on protocol and etiquette from wha
- Tasks (asset pipeline, transpiling, releasing, etc).
- Dependency management.

Our toolkit for each of these is not set in stone, and we don't plan to halt our constant search for better tools. Get in touch if you've got ideas.

Also, remember:

![Barbossa's warning](assets/CodeIsMoreLikeGuidelines.jpg)
Our toolkit for each of these is not set in stone, and we don't plan to halt our constant search for better tools. Get in touch if you've got ideas. [These are guidelines rather than rules](assets/CodeIsMoreLikeGuidelines.jpg).

## Table of Contents

- [Goals](#goals)
- [Tech Leads and Lead Maintainers](#tech-leads-and-lead-maintainers)
- [Contributing](#contributing)
- [Captains and Maintainers](#captains-and-maintainers)
- [Guidelines](#guidelines)
- [Linting & Code Style](#linting--code-style)
- [Testing](#testing)
- [Releasing](#releasing)
- [Documentation](#documentation)
- [Commits](#commits)
- [Commit Message Format](#commit-message-format)
- [Revert](#revert)
- [Type](#type)
- [Scope](#scope)
- [Subject](#subject)
- [Body](#body)
- [Footer](#footer)
- [Examples](#examples)
- [References](#references)
- [Pull Requests](#pull-requests)
- [Guidelines](#guidelines)
- [Linting & Code Style](#linting--code-style)
- [Dependency Versions](#dependency-versions)
- [Testing](#testing)
- [Releasing](#releasing)
- [Documentation](#documentation)
- [Commits](#commits)
- [Commit Message Format](#commit-message-format)
- [Signed Commits](#signed-commits)
- [Revert](#revert)
- [Type](#type)
- [Scope](#scope)
- [Subject](#subject)
- [Body](#body)
- [Footer](#footer)
- [Examples](#examples)
- [References](#references)
- [Pull Requests](#pull-requests)
- [Aegir](#aegir)
- [...for maintainers](#for-maintainers)
- [Setting up `aegir`](#setting-up-aegir)
- [Directory Structure](#directory-structure)
- [Default `require`](#default-require)
- [Continuous integration](#continuous-integration)
- [`.gitignore`](#gitignore)
- [`.npmignore`](#npmignore)
- [Dependency management](#dependency-management)
- [Pre-Commit](#pre-commit)
- [Building](#building)
- [...for consumers](#for-consumers)
- [...for maintainers](#for-maintainers)
- [Setting up `aegir`](#setting-up-aegir)
- [Directory Structure](#directory-structure)
- [Continuous integration](#continuous-integration)
- [`.gitignore`](#gitignore)
- [`.npmignore`](#npmignore)
- [Dependency management](#dependency-management)
- [Pre-Commit](#pre-commit)
- [Building](#building)
- [...for consumers](#for-consumers)
- [FAQ](#faq)
- [Why are you not using XYZ?](#why-are-you-not-using-xyz)
- [Why not use simple npm scripts instead of gulp?](#why-not-use-simple-npm-scripts-instead-of-gulp)
- [Where are all the semicolons?](#where-are-all-the-semicolons)
- [Why are you bothering with ES2015 and all this build setup?](#why-are-you-bothering-with-es2015-and-all-this-build-setup)
- [Do I have to use ES2015 and Babel and aegir in my project?](#do-i-have-to-use-es2015-and-babel-and-aegir-in-my-project)
- [Do I have to bundle everything with webpack?](#do-i-have-to-bundle-everything-with-webpack)
- [Why are you doing this?](#why-are-you-doing-this)
- [Why are you not using XYZ?](#why-are-you-not-using-xyz)
- [Where are all the semicolons?](#where-are-all-the-semicolons)
- [Why are you bothering with ES2015 and all this build setup?](#why-are-you-bothering-with-es2015-and-all-this-build-setup)
- [Do I have to use ES2015 and Babel and aegir in my project?](#do-i-have-to-use-es2015-and-babel-and-aegir-in-my-project)
- [Do I have to bundle everything with webpack?](#do-i-have-to-bundle-everything-with-webpack)
- [Why are you doing this?](#why-are-you-doing-this)
- [Code of Conduct](#code-of-conduct)
- [References - Resources and good reads](#references---resources-and-good-reads)
- [Acknowledgment](#acknowledgment)
- [Acknowledgments](#acknowledgments)

## Goals

Expand All @@ -73,39 +69,83 @@ For the majority of our JavaScript projects, our goals are to:
- **Encourage contribution**.
- **Have great UX** for everyone involved.

## Contributing
## Tech Leads and Lead Maintainers

Please follow the conventions described in this document.
> This section is a formalization of the proposal and discussion around the [Module Lead Maintainers - Sharing the Responsibility over the IPFS module base](https://github.com/ipfs/pm/issues/600) proposal.

When reporting a bug, if possible, provide a way for us to reproduce it (or even better, write a test that fails with your case).
We have two types of leads in the JavaScript project ecosystems, the Tech Lead and the Module Lead Maintainer. A brief description of both roles is:

Always run tests before pushing and PR'ing your code.
- A Tech Lead directs the development of an entire ecosystem of modules (i.e js-ipfs, js-libp2p, js-ipld and js-multiformats), it has a complete understanding of the stack, the IPFS project, its goals and participates actively in the ROADMAP planning.
- A Lead Maintainer is a contributor that has shown extraordinary ability to contribute to the project and willingness to make the project better by taking the responsibility of stewarding one of its modules forward.

With this structure, we expect to achieve the following goals:

- Recognize extraordinary contributions and empower contributors to take an even more important role in the project.
- Reduce PR review time and Time To Release.
- Increase the overall quality of the project.
- Help users know who to reach out to for help.
- Have a clear protocol to pass on the baton.

The current Tech Leads are:

- [David Dias](https://github.com/diasdavid/) for js-ipfs, js-libp2p js-multiformats ecosystems.
- [Volker Mische](https://github.com/vmx) for the js-ipld ecosystem.

### Captains and Maintainers
The current Lead Maintainers can be identified either by the `maintainer` field in the package.json of the module and/or the section `Maintainer` in the README.md of the module.

For each JavaScript repository in the IPFS, libp2p, IPLD, or related GitHub orgs, there should be a single Captain specified in the Maintainers section of the README for that repository. The Captain is in charge of merging PRs, keeping issues up to date, and overall quality of a repository.
**Lead Maintainer responsibilities:**

Sometimes, a Captain may elect to have other maintainers that also have merge ability and commit access to the main repo. These maintainers can help out, but defer to the Captain as the person in charge of maintaining quality across the repo. It is important that this distinction is explicit; if there are long-standing PRs or issues, it is ultimately up to the Captain to gather information about the issue or PR. A Captain only makes a decision if he _needs_ to and _all_ methods of discussion are exhausted. Our community strives to trust the Captain as someone who ultimately has the most knowledge of a repo (even if they are also opinionated, and even if they have to spend effort to source that knowledge). This may change in the future, if we go with more non-hierarchical model.
- Respect and follow the [IPFS Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md).
- Have a complete understanding of the module purpose, its specification (if any) and how the module is used by other parts of the project.
- Review and merge PRs.
- Respond in a timely manner to Github issues and curate them to ensure that duplicates are coalesced, issues are labeled with difficulty and priority, and also tag any issue that is open for new contributors with the `help wanted` label.
- Publish new versions of the module to npm.

Repositories which do not have Captains will show up in red on [Project Repos](https://project-repos.ipfs.io). Please open an issue in the repository asking for a captain to be nominated if none is provided.
**Lead Maintainer expected attitude:**

If you would like to become a maintainer (or lieutenant, or first mate, or whatever nautical metaphor you prefer), please open an issue about it! Chances are that we would love to have more help.
- Be proactive in increasing the quality of the module. This goes from improving documentation, tests, codebase and more.
- Show a great level of rigor and polish in the code that they ship.
- Help others in understanding how the module works and why it exists.
- Apply the established Contributing Guidelines to the project and help others do too

## Guidelines
**How to become a Lead Maintainer:**

### Linting & Code Style
Currently, there is no formal test or request form to do so. Lead Maintainers will be invited and nominated by the Tech Lead once the expected behaviour and rigor is observed. A Lead Maintainer can nominate the next Lead Maintainer to the Tech Lead

**In practice:**

- Update each package.json and README.md to have a `leadMaintainer` field.
- Update packages table on each entry module (e.g https://github.com/ipfs/js-ipfs#packages) to also list the maintainer for each.
- Protect the master branch and only grant permissions for merge to the Maintainer and the Tech Lead, only.
- Grant publish permission to the Maintainer and Tech Lead, only.

## Contributing

Please follow the conventions described in this document.

When reporting a bug, if possible, provide a way for us to reproduce it (or even better, write a test that fails with your case).

Always run tests before pushing and PR'ing your code.

### Guidelines

#### Linting & Code Style

IPFS JavaScript projects default to [standard](https://github.com/feross/standard) code style. It is a clean codestyle, and its adoption is increasing significantly, making the code that we write familiar to the majority of the developers.

However, we've added an extra linting rule: Enforce the use of [strict mode](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode). This avoids issues we had when using ES2015 features outside of strict mode. We enforce this rule by using [eslint](http://eslint.org/) and extending [standard module](https://github.com/feross/standard) with the [eslint-config-standard](https://github.com/feross/eslint-config-standard).

Using [aegir-lint](#aegir) will help you do this easily; it automatically lints your code.

### Testing
#### Dependency Versions

Our rule is: Use ~ for everything below 1.0.0 and ^ for everything above 1.0.0. If you find a package.json that is not following this rule, please submit a PR.

#### Testing

Since `js-ipfs` is meant to be both a Node.js and Browser app, we strongly recommend having tests that run in both platforms, always. For most cases, we use [mocha](http://mochajs.org) to run write the tests and [karma](http://karma-runner.github.io) to automate the test execution in the browser. This solution has been extremely convenient.

### Releasing
#### Releasing

Each time a new release happens, these are the steps we follow to make sure nothing gets left out:

Expand All @@ -118,25 +158,21 @@ Each time a new release happens, these are the steps we follow to make sure noth
7. Push to GitHub
8. Publish to npm

### Documentation
#### Documentation

We use [documentation.js](https://github.com/documentationjs/documentation/tree/master/docs) to document our JavaScript repositories. For each repo, we use [this gulp task](https://github.com/documentationjs/gulp-documentation). An example for how to use JSDoc to document everything can be seen in [this PR to js-ipfs](https://github.com/ipfs/js-ipfs/pull/651). Ideally, we create a `docs` folder in each repository, and make sure it is not tracked to git.
We use [documentation.js](https://github.com/documentationjs/documentation/tree/master/docs) to document our JavaScript repositories. An example for how to use JSDoc to document everything can be seen in [this PR to js-ipfs](https://github.com/ipfs/js-ipfs/pull/651). Ideally, we create a `docs` folder in each repository, and make sure it is not tracked to git.

We use [`aegir-docs`](https://github.com/dignifiedquire/aegir) for the actual generation, which relies on JSDoc style comments. For more on aegir, see [the section below](#aegir).

## Commits
### Commits

We have very precise rules over how our git commit messages can be formatted. This leads to more readable messages that are easy to follow when looking through the project history. But also, we use the git commit messages to generate the change log.

We have very precise rules over how our git commit messages can be formatted.
This leads to more readable messages that are easy to follow when
looking through the project history. But also,
we use the git commit messages to generate the change log.
The commit message formatting can be added using a typical git workflow or through the use of a CLI wizard ([Commitizen](https://github.com/commitizen/cz-cli)).

The commit message formatting can be added using a typical git workflow or
through the use of a CLI wizard ([Commitizen](https://github.com/commitizen/cz-cli)).
#### Commit Message Format

### Commit Message Format
Each commit message consists of a header, a body and a footer.
The header has a special format that includes a type, a scope and a subject:
Each commit message consists of a header, a body and a footer. The header has a special format that includes a type, a scope and a subject:

```
<type>(<scope>): <subject>
Expand All @@ -148,15 +184,25 @@ The header has a special format that includes a type, a scope and a subject:

The header is mandatory and the scope of the header is optional.

Any line of the commit message cannot be longer 100 characters! This allows the message to be easier
to read on GitHub as well as in various git tools.
Any line of the commit message cannot be longer 100 characters! This allows the message to be easier to read on GitHub as well as in various git tools.

#### Signed Commits

We kindly ask and expect for all commits to be signed off with the same license as the repo and module. This can be done by appending the following to your commit message:

```
License: MIT
Signed-off-by: User Name <email@address>
```

### Revert
If the commit reverts a previous commit, it should begin with `revert: `,
followed by the header of the reverted commit. In the body it should
say: `This reverts commit <hash>.`, where the hash is the SHA of the commit being reverted.
You can use the [sign-commit](http://npmjs.com/sign-commit) module to get a git hook to append this to all your commits.

#### Revert

If the commit reverts a previous commit, it should begin with `revert: `, followed by the header of the reverted commit. In the body it should say: `This reverts commit <hash>.`, where the hash is the SHA of the commit being reverted.

#### Type

### Type
Must be one of the following:

* **feat**: A new feature
Expand All @@ -170,28 +216,29 @@ Must be one of the following:
* **chore**: Changes to the build process or auxiliary tools and libraries such as documentation
generation

### Scope
The scope could be anything specifying the place of the commit change. For example `api`,
`cli`, etc...
#### Scope

The scope could be anything specifying the place of the commit change. For example `api`, `cli`, etc...

#### Subject

### Subject
The subject contains a succinct description of the change:

* use the imperative, present tense: "change" not "changed" nor "changes"
* don't capitalize first letter
* no dot (.) at the end

### Body
Just as in the subject, use the imperative, present tense: "change" not "changed" nor "changes".
The body should include the motivation for the change and contrast this with previous behavior.
#### Body

### Footer
The footer should contain any information about breaking changes and is also the place to
reference GitHub issues that this commit closes.
Just as in the subject, use the imperative, present tense: "change" not "changed" nor "changes". The body should include the motivation for the change and contrast this with previous behavior.

#### Footer

The footer should contain any information about breaking changes and is also the place to reference GitHub issues that this commit closes.

**Breaking Changes** should start with the word `BREAKING CHANGE:` with a space or two newlines. The rest of the commit message is then used for this.

### Examples
#### Examples

```
feat(pencil): add 'graphiteWidth' option
Expand All @@ -215,7 +262,7 @@ revert: feat(pencil): add 'graphiteWidth' option
This reverts commit 667ecc1654a317a13331b17617d973392f415f02.
```

### References
#### References

This commit strategy is based on:

Expand All @@ -224,7 +271,7 @@ This commit strategy is based on:

More details about the commit convention can also be found in this [document](https://docs.google.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y).

## Pull Requests
### Pull Requests

There should be no dependencies that rely on commits. Instead, there should be WIP PR and each PR that depends on other WIP PR should list what it depends on. Yes, everyone will have to do the extra work of `npm link`ing everything, but this helps us have a cleaner workflow.

Expand Down Expand Up @@ -281,9 +328,6 @@ To reduce the amount of configuration, aegir expects your source code to be in `
├── dist # auto-generated by the transpile and minification task.
│ ├── index.js
│ └── index.min.js
├── lib # auto-generated source tree, transpiled using babel. Makes the code es5 compatible
│ ├── index.js
│ └── ...
├── src # source code. Can use the latest features (ES2015) in JavaScript.
│ ├── index.js
│ └── ...
Expand Down Expand Up @@ -312,7 +356,7 @@ We also use [coveralls.io](https://coveralls.io/) to automatically publish cover
script:
- npm run coverage
after_success:
- npm run coverage publish
- npm run coverage publish --providers coveralls
```

##### `.gitignore`
Expand Down Expand Up @@ -383,7 +427,7 @@ Our linting rules are compatible with [standard](https://github.com/feross/stand

We want to see the web move forward, and some of us enjoy writing their JavaScript with things like `const` and arrow functions.

#### Do I have to use ES2015 and Babel and aegir in my project?
#### Do I have to use ES2015, Babel and aegir in my project?

No.

Expand All @@ -405,7 +449,7 @@ Any IPFS JavaScript project follows the same [Code of Conduct](https://github.co
- [The cost of transpiling ES2015 in 2016](https://github.com/samccone/The-cost-of-transpiling-es2015-in-2016)
- [standardjs.com](http://standardjs.com/)

## Acknowledgment
## Acknowledgments

This project would not be possible without the hard work of many many people. So a big shout out to all contributors to these projects:

Expand All @@ -415,4 +459,3 @@ This project would not be possible without the hard work of many many people. So
- [mocha](https://github.com/mochajs/mocha/graphs/contributors)
- [chai](https://github.com/chaijs/chai/graphs/contributors)
- [webpack](https://github.com/webpack/webpack/graphs/contributors)
- [babel](https://github.com/babel/babel/graphs/contributors)