Project contribution guidelines.
Woot woot! If you are new to stdlib, welcome! And thanks for your interest! While this guide focuses on technical development, if you are looking to contribute to the project but are non-technical, you can still contribute! For example, you can contribute by filing issues, writing RFCs (feature requests), updating documentation, providing build and infrastructure support, offering funding, and helping market and promote the project, among other things. Every bit helps, and we are grateful for your time and effort!
Before contributing, read the Code of Conduct, which details the bare minimum behavior expectations that the project requires of its contributors.
When filing new issues and commenting on existing issues on this repository, please ensure that discussions are related to concrete technical issues. For general questions and help, consult the FAQ and visit the Gitter channel.
Before filing a potential bug report,
- Search for existing issues and pull requests.
- Try some debugging techniques to help isolate the problem, including logging inputs and outputs.
If the source of the problem is a third party package, file a bug report with the relevant package author, rather than on this repository.
We want to fix all issues as soon as possible; however, before fixing a bug, we need to reproduce and confirm the errant behavior. Accordingly, in order to help us reproduce bugs, we require that you provide a minimal reproduction. A minimal reproduction provides us with important information and helps us avoid having to ask follow-up questions and wait for your response.
A minimal reproduction allows us to more quickly confirm a bug (or identify a potential coding problem) and confirm that we are fixing the right problem.
We require a minimal reproduction to save maintainers' time and ultimately to fix more bugs. Often, developers may find coding problems in their original code while preparing a minimal reproduction. We certainly understand that extracting essential bits of code from a larger codebase can be difficult, but we really need to isolate the problem before we can fix it.
Unfortunately, we are not able to investigate or fix bugs without a minimal reproduction. If a bug report does not include a minimal reproduction, the issue will be automatically closed.
When filing an issue, provide the following, where possible:
- A description of the issue.
- Links to any related issues.
- The full error message, including the stacktrace.
- The sequence of steps required to reproduce the issue.
- A minimal working example (i.e., the smallest chunk of code that triggers the error.) Ideally, the code can be pasted into a REPL or run from a source file. If the code is larger than
100
lines, consider creating a gist. - The expected results.
- List of affected environments (e.g., browser, browser version,
npm
version, Node.js version, operating system, and stdlib version).
When pasting code blocks or output, use triple backticks to enable proper formatting. Surround inline code with single backticks. For other Markdown formatting tips and trips, see GitHub's Markdown guide.
Be aware that the @
symbol tags users on GitHub, so always surround package names with backticks (e.g., @stdlib/utils/copy
).
By contributing code to the project, you are agreeing to release it under the project license.
Before contributing code, be sure to
- read and understand the licensing terms.
- read and understand the style guides.
- read and understand the doctest guide.
For instructions on how to setup and configure your environment, be sure to
- read and follow the development guide.
If you have found a bug that you would like to fix,
- file an issue on the project GitHub issue tracker describing the bug as instructed above.
- wait for feedback.
- submit a pull request with your proposed changes.
If you want to contribute a new feature or a breaking change to stdlib, be sure to
- consult the Gitter channel to discuss ideas and to gather feedback as to whether a feature would be better developed as an external package. Discussing the design upfront helps ensure that we're ready to accept to your work.
- write an RFC (request for comments) detailing the proposed change and submit as an issue on the project GitHub issue tracker.
- wait for RFC approval.
- submit a pull request, making sure to adhere to the guidance set forth in the RFC.
If you want to contribute a new package, be sure to
- read and follow the package development guide.
- read and follow the REPL text guide.
If you are unfamiliar with Git, the version control system used by GitHub and this project,
Next, take a look around the project, noting the style and organization of documentation, tests, examples, benchmarks, and source implementations. Consistency is highly prioritized within stdlib. Thus, the more you are able to match and adhere to project conventions and style, the more likely your contribution will be accepted. While we have done our best to automate linting and style guidelines, project automation is not perfect and cannot adequately capture the inevitable exceptions and nuance to many rules. In short, the more you study existing practice, the better prepared you will be to contribute to stdlib.
Create a GitHub account. The project uses GitHub exclusively for hosting source code, managing issues and pull requests, triggering continuous integration, and reporting.
Fork the repository on GitHub and clone the repository to your local machine.
$ git clone https://github.com/<username>/stdlib.git
where <username>
is your GitHub username. When cloning, avoid cloning to a directory having spaces in its path. Because this project relies heavily on make
, any spaces in the directory path will lead to errors and inevitable frustration.
// Bad:
/home/foo/bar/beep boop/stdlib
// Good:
/home/foo/bar/beep_boop/stdlib
The repository has a large commit history, leading to slow download times. You can reduce the download time by limiting the clone depth.
$ git clone --depth=<depth> https://github.com/<username>/stdlib.git
where <depth>
refers to the number of commits you want to download (as few as 1
and as many as the entire project history). However, you should be aware that limiting clone depth can cause difficulties later when attempting to rebase a pull request on the latest development branch. For simple pull requests, limiting clone depth is likely to work out fine; however, for more complex pull requests, including those depending on upstream changes, limiting clone depth may be a source of Git errors (e.g., due to unrelated Git histories), and, thus, you may be forced to re-clone the repository and start over.
If you are behind a firewall, you may need to use the https
protocol, rather than the git
protocol.
$ git config --global url."https://".insteadOf git://
Once you have finished cloning the repository into the destination directory, you should see the folder stdlib
. To proceed with configuring your environment, navigate to the project folder.
$ cd stdlib
And finally, add an upstream
remote to allow syncing changes between this repository and your local version.
$ git remote add upstream git://github.com/stdlib-js/stdlib.git
Install dependencies.
$ make install
Initialize Git hooks to enable automated development processes to run prior to authoring commits and pushing changes.
$ make init
Note that make init
only needs to be run once; however, we repeat it below as not running it is a common omission by new contributors.
For modifications intended to be included in stdlib, create a new local branch.
$ git checkout -b <branch>
where <branch>
is the branch name. Both the master
and develop
branches for the main stdlib project are protected, and direct modifications to these branches will not be accepted. Instead, all contributions should be made on non-master and non-develop local branches, including documentation changes and other non-code modifications. See the project branching guide for additional guidance.
Start making your changes and/or implementing the new feature. Any text you write should follow the text style guide, including comments and API documentation.
Ensure that you have configured Git to know your name and email address.
$ git config --global user.name "Jane Doe"
$ git config --global user.email "[email protected]"
Add changed files and commit.
$ git add files/which/changed
$ git commit
When writing commit messages, follow the Git style guide. Adherence to project commit conventions is necessary for project automation which automatically generates release notes and changelogs from commit messages.
To incorporate recent changes from the upstream
repository during development, you should rebase your local branch, reapplying your local commits on top of the current upstream HEAD
. This procedure is in contrast to performing a standard merge, which may interleave development histories. The rationale is twofold:
- interleaved histories make squashing commits more difficult.
- a standard merge increases the risk of incomplete/broken commits appearing in the Git history.
An ideal commit history is one in which, at no point in time, is the project in a broken state. While not always possible (mistakes happen), striving for this ideal facilitates time travel and software archeology.
$ git fetch upstream
$ git rebase upstream/develop
Tests should accompany all bug fixes and features. For guidance on how to write tests, consult existing tests within the project.
Before submitting a pull request to the upstream
repository, ensure that all tests pass, including linting. To run tests locally, consult the guidance below.
If Git hooks have been enabled,
$ make init
linting should be automatically triggered prior to each commit, and test execution should be automatically triggered prior to each push.
Any pull requests which include failing tests and/or lint errors will not be accepted.
Push your changes to your remote GitHub repository.
$ git push origin <branch>
where <branch>
is the name of your branch.
Once your contribution is ready to be incorporated in the upstream
repository, open a pull request against the develop
branch. One or more project contributors will review the contribution, provide feedback, and potentially request changes.
Receiving feedback is the most important, and often the most valuable, part of the submission process. Don't get disheartened!
To make changes to your pull request, make changes to your branch. Each time you push changes to your forked repository, GitHub will automatically update the pull request.
$ git add files/which/changed
$ git commit
$ git push origin <branch>
Note that, once a pull request has been made (i.e., your local repository commits have been pushed to a remote server), you should not perform any further rewriting of Git history. You can, however, use Git's squash!
or fixup!
to convey that a commit is intended to be squashed into another commit. For example, to create a fix up on the last commit
$ git commit --fixup HEAD ...
or a specific commit
# Find the commit SHA:
$ git log
# Create a fix up:
$ git commit --fixup <COMMIT_SHA> ...
Alternatively, you can also create a new commit with a commit message starting with fixup! <commit header>
followed by the commit header of the commit being fixed up. For example,
$ git commit -m "fixup! feat: add support for computing the absolute value"
If the history needs modification, a contributor will modify the history during the merge process. The rationale for not rewriting public history is that doing so invalidates the commit history for anyone else who has pulled your changes, thus imposing additional burdens on collaborators to ensure that their local versions match the modified history.
In the event that you need to pull in changes from the upstream
repository after having pushed changes to your remote repository (e.g., to incorporate fixes unrelated to your work in order to address CI failures, etc), perform a standard merge.
$ git pull upstream develop
After any changes have been resolved and continuous integration tests have passed, a contributor will approve a pull request for inclusion in the project. Once merged, the pull request will be updated with the merge commit, and the pull request will be closed.
Note that, in most cases during the merge process, multiple commits will be squashed into a single commit.
Congratulations! You are an official contributor to stdlib! Thank you for your hard work and patience!
- When linking to specific lines of code in an issue or a pull request, hit the
y
key while viewing a file on GitHub. Doing so reloads the page with a URL that includes the specific version of the file you are viewing. This ensures that, when you refer to specific lines, these same lines can be easily viewed in the future, even if the content of the file changes. - GitHub does not send notifications to project maintainers when you push a commit and update a pull request, so be sure to comment on the pull request thread to inform reviewers that you have made changes and request another review using the GitHub UI.
By contributing tests to the project, you are agreeing to release it under the project license.
The project can never have enough tests. To address areas lacking sufficient test coverage,
-
View the latest coverage report.
-
Browse the source files and find untested functionality highlighted in red.
-
Locate the package containing the source file in your forked repository.
-
Add tests to the package test file(s).
-
To run package tests,
$ make TESTS_FILTER=".*/<pattern>/.*" test
where
<pattern>
is a pattern matching a particular path. For example, to test the base mathsin
package$ make TESTS_FILTER=".*/math/base/special/sin/.*" test
where the pattern
.*/math/base/special/sin/.*
matches any test file whose absolute path containsmath/base/special/sin
. -
To generate a test coverage report,
$ make TESTS_FILTER=".*/<pattern>/.*" test-cov $ make view-cov
which opens the coverage report in your default web browser.
-
Submit the test as a pull request.
Note that, for contributions targeting C implementations, you'll need to first compile the native add-on which provides the bridge between JavaScript and C (assuming that the package has a native add-on binding).
$ make install-node-addons NODE_ADDONS_PATTERN="math/base/special/sin"
where the pattern math/base/special/sin
(note the differences from the filter pattern above!) matches any add-on whose absolute path contains math/base/special/sin
.
Once the add-on is compiled, you can follow steps 5-7 above.
By contributing documentation to the project, you are agreeing to release it under the project license.
Project documentation is localized within each package. Similar to code, you should modify documentation using Git. Provided you have followed the development guide and enabled Git hooks,
$ make init
modified Markdown files are automatically linted prior to each commit. Any changes to documentation files should be free of lint errors. If a pull request includes lint errors, the pull request will not be accepted.
Opening a pull request automatically triggers a continuous integration build. Each pull request update queues an additional build. If a pull request has more than one build queued, only the most recent build in the queue is run.
Only a project administrator can manually trigger a build.
By making a contribution to this project, I certify that:
- (a) The contribution was created in whole or in part by me and I have the right to submit it under the open source license indicated in the file; or
- (b) The contribution is based upon previous work that, to the best of my knowledge, is covered under an appropriate open source license and I have the right under that license to submit that work with modifications, whether created in whole or in part by me, under the same open source license (unless I am permitted to submit under a different license), as indicated in the file; or
- (c) The contribution was provided directly to me by some other person who certified (a), (b) or (c) and I have not modified it.
- (d) I understand and agree that this project and the contribution are public and that a record of the contribution (including all personal information I submit with it, including my sign-off) is maintained indefinitely and may be redistributed consistent with this project or the open source license(s) involved.
Phew. While the above may be a lot to remember, even for what seem like minor changes, eventually it becomes routine and part of the normal development flow. Part of the motivation for enforcing process is to ensure that all code contributions meet a certain quality threshold, thus helping reviewers focus less on non-substantive issues like style and failing tests and more on substantive issues such as contribution content and merit. Know that your patience, hard work, time, and effort are greatly appreciated!