# Contributing

## Prerequisite

- Node 20.11+
- npm 10.2+
- Chrome or Chromium
- G++
- The variable `CHROMIUM_BIN` set in your environment

If you're using bashrc.dev.pee, the variable `CHROMIUM_BIN` is already set to `~/slave-apps/chromium-headless-64/chrome`

If not, you can set the variable in your `.bashrc` or `.zshrc`:

```bash
export CHROMIUM_BIN=/usr/bin/google-chrome-stable
```

## Developing using the Dev Tool

Since version `8`, `prestations-ng` has a standalone application that allows
developers to test their fixes/new features without integrating the library
in an actual prestation: the Dev Tool.

To start the Dev Tool, run `npm start`. This will ensure that modifications
in both the Dev Tool and the library reload the page.

## Testing the library in integration

Since version `8`, we can't use native symlink to integrate `prestations-ng` to
a prestation such as Skeleton. We can however use `npm link` to achieve the same
result.

### In **prestations-ng**

- if it is the first time, execute `npm install` then `npm run build:lib` (at root level)
- `cd dist/prestations-ng && yarn link` (it's critical to link the content of `dist/prestations-ng`, not the root)
- `cd ../.. && npm run build:lib:dev` (at root level)

`build:lib:dev` will use a feature of the Angular CLI: `--watch`. For more information on `--watch`, refer to the [official documentation](https://github.com/angular/angular-cli/blob/master/docs/documentation/stories/create-library.md#why-do-i-need-to-build-the-library-everytime-i-make-changes).

### In the prestation

- `cd front`
- `yarn link @dsivd/prestations-ng`
- `npm start` (only when `npm run build:lib:dev` in `prestations-ng` has started)

Now if you change something in `prestations-ng`, the CLI of the prestation will hot swap the missing pieces and reload the page.

Finally, when you're done, run `yarn unlink @dsivd/prestations-ng` to unlink the local version. You will need to run `npm install --force` to re-install the package that was linked.

**NB: When the project uses a version 12+ or 13+ of the library, you need to use `yarn start:symlink` and checkout the library tag matching v12+ or v13+. More information on [UPGRADING_V12](UPGRADING_V12.md)**

## Upgrade Foehn

To upgrade the Foehn peer dependency, please follow [Foehn Changelog](http://dsi-vd.github.io/foehn/docs/changelog).

The dependency targets a specific version as upgrading this peer dependency might require modifications
of `prestations-ng`.

## Adding a schematic

### Tips

- Add logic into `utility` folder so you can reuse them in `ng-add` and `ng-update`.
- Create a proper schematic such as [update-karma-config](projects/prestations-ng/schematics/update-karma-config/index.ts) to be able to test it into a project when the library is linked.

### Testing

run `npm run test:schematics` (at root level).

### Testing into a project such as **skeleton**

- **In prestations-ng**:

    - if it is the first time, execute `npm install` then `npm run build:lib` (at root level)
    - `cd dist/prestations-ng && npm link` (it's critical to link the content of `dist/prestations-ng`, not the root)
    - `npm run build:lib:dev` (at root level)

- **In project**:
    - `cd front`
    - `npm link @dsivd/prestations-ng` (`npm unlink @dsivd/prestations-ng` to remove link)
    - `ng g @dsivd/prestations-ng:[YOUR_SCHEMATIC]` (i.e. `ng g @dsivd/prestations-ng:ng-add` or `ng g @dsivd/prestations-ng:update-karma-config` or `ng g @dsivd/prestations-ng:replace-browsers-list`)

In your project, you can test any schematic added into [collection.json](projects/prestations-ng/schematics/collection.json).
If you want to test `ng-update`, you will need to release the library under a beta version and then update your version of prestations-ng.

**NB: Do not forget to add your utility into ng-add and ng-update schematics**

## Adding a module

In case you're adding or modifying a `*.module.ts`, please update [MODULES.md](MODULES.md).

## Adding an icon

- Create a `.ts` and `.html` similar to `foehn-icon-lock.component`, and replace the name of the icon accordingly
- Add a `title` for accessibility
- Import and export the new `*.component.ts` in [foehn-icons.module.ts](projects/prestations-ng/src/foehn-icons/foehn-icons.module.ts)

## Notes about linting, formatting and pre-commit hooks

This project uses a set of scripts to lint and format the code, along with pre-commit hooks.

Important scripts are :

- `npm run lint` : run ESLint and Prettier on all files
- `npm run format`: run ESLint and Prettier on all files and fix errors automatically
- `npm run validate`: clean and run all tests

**Husky** is used as a pre-commit hook to automatically output linting and formatting errors for staged files before committing.
In the end, this utilitary calls `npm run lint-staged` which you can also call yourself of course. To have this pre-commit hook,
run `npm run huskyInstall`. When you commit, Husky will run and show you potential errors. If you commit from Intellij, make sure you
use the correct node version in the settings, otherwise it might fail. Same thing applies if you commit from terminal (run `which node`).

## Before committing

- **Make sure you have installed pre commit hook by running :** `npm run huskyInstall`
- Remove unnecessary `console.log`
- Update [CHANGELOG.md](CHANGELOG.md)
- Have it up to date with `npm install`
- If you want to autofix lint/format errors in your code : `npm run format`
- Run all tests `npm run validate`
- Ensure the commit message contains a Jira reference

> On commit, Husky will run ESLint and Prettier on all changed files. If you still want to run both on all files, please read the sections above.

## Prettier & ESLINT

The project uses [Prettier](https://prettier.io/) to auto-format the code. To lint, this project use [ESLint](eslint.org) (see `angular.json`).

You can auto-format the code on save with IntelliJ. More informations
[on this guide](https://prettier.io/docs/en/webstorm.html).

Please make sure you have followed the **Before committing** section so you will see formating/linting errors before you commit.

## Publishing a new version of the package

Please use the dedicated Jenkins build:

[https://validation.portail.etat-de-vaud.ch/outils/jenkinsdgnsi/view/METIMT/job/AAC_Release_Prestakit/](https://validation.portail.etat-de-vaud.ch/outils/jenkinsdgnsi/view/METIMT/job/AAC_Release_Prestakit/)

**Then**

- Choose [Lancer un build avec des paramètres](https://validation.portail.etat-de-vaud.ch/outils/jenkinsdgnsi/view/METIMT/job/AAC_Release_Prestakit//build?delay=0sec) in the left menu
- Uncheck **RELEASE_BE** and check **RELEASE_NG** (if not already checked)
- Choose **origin/master** as **SOURCE_BRANCHE**
- Add version number in **TARGET_VERSION** (i.e.: 1.2.3) but before check in tags list if your version doesn't already exist
- Nothing in **NEXT_VERSION**
- Choose **STABLE** in **NPM_TAG** when certain that your release is stable otherwise choose **NEXT** which will publish a **v1.2.3-BETA** on NPM
- Check **RUN_TEST** if you wish to validate the library's test (can take a while)

Alternatively, you can manually publish the package. Although this method is not recommended.

- Ensure you can push to the npm registry: `npm adduser --registry=https://registry.npmjs.org --scope=@dsivd`
- Update the version number in `package.json` either manually or with `npm version`
- Commit and tag the version change
- Package a new version of the library with `npm package`
- Publish the package:
    - `npm run publish:stable` for stable version (released to everybody)
    - `npm run publish:next` for next version (development only)

## Maintaining branches (LTS)

Because we might have fixes to do on previous releases (for instance the current version is `v11` but there's a bug that
needs to be fixed on the `v10` version because a prestation cannot afford to migrate strait away), we can apply the following
process to add and forward-port fixes to a specific version.

Let's assume we want to add a fix in the version `v10.16.10`.

**If `release/v10` doesn't exist**

- Checkout the latest `v10` tag of the version to fix: `git checkout tags/v10.xx.xx -b release/v10` (replace xx.xx by the latest version)
- Push the branch directly to the remote : `git push origin release/v10:release/v10`

**Then**

- Checkout the target release branch: `git checkout origin/release/v10 -b release/v10`
- Create a new local branch for your fix: `git checkout -b My_Fix_Branch`
- Develop and test your fix, then commit it
- Push your local branch to a remote branch: `git push origin My_Fix_Branch:bugfix/My_Fix_Branch`
- Create a pull request from `bugfix/My_Fix_Branch` to `release/v10`
- Merge the pull request
- Then go on [Jenkins](https://validation.portail.etat-de-vaud.ch/outils/jenkins-pee/job/AAC_Release_Prestakit/) for appropriated build
- Choose [Lancer un build avec des paramètres](https://validation.portail.etat-de-vaud.ch/outils/jenkins-pee/job/AAC_Release_Prestakit/build?delay=0sec) in the left menu
- Uncheck **RELEASE_BE** and check **RELEASE_NG** (if not already checked)
- Choose **origin/release/v10** as **SOURCE_BRANCHE**
- Add version number in **TARGET_VERSION** (i.e.: 10.16.11) but before check in tags list if your version doesn't already exist
- Nothing in **NEXT_VERSION**
- Choose **LTS** in **NPM_TAG**
- Check **RUN_TEST** if you wish to validate the library's test (can take a while)
- Merge `release/v10` to `master` so we won't loose this fix
- Release `master` as per README.md instructions

## Improving Compilation Performance

You should be able to improve the Angular compilation time by increasing the
memory allocated to Node.

Add this export in your `.bashrc` or `.zshrc`.

```bash
export NODE_OPTIONS=--max_old_space_size=4096
```

Use at your own risks.

## E2E testing

`Protractor` is no longer included in new Angular projects as of Angular 12.
We have decided to remove it from `prestations-ng` and use instead `Cypress`.

For more informations, please visit :
https://github.com/angular/protractor/issues/5502
https://docs.cypress.io/guides/migrating-to-cypress/protractor#Introduction

**DO NOT FORGET TO BUILD THE LIBRARY BEFORE RUNNING E2E TESTS**

### Running e2e in headless mode

When launching Cypress in headless mode, execute:

```bash
npm run e2e
```

When a test fails, a screenshot will be added in `cypress/e2e/screenshots` folder.

### Running e2e using Cypress visual interface

When launching Cypress visual interface for running tests files individually in `watch` mode, execute:

```bash
npm run e2e:open
```

To execute a test, just click on your integration test file listed in the newly open window.
A new window will open showing your e2e test execution.
To show back your test list window, just click on `Tests` button in the top left corner.
Click the `Stop` button to close your e2e test execution window.
Then click on an other test in the list and so on...
