# Contributing
The _Privacy Components for the web_ are made in a monorepository where web components are delivered as separate npm packages and CDN bundles as part of the [blindnet devkit](https://blindnet.dev).
This guide is here to help you master all parts of our development workflow, so you can help us make the _Privacy Components for the web_ even better.
> **Note**
>
> We welcome all kinds of contributions, including the non-code related ones.
>
> Just [open an issue][new-issue] or a simple informal [DevRel Request][request] anytime you have a suggestion to make or a discussion to start, and we'll make sure to quickly find the best solution for you.
## Prerequisites
This project only requires Git, [classic Yarn (v1)](https://classic.yarnpkg.com/en/docs/install#debian-stable) and [Node.js v16](https://nodejs.org/).
> **Note**
>
> We recommend using [nvm](https://github.com/nvm-sh/nvm) to install and use Node.js with this project.
>
> Just run `nvm install` (without any other option) at the root of this repository to install the recommended version of Node.js, then `nvm use` to use it.
>
> You can then the run `npm i -g yarn` to install classic Yarn in this specific version of Node.js.
## Get Started
You first need to [fork this repository](https://github.com/blindnet-io/privacy-components-web/fork) and clone your fork locally:
```bash
git clone git@github.com:{{your-username}}/privacy-components-web.git
```
Then, go to the root directory of your local clone, install the dependencies **with classic Yarn** (_Yarn 2+ and npm aren't supported_), and link local packages together [using Lerna](https://github.com/lerna/lerna/tree/main/commands/bootstrap):
> Lerna is part of this project's development dependencies, so you don't need to install it yourself.
```bash
cd privacy-components-web
yarn install
yarn lerna bootstrap
```
> **Note**
>
> We also recommend using VS Code and provide a [recommended list of extensions](https://code.visualstudio.com/docs/editor/extension-marketplace#_workspace-recommended-extensions) for it, but you can use any IDE or editor to contribute to this project.
## Storybook
The Privacy Components for the web are built with a _Visual TDD_ / _Story Driven Development_ approach in mind.
In practical terms, this means Storybook stories (along with unit tests) are the central entry point for all developments.
For more detail about how to write good stories, refer to the [Storybook for Web Components documentation](https://storybook.js.org/docs/web-components/get-started/introduction).
To run a local instance of Storybook for your component, run
```bash
npm run storybook
```
To build a production version of Storybook, run
```bash
npm run storybook:build
```
## Testing
This project uses the modern-web [Web Test Runner](https://modern-web.dev/docs/test-runner/overview/) to run all unit tests, and the Open-WC [Testing Package](https://open-wc.org/docs/testing/testing-package/) to ease their development.
To execute a single test run:
```bash
npm run test
```
To run the tests on packages in interactive watch mode run:
```bash
npm run test:packages:watch
```
> **Note**
>
> As our demos needs to be self-sufficient, we run their tests using their own "test" npm scripts in parallel using `lerna run`.
> However, web-test-runner [can't run in watch mode in a non-interactive (TTY) terminal](https://github.com/modernweb-dev/web/issues/19).
> This mean you can't run both packages and demos tests simultaneously in watch mode.
>
> Instead, you should go to the directory where the demo you want to contribute to is developed (e.g. `/demos/devkit-simple-tutorial`) and directly run all the specific npm scripts you want their (including `test:watch` if it exists).
## Linting & Formatting
To scan the project for linting and formatting errors, run
```bash
npm run lint
```
To automatically fix linting and formatting errors, run
```bash
npm run format
```
Linting and formatting are provided using [ESLint](https://eslint.org), [Prettier](https://prettier.io) and [Markdownlint](https://github.com/igorshubovych/markdownlint-cli).
If you only want to check or format using one of these tools, run:
- `[format|lint]:es` for ESLint
- `[format|lint]:prettier` for Prettier
- `[format|lint]:md` for Markdownlint
> **Note**
>
> Commit hooks are provided via [Husky](https://github.com/typicode/husky) to automatically check and fix the format of all staged files using [lint-staged](https://github.com/okonet/lint-staged).
## Building
To build all packages at once, just run `yarn build`.
This will run:
1. [import maps](https://github.com/WICG/import-maps) generation using [Importly](https://github.com/chase-moskal/importly/)
`yarn run build:imports`
1. the extraction of internationalized messages and build of the localized components using [@lit/localized-tools](https://www.npmjs.com/package/@lit/localize-tools)
`yarn run build:localize`
1. typescript compilation, bundling, and every other parts of the building process using [Rollup.js](https://rollupjs.org)
`yarn run build:rollup`
Each script can be run independently.
However, Rollup.js requires the import maps and localization files to be generated and up to date.
To automatically rebuild the bundles when its source files change on disk, use `yarn watch`.
More options, specific to this project's configuration, can also be used to customize Rollup.js behavior when using the `build:rollup` or `watch` scripts.
For the complete list of options, run: `yarn build:rollup --configHelp`
> **Warning**
>
> This project only supports and provides [ESM](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules) packages for web browsers.
> No [CJS](https://nodejs.org/docs/latest/api/modules.html), [AMD](https://github.com/amdjs/amdjs-api/blob/master/AMD.md) or Node.js specific code/package can be used as a dependency.
## Workflow & Releases
This project follows a "permissive" [gitflow](https://danielkummer.github.io/git-flow-cheatsheet/), with:
- no restriction on feature branch names whatsoever
- a `develop` branch, target of all feature / bug fix PRs
- a `main` branch, receiving merges from the develop branch on a regular basis, and hotfixes when required
Releases are **automatically** made and published to npm as follow:
- every new commit pushed to a branch associated with an open PR leads to a "canary" alpha release
(`X.X.X-pr{{PR-Number-in-Github}}-{{short-commit-hash}}`)
- every PR merged to the `develop` branch leads to a new `beta` release
(`X.X.X-beta.N`)
- every new commit in the `main` branch leads to a new "stable" release
(major, minor or patch)
Version numbers follow [**semantic versioning**](https://semver.org/) and are automatically incremented based on commits messages.
## Localization
To contribute by adding translations, see [here](localization/README.md).
## Commit Message Guidelines
Automating releases and change log generation require following very **precise rules** over how the git commit messages can be formatted.
Which is why this project follows [conventional commits](https://www.conventionalcommits.org/) ["Angular"](https://github.com/conventional-changelog/conventional-changelog/tree/master/packages/conventional-changelog-angular) conventions.
And furthermore, following these conventions also leads to **more readable messages** that are easy to follow when looking through the **project history**.
### 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**:
```text
():