# Contributor manual / FAQ We are happy that you are considering contribution to GoodData.UI SDK. Before proceeding, please familiarize yourself with the technical aspects of the contribution. This document gives overview how to build and test the SDK and perform other typical tasks related to contributing. > :warning: Although pull-requests can be created for this repository, > the changes need to be delivered via the `gdc-ui` main repository. ## Environment Requirements The development process is tested on macOS and Linux and uses bash for some of the scripting. This means that some parts of the development process will not work on Windows. You can use [Windows Subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl/install-win10) but note that this mode of development is not tested and not supported by our teams. ## Getting started 1. Install [nvm](https://github.com/nvm-sh/nvm) ```bash curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.2/install.sh | bash ``` 2. Clone and bootstrap ```bash git clone git@github.com:gooddata/gooddata-ui-sdk.git cd gooddata-ui-sdk nvm install nvm use npm i -g @microsoft/rush rush install ``` 3. Build ```bash rush build ``` 4. Read the rest of this guide and also the [developer guide](./sdk-dev.md). **HINT**: The repository includes the `.envrc` configuration file for [direnv](https://direnv.net/); you can use this to auto-nvm-use the correct node.js installation every time you enter the `gooddata-ui-sdk` directory. ## After you pull latest changes Always run `rush install`; this will make sure all the dependencies from the lock file will be installed in all the projects managed in the repository. After that run `rush build`. In case the pull brings in new projects or large bulk of changes, it is safer (albeit more time-consuming) to run `rush clean && rush purge && rush install && rush rebuild`. ## IDE Settings Please check out [How to setup IntelliJ](setupIntellij.md) guide to find out about recommended settings for IntelliJ IDEA or [How to setup VS Code](setupVsCode.md) guide to find out about recommended settings for VS Code. ## Rush primer Rush is an opinionated monorepo management tool that comes with batteries included. We strongly encourage you to read the [official documentation](https://rushjs.io/pages/intro/welcome/). Long story short, here are facts and commands you need to know: - lock file (shrinkwrap file) is stored in pnpm-lock.yaml. - Rush maintains internal registry of packages in common/temp; all package dependencies are symlinked; projects within the monorepo are also symlinked. - the [common](common) directory contains Rush and project configuration including: - [lockfile](common/config/rush/pnpm-lock.yaml) - [git hooks scripts](common/git-hooks) which will be automatically installed by Rush - [custom scripts](common/scripts) that can be integrated into - `rush install` - installs dependencies according to the lock file. - `rush update` - conservatively install dependencies describes in package.json files, update lockfile. This will only install / update dependencies that you have modified. - `rush update --full` - install and update all dependencies according to the semver, update lockfile. This is a more aggressive mode in which Rush will install and use latest applicable versions of packages, possibly resulting in a massive change to the lockfile. There is no need to run this as part of typical feature development. - `rush build` - builds all the projects' ESM and CommonJS builds, in the right order, possibly skipping those that have no changes since the last build. - `rush link` and `rush link --force` - builds or rebuilds symlinks between projects in the repository. This is typically not needed as Rush will re-link during update. Use in case you encounter strange dependency errors during build. - `rush add` - adds a new dependency to a project. **IMPORTANT**: When `rush` runs builds in the projects it will truncate the project's build outputs when emitting to console. It will, however, store full build output into each project's directory. It will create files `.build.log` and this will contain the full build output. > Note: Rush by default tries to use all cores available on the machine. It is possible to override this using > the `--parallelism` option on the CLI or using the `RUSH_PARALLELISM` environment variable. ### Bulk projects commands On top of Rush built-in commands, we have added our own custom commands (see [command-line.json](common/config/rush/command-line.json)): | Command | Description | | ------------------- | --------------------------------------------------------------------------------------- | | `rush audit` | Performs security audit of all packages listed in global lock file | | `rush purge` | Delete all installed npm modules, clean temp and node_modules directories | | `rush clean` | Cleans up artifacts created by build and tests. Full 'rebuild' required after cleaning. | | `rush validate` | Validates code in all projects. | | `rush test-once` | Tests code in all projects. | | `rush dep-cruiser` | Runs dependency-cruiser in all projects. | | `rush format-check` | Verifies code formatting in all projects. | | `rush format-write` | Formats code in all projects. | | `rush populate-ref` | Makes projects populate reference workspace with recording definitions. | ## How do I...? This section should answer most of the contribution questions for the practical side of things. ### How do I add new / update existing dependency in a project? You must use Rush to add a new dependency to a project and use the `make-consistent` parameter. This parameter will make Rush update all other projects that already use the package to also use the desired version. Navigate to the subproject and invoke: ```bash rush add -p @^ --make-consistent ``` to add a new production dependency. Add the `--dev` flag to add the package as dev dependency instead. With rare exceptions such as typescript package, all our dependencies use caret. Dependencies must be kept consistent across subprojects. > Note: **never** add new packages by running package manager directly (e.g. `yarn add ...`). > This will break the node_modules. After adding new dependency run `rush update` to approve new package. ### How do I remove dependencies from a project? Remove the dependencies from package.json and then run `rush update`. ### How do I build stuff? To build everything, run `rush build`; this will trigger parallel execution of build scripts defined in each subproject's `package.json`, starting them in the correct order - honoring the inter-package dependencies. Rush build is incremental and will only build projects which have changed since the last build. This is safe and preferred way to build. In rare cases such as large refactors or refactors of SCSS styles you should perform clean & rebuild: `rush clean && rush rebuild` To build a single subproject with its dependencies: ```bash rush build -t @gooddata/sdk-ui ``` If you want to build _just_ single subproject, you can navigate to the subproject directory and invoke build using `rushx`: ```bash rushx build ``` > Hint: starting package.json **scripts** using npm/yarn/pnpm also works and there is nothing wrong with it. > Hint: if you find that the `rush build` makes your system unresponsive, you can try tweaking (lowering) the parallelism, > either by using the `-p` parameter of `rush build`, or by setting the `RUSH_PARALLELISM` environment variable. ### What should the commits look like? Commits should follow the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) specification. Following format and rules are enforced by CI checks. Example: ``` feat(sdk-model): clarify attribute area sort - the attribute sort aggregation switches the attribute sort into area sort - having a 'flag' or 'aggregation' on a newAttributeSort factory seemed confusing while I tried to explain this in docs - it is more clear if the area sort has separate factory - even if it creates the same type. - but this way, the intent is cleaner - also, the aggregation: boolean was not good, this is indeed a function that may one day support more risk: low JIRA: RAIL-2175 ``` Commit message structure: ``` ():