Skip to content

Contributing Guide

Ben Siggery edited this page Jan 23, 2024 · 6 revisions

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

  1. Prerequisites
  2. Installing Yarn
  3. Local Development
  4. Testing
  5. Remote Caching in AWS S3
  6. Running project-level commands that rely on root-level dependencies
  7. Versioning / Publishing Packages
  8. Example apps
  9. Helpful Links

Required on your Machine:

  1. git-secrets: Install following instructions here
  2. Volta: Install following instructions: https://docs.volta.sh/guide/getting-started
  3. Yarn 2+ (see below)
  4. NodeJS 16.x

We have pinned versions for both Node and Yarn using Volta. This means that when running node --version or yarn --version inside the repo, the result should match the one present in the root package.json.

Installing Yarn >= 2

  • Open a terminal OUTSIDE of the project folder
  • Make sure node >=16.10.0 (at time of test 16.51.1 was the latest and worked)
  • Make sure yarn >=1.22 is installed
  • run "corepack enable"
  • run "yarn -v"
  • It should >=1.22

  • Open a terminal INSIDE of the project folder
  • run "yarn set version stable"
  • run "yarn -v"
  • should be >= 2.0.0 (at time of test v3.2.1 was the ref. in this project)

Local Development

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

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

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.

Running Web Components

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

yarn build --filter={component} # e.g. yarn build --filter=pie-button

If you'd like to develop using the component storybook, then you should build the component in watch mode, and run storybook in a separate terminal tab:

yarn watch --filter=pie-{component} # e.g. yarn watch --filter=pie-button

# in a separate terminal tab, run
yarn dev --filter=pie-storybook

Testing

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

To run the browser tests:

yarn test:browsers --filter={component} # e.g. yarn test:browsers --filter=pie-button

Visual tests

To run the visual regression tests:

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 to mirror those on CI (such as Percy tokens). How you achieve this will differ between operating systems.

Setup via bash

export PERCY_TOKEN_{COMPONENT}=abcde # e.g PERCY_TOKEN_PIE_BUTTON=abcde or PERCY_TOKEN_PIE_CARD_CONTAINER=abcde

Setup via package.json

Under scripts test:visual replace the environment variable with the below:

PERCY_TOKEN_{COMPONENT}=abcde

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. 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 means if you ran the command yarn build:examples or build:examples --filter=wc-nuxt2, ensure you are using Node 16 or you'll see it fail.

To see our supported Node versions for each example application, please refer to the engines section of the example application you wish to build.

Helpful Links

Yarn2

Commitizen, Commitlint & Conventional Commits

We use commitizen in combination with commitlint to ensure commit messages in the PIE monorepo conform with the Conventional Commits specification. Having a standardised format ensures commit messages are more descriptive, and provide context to contributors working in the codebase.

We recommend when commiting new changes to the codebase, you use yarn cz and not git commit -m.

The former will present commitizen's interactive prompt to ensure it conforms to our commitlint ruleset.

While you can still use git commit -m, it is up to you to manually ensure your commit message conforms with our commitlint ruleset.

Pull Request Title

When creating a pull request, please ensure the title conforms to the conventional commit standard. For example, a fix to pie-docs should have a title such as:

fix(pie-docs): fixed a bug with navigation

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.

Ensure 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. - https://turbo.build/repo/docs/core-concepts/caching/file-inputs#customizing-the-behavior

Clone this wiki locally