Skip to main content

How to get changesets to use turborepo in monorepo

· 3 min read
Sanghyeon Kim

Turborepo

TL;DR

To get changesets in monorepo, use turbo --filter option.

Intro

when i started to use turborepo in monorepo, i needed to get changesets to build workspaces in CI/CD pipeline, otherwise it would take too long.

info

development environment is below.

  • pnpm: 8.13.1
  • turbo: 1.10.13
// project structure
// app1 rely on package1

example
├── apps
│ ├── app1
├── packages
│ ├── package1
├── turbo.json
├── package.json

What changesets do we need?

If app1 are changed, we need to build only app1. But if package1 are changed, we need to build packag1 and app1 because app1 rely on package1. So we need to get changesets to build the changed workspaces, as well as workspaces that depent on them.

What should we do?

i wrote a script to get changesets before use turborepo, but luckily turborepo has a option to get changesets what we need. We just use --filter option.

How to use --filter option

In the documentation, there are many sections to use --filter option, but we need to only from this section: Filter by changed workspaces --filter allows me to run build on any workspaces which have changed since a certain commit or between two commits.

# Test everything get changesets from last commit
npx turbo run test --filter=[HEAD^1]
# Test everything get changesets between 'main' and 'my-feature'
npx turbo run test --filter=[main..my-feature]

but this comand only know changesets that have changed not dependant workspaces. To get dependant workspaces that have changed, we need to use ... syntax.

# Build everything that depends on changes in branch 'my-feature'
npx turbo run build --filter=...[origin/my-feature]

What task should we run?

we know how to know changesets what we need, but what task should we run? Should we run task like build or test to get changesets? We think it's not wasteful. Whenever we run build or test, it takes a long time.

When run task, turborepo find task in each package.json if it does not exists, it will be ignored. Using this trick, we can know changesets what we need fast.

{
"$schema": "https://turbo.build/schema.json",
"pipeline": {
"changesets":{}
},
}
}

How to get changesets

npx turbo run changesets command will work based on the changeset, but we don't actually know what the changeset is. To get changesets, we need to add --dry-run=json option. With --dry-run=json option, we can get json format in stdout. stdout will be like below.

{
"id": "2egINTO3mpado71GD7K8g5h01Jr",
"version": "1",
"turboVersion": "1.10.13",
"monorepo": true,
"globalCacheInputs": {
},
"packages": [
"app1"
"package1"
],
}

Solution

npx turbo run changesets --filter=...[commit...commit] --dry-run=json command will give us changesets what we need. If you need a only changesets as list or object type, you can use jq command.