Skip to content

Contributing Guide

maledr5 edited this page Dec 6, 2024 · 14 revisions

This documentation will guide you through the basics of contributing to the PIE monorepo.

  1. Prerequisites
  2. Local Development
  3. Testing
  4. Turborepo
  5. Versioning / Publishing Packages
  6. Example apps
  7. Helpful Links

Prerequisites

Required on your Machine:

The following things should be installed on your machine in order to run projects within the repo:

  1. git-secrets Install following the instructions.

  2. Volta Install following the instructions. This will ensure you have the correct versions of Node and Yarn installed. We have pinned versions for both Node and Yarn using Volta in each of our packages inside the repo. This means that when running node --version or yarn --version inside a package in the repo, the result should match the one present in the closest package.json file. Most of which extend the root package.json file.

  3. Yarn >= 2 - Using Volta should take care of this for you.

  4. Node 18+ - Using Volta should take care of this for you.

  5. Environment variables

    • TURBO_TOKEN: you will need this token to properly run Turborepo commands and enable remote caching. Please reach out to the design system team for the value of this token.

    • PERCY_TOKEN_{COMPONENT}: you will need these tokens to run visual regression tests locally. Please reach out to the design system team for the values of these tokens. An example could be PERCY_TOKEN_PIE_BUTTON or PERCY_TOKEN_PIE_DOCS.

    • How you add these will depend on your operating system. For example, on Mac they could be added to a .zshrc or .zshenv file.

    • Examples of adding these environment variables:

      • via bash (e.g. .zshrc):
        export PERCY_TOKEN_{COMPONENT}=abcde # e.g PERCY_TOKEN_PIE_BUTTON=abcde or PERCY_TOKEN_PIE_CARD=abcde
      • via package.json:
        # Under scripts `test:visual` replace the environment variable like so:
        PERCY_TOKEN_{COMPONENT}=abcde # e.g PERCY_TOKEN_PIE_BUTTON=abcde

Local Development

Note: the following commands should be run from the root of the monorepo:

To install all project dependencies:

yarn

To run a project (note: dev has no effect on individual components as we run Storybook to serve them):

yarn dev --filter=PROJECT_NAME # e.g. yarn dev --filter=pie-storybook

The filter is needed to ensure not all projects are run in dev mode simultaneously. The PROJECT_NAME can be found from the value of the name key inside a projects' package.json.

Building Web Components

For a more in detail guide on how to develop a new component, please follow this README.

Running Web Components

Web components are served via Storybook, all at once:

# remember to run this from the root of the monorepo
yarn dev --filter=pie-storybook

To build a web component package, run the following commands with the component of your choosing.

# remember to run this from the root of the monorepo
yarn build --filter={component} # e.g. yarn build --filter=pie-button

If you'd like Storybook to refresh with your component changes as you alter code, then you should build the component in watch mode:

# remember to run this from the root of the monorepo
yarn watch --filter=pie-{component} # e.g. yarn watch --filter=pie-button

Then run storybook in a separate terminal tab:

# (in a separate terminal/tab)
# remember to run this from the root of the monorepo
yarn dev --filter=pie-storybook

Sometimes you may need to run without hitting a cache. To do this, add --force to the end of your command:

# remember to run this from the root of the monorepo
yarn build --filter={component} --force # e.g. yarn build --filter=pie-button --force

Testing

PIE Docs

Please see the pie-docs README.md for information on testing the documentation site:

Web Components

To test Web Components, please run the following commands from the root of the monorepo:

Browser tests

We use Playwright via npx, so you may need to set up your npx dependencies by running npx playwright install

To run the browser tests:

# remember to run this from the root of the monorepo
yarn test:browsers --filter={component} # e.g. yarn test:browsers --filter=pie-button

Visual tests

To run the visual regression tests:

# remember to run this from the root of the monorepo
yarn test:visual --filter={component} # e.g yarn test:visual --filter=pie-button

Note: To run these locally, you will need to ensure that any environment variables required are set up on your machine (as mentioned in the prerequisites section above). Otherwise, you will encounter unbound variable errors.

Turborepo

Turborepo is an intelligent build system optimized for JavaScript and TypeScript codebases. We use Turborepo to facilitate the execution of all our build scripts within the PIE monorepo.Turborepo allows us to achieve a number of things as part of our development process.

Ensuring build-tasks are executed in the correct order

By allowing Turborepo to handle the execution of our build-tasks, it means that maintainers and contributors can focus on their work, rather than spending time trying to bootstrap the repo. Turborepo means that as an engineer working in the repo, you don't need to know the execution order of build tasks, making the repo simpler to work in.

Build task caching

Certain build-tasks defined in the turbo.json have the cache: true property defined.

With this setting enabled, Turborepo intelligently caches the console output and any files defined in the outputs array, and uploads these to our AWS Remote Cache Server.

With this functionality, we lets Turborepo determine when build-tasks need to be executed, allowing us to speed up local-development time, and reduce our CI duration.

Remote Caching Troubleshooting

One of the things to bear in mind with remote caching, is that by default, Turborepo will invalidate the cache if any file changes in the workspace you have updated (provided it's not in .gitignore).

Because of this, if for whatever reason you need to provide the inputs property to further finetune when cache is invalidated, we recommended reading the Turborepo documentation for best practice.

By providing inputs, you opt-out of the default behaviour, which can result in your cache not invalidating when it should, which can cause issues that don't get picked up as part of CI. Reference.

Remote Caching in AWS S3

In order to speed up local development / CI workflows, we use Turborepo's remote caching functionality to publish build artifacts to AWS S3. This ensures that only modified packages have their build tasks executed.

In order to take advantage of this functionality, you must set the TURBO_TOKEN environment variable on your local machine (as outlined in our prerequisites section above). Please reach out to the design system team for the value of this token.

Once enabled you'll see 'Remote caching enabled' when executing a packages node task.

Running project-level commands that rely on root-level dependencies

If you have a project-level command, such as yarn lint:style within the pie-docs project, you will see that it has run -T in front of the stylelint command.

This is because stylelint is a root-level dependency (so it can be shared across monorepo projects). The problem is that if you cd into /apps/pie-docs and run the command, you will get a command not found error because stylelint does not exist at the project level.

Using the run -T expression will tell yarn to look in the root of the repository for that dependency.

Example:

"lint:style": "run -T stylelint ./src/**/*.{css,scss}"

Yarn docs reference for this

Versioning / Publishing Packages

If you are contributing a user-facing or noteworthy change to a pie-monorepo package that should be added to the changelog, you should include a changeset with your PR.

Changesets are only required for Major, Minor, and Patch changes that have an effect on consumers. Changes that don't affect consumers do not need to be versioned. Examples include linting, testing or CI updates.

To add a changeset, run this script locally in the root of the project:

yarn changeset

Follow the prompts to select which package(s) are affected by your change, and whether the change is a major, minor or patch change. This will create a file in the .changesets directory at the root of the monorepo. This change should be committed and included with your PR.

Considerations:

  • When writing your Changesets message, be sure to prefix your message with one of the following: [Added], [Changed], [Fixed] or [Removed].
  • E.g. [Added] - My new webpage.
  • You can use markdown in your changeset to include code examples, headings, and more. However, please use plain text for the first line of your changeset. The formatting of the GitHub release notes does not support headings as the first line of the changeset.
  • When selecting packages for the changesets, only select packages which are intended to be published.

Stable Versions - 'latest' tag

If your change is intended to be released under the latest tag on npm, you must follow this workflow:

  • Create a branch with your changes. These changes should exclude any package.json or manual CHANGELOG updates – only include the .changesets changes added by Changesets.
  • When you create your PR, target the main branch.
  • Upon merging to main, a new PR titled release: release Packages is automatically created. This PR includes the CHANGELOG.md and package.json version bump. Merging this PR will commit these changes to main and execute a publish to npm under the latest tag.

Beta Versions - 'beta' tag

A Beta release is a release that contains experimental changes. These are ready for early adoption and testing by consumers but may introduce bugs (or be considered work-in-progress).

Feature versions - 'next' tag

A Feature release is for larger changes that may require multiple PRs, across several packages, before it is released. These changes are unstable and are not intended to be used by consumers. Typically, these releases will be used for testing changes in consuming applications as an alternative to using something like yalc.

If your change is intended to be released under the next / beta tag on npm, you must follow this workflow:

  • Create a new branch with the feature-* / beta-* prefix, and push this to the remote. E.g. git push origin feature-myawesomework.
  • Create another branch, off this initial feature/beta branch, to implement your code changes. Ensure that this branch does not use a prefix.
  • When you create your PR, target the feature-* / beta-* branch.
  • Upon merging to your feature-* / beta-* branch, a new PR titled release: release Packages (beta) / release: release Packages (next) is automatically created. This PR includes the CHANGELOG.md and package.json version bump. Merging this PR will execute a publish to npm using the appropriate tag.

Notes: Any new PRs that target the feature-* / beta-* branch will cause GitHub actions to include the changes as part of that beta/feature release. Any package that uses the beta / next tag must follow this workflow until it's ready to be promoted to the latest tag (see Stable Versions section). PRs that combine changes in latest and beta / next packages will result in the beta / next package being versioned incorrectly.

Promoting to stable

When you're happy your next / beta tagged package is ready to be promoted to a latest release, you must use the following workflow.

  • Create a PR to merge the feature-* / beta-* into main.
  • Upon merging to main, a new PR titled release: release Packages is automatically created. This PR includes the CHANGELOG.md and package.json version bump. Merging this PR will commit these changes to main and execute a publish to npm.

Example apps

Whilst our monorepo supports multiple versions of node, there are specific example applications that are intended to be used with specific versions of node. For example our Nuxt 2 app should be used with Node 16.

This is why it is important to ensure you have Volta installed as explained in our prerequisites. This will ensure you have the correct version of Node and Yarn installed for each app.

If you do not have Volta installed and are running an incorrect version of node, running commands such as yarn build:examples or build:examples --filter=wc-nuxt2 will fail.

Helpful Links and resources

Yarn 2

Commitizen, Commitlint & Conventional Commits

Please read up on our Git conventions to understand how we use these tools.

Turborepo

Clone this wiki locally