# Contributing to Canvas

On behalf of the Canvas team, thank you so much for your contribution to this project and being a
part of the community. Before you contribute, please take a moment and look through the following
sections:

- [Code of Conduct](#code-of-conduct)
- [How to Contribute](#how-to-contribute)
  - [Communicate on Issues](#communicate-on-issues)
  - [Git Guidelines](#git-guidelines)
    - [Branches](#branches)
    - [Commit Message Format](#commit-message-format)
    - [Commit Descriptions](#commit-descriptions)
    - [Pull Requests](#pull-requests)
  - [Developer Experience](#developer-experience)
    - [Yarn and Workspaces](#yarn-and-workspaces)
    - [Storybook](#storybook)
    - [Testing](#testing)
    - [Automation on Commit](#automation-on-commit)
    - [Releases](#releases)
- [Getting Started Developing](#getting-started-developing)
  - [Creating a Module](#creating-a-module)
  - [Exporting a Module](#exporting-a-module)
  - [Building Modules](#building-modules)
  - [Testing Modules](#testing-modules)
  - [Code Style Guide](#code-style-guide)
  - [Canvas Kit Labs & Preview](#canvas-kit-labs--preview)
  - [Editors](#editors)
- [Contributor License Agreement](#contributor-license-agreement)

## Code of Conduct

At Workday, we are committed to a culture of integrity, innovation, and fun. That culture extends to
the community that we are building here through Canvas. By participating in it, you are expected to
uphold our [Code of Conduct](https://github.com/Workday/canvas-kit/blob/master/CODE_OF_CONDUCT.md)
and agree to our [Contributor License Agreement](#contributor-license-agreement).

## How to Contribute

**Don't hesitate to contribute!** Canvas Kit thrives on open discussion and contribution by anyone
in the Workday community. Contribution doesn't have to be code-based. Anyone can suggest changes to
things such as documentation, processes, and use cases.

If you are contributing code, please take a look at the following sections to familiarize yourself
with how the Canvas Kit repo is organized and run. This will help streamline the pull request
process. If you have any questions, please reach out!

If your contribution is visual or UI-based, please ensure you consult with a designer or request a
maintainer's help so the contribution can be evaluated as an end-to-end process.

### Communicate on Issues

- Create or identify [an issue](https://github.com/Workday/canvas-kit/issues) to work on
- New contributors are recommended to start with a
  [good first issue](https://github.com/Workday/canvas-kit/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22)
- Ask our team if the issue is relevant or has attention from other developers
- Communicate if you'd like to work on the issue
- Ask questions! You have our support, and you will always need more information than what is in the
  issue.

### Git Guidelines

All development should happen on a personal fork (including maintainers). Fork the
[repo](https://github.com/Workday/canvas-kit) to your personal account, and create a feature branch
for each contribution.

#### Branches

- Create branches for each feature you develop
- Branch names should be a description of the feature being implemented/bug being fixed (i.e.
  `my-feature`).
- Prefer dashes over camelCasing in branch names.

We maintain three major versions of Canvas Kit at any given time: the previous major, the current
major, and the next major version. These versions live in four branches:

- `support` - the previous major version - patches only, no new features or breaking changes
- `master` - the current major version - patches and small updates only
- `prerelease/minor` - the current major version - new features are added here and released in a new minor version.
- `prerelease/major` - the next major version - patches, new features, and major breaking changes

#### Commit Message Format

Canvas Kit relies on the
[conventional-commit format specification](https://www.conventionalcommits.org/en/v1.0.0-beta.2/#specification).
By formalizing our commit message format, this allows us to easily generate changelogs and scan
through the commit history. It also automates [semantic versioning](https://semver.org/).

#### Commit Descriptions

> **Examples**

```
feat(Button): Add proper hover states for secondary buttons
fix: Add missing static class variable to PrimaryButton and Avatar
```

> **DO**

- Use the commit scope if your change is specific to a component or module
- When in doubt, leave scope out
- Capitalize your description
- Explain the additions/edits/fixes made in your staged changes. If you cannot describe it within
  ~50 characters, you should be breaking it into multiple commits
- Use the imperative mood (e.g. "fix", not "fixed")
- Start with a verb
- Use the body of the commit if more context is needed
- If you have similar/identical commits one after another, consider using `--amend` or squashing.

> **DON'T**

- Don't use generic messages (e.g. "fix: Clean up code", "fix: Address review feedback", etc.)
- Don't describe the problem that was being solved (e.g. "fix: State was broken")
- Don't be too brief. Avoid one word descriptions. Anyone with context should have a good idea of
  what your commit does without having to look at it.
- Don't end with a period

#### Pull Requests

- We support creating a Draft Pull Request as soon as you have figured out a working implementation,
  for early feedback. It can later be marked Ready for Review.
- Open a pull request from a feature branch on your fork against the master branch on the main
  repository
- When a pull request passes all checks and reviews, a core maintainer merges via Squash and Merge
  with a link back to the PR
- The branch will automatically be deleted on merge, but its commits and the branch reference are
  still available via the PR
- When multiple developers collaborate on a PR, project maintainers are able to push commits to fork
  PRs, but other contributors will need to open their own PRs against the personal fork and the
  appropriate feature branch.
- If you have questions about the above policies, please ask :)

## Developer Experience

### Storybook

Canvas Kit uses [Storybook](https://storybook.js.org/) for the component development environment.

### Yarn and Workspaces

Canvas Kit uses Yarn for package management and takes advantage of its support for
[Workspaces](https://yarnpkg.com/lang/en/docs/workspaces/) to connect all of its different modules
within a single repository. It is recommended but not required over `npm`, unless you are updating
dependencies, then it's required.

### Testing

Canvas Kit uses [Jest](https://jestjs.io/) and
[React Testing Library](https://testing-library.com/docs/react-testing-library/intro) to unit test
our React components. For more information about our testing strategy and how we write unit tests,
visit our [Testing Readme](/getting-started/for-developers/resources/testing/).

Canvas Kit uses [Cypress](https://cypress.io) for UI tests. For info on why we chose Cypress, visit
[Why Cypress?](https://github.com/Workday/canvas-kit/tree/master/cypress/WHY_CYPRESS.md) For more
information about how to write Cypress tests, visit
[Writing Cypress Tests](https://github.com/Workday/canvas-kit/tree/master/cypress/README.md).

### Automation on Commit

Upon commit, [lint-staged](https://github.com/okonet/lint-staged) will run your staged code through
[Prettier](https://prettier.io) and [eslint](https://eslint.org).

### Releases

- Releases are prepared by updating package versions with `lerna version`, and updating the
  [changelog](/docs/changelog--docs)
- A PR is created for the above updates
- After the release PR is approved and merged, we create a release in GitHub with the contents of
  the changelog updates.
- The GitHub release automatically tags master with the new version, and deploys the new version to
  NPM.

## Getting Started Developing

1.  Clone the repository from your fork and run `yarn`
2.  Run `yarn start` to start [Storybook](https://storybook.js.org/)
3.  Visit [http://localhost:9001/](http://localhost:9001/)

### Creating a module

1.  Run `yarn create-component`
2.  Enter in a module name and description
3.  (optional) Add any required dependencies on other modules
4.  (optional) If you added any extra dependencies, run `yarn`
5.  Start Storybook `yarn start`
6.  Navigate to [http://localhost:9001/](http://localhost:9001/) and find your new module's story
7.  Begin editing your new React component in `modules/react/<MODULE_NAME>/index.ts`.

If creating a React module, a new compound component will be created. To find out more about
Compound Components, refer to
[Compound Components](/getting-started/for-developers/resources/compound-components/). To find out
more about creating Compound Components, refer to
[Creating Compound Components](/getting-started/for-developers/resources/creating-compound-components/).

### Exporting a Module

If your module's `index.ts` has a default export, make sure it is available as a named export as
well. This allows for greater flexibility in how developers consume your module. _Note that
`yarn create-component` should set this up for you by default._

### Building Modules

**`yarn build`**

This will build all modules' CSS and JS. This should only be done before publishing. It is not
needed for development.

### Testing Modules

**`yarn test`**

This will start the unit tests.

### Code Style Guide

Refer to the
[API & Pattern Guidelines](/getting-started/for-developers/resources/api-pattern-guidelines/).

Rules are enforced using [ESLint](https://eslint.org) and code formatting is provided through
[Prettier](https://prettier.io).

To lint using ESLint, use `yarn lint`. To format and lint your code (careful - this can rewrite
files), use `yarn format`.

Code formatting will occur automatically before `git commit` for files staged using `git add`.

### Canvas Kit Labs & Preview

While we iterate on a new component's API, functionality and accessibility, sometimes we want to
make it available to consumers ASAP. If we introduced the component normally, this could result in
many breaking changes to our codebase. To avoid this, we have introduced
[Canvas Kit Labs](https://github.com/Workday/canvas-kit/tree/master/modules/labs-react) as a place
to incubate components. If there is a lot of debate/discussion/flux happening in your PR and the
component is needed right away, it may be moved to this location so it can be made available while
we iterate on it. Visit the link above for more info.

[Canvas Kit Preview](https://github.com/Workday/canvas-kit/tree/master/modules/preview-react) is for
components that have had a full design and a11y review, and are approved for use in product. The
API's and/or underlying architecture could still be subject to change, but not without strong
communication and migration strategies. Essentially, Canvas Kit Labs is for alpha components and
Canvas Kit Preview is for beta components.

### Editors

Visual Studio Code is our preferred IDE. Install the Prettier and ESLint plugins for quicker and
easier formatting.

#### Visual Studio Code

Install [prettier-vscode](https://github.com/prettier/prettier-vscode) and
[vscode-eslint](https://github.com/microsoft/vscode-eslint)

Consider adding the following options:

- [Format on save](https://github.com/prettier/prettier-vscode#format-on-save)

## Contributor License Agreement

Each Contributor (“You”) represents that such You are legally entitled to submit any Contributions
in accordance with these terms and by posting a Contribution, you represent that each of Your
Contribution is Your original creation.

You are not expected to provide support for Your Contributions, except to the extent You desire to
provide support. You may provide support for free, for a fee, or not at all. Unless required by
applicable law or agreed to in writing, You provide Your Contributions on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any
warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR
PURPOSE.