Lets Lerna monorepos fully utilize CircleCI features like parallelism and splitting tasks by timings.
- Automatically splits relevant Lerna commands across parallel machines
- Supported commands:
run,exec,list,changed
- Supported commands:
- Allows splitting tasks based on timing history from previous runs
- Works for any type of task, not just tests (unlike CircleCI's own CLI)
CircleCI's parallelism feature is great for splitting up heavy tasks across machines, which seems like a great fit for a
Lerna monorepo with multiple projects. However, there is no easy way to split the projects across nodes while still working with Lerna
options like --include-dependents, --include-dependencies, filters or other options that affect which projects are selected by Lerna's
commands.
There is also no convenient way to use CircleCI's test splitting features since tests (or other tasks) are split across multiple projects with different needs and configurations.
lerna-circleci means to make these features work just as well for a Lerna monorepo as any other repo 👍
It's recommended to install lerna-circleci in the root of your monorepo, together with Lerna.
# npm
npm install lerna lerna-circleci --save-dev
# pnpm
pnpm add lerna lerna-circleci --save-dev
# yarn
yarn add lerna lerna-circleci --devlerna-circleci can be used as a drop-in replacement for the commands listed under Commands.
It can be used outside of CircleCI, but will just act like regular Lerna if no the expected CircleCI environment variables are not found and no override options are passed. See the API for more information.
Simply replace lerna with lerna-circleci inside your parallel jobs:
# .circleci/config.yml
jobs:
test:
parallelism: 5
steps:
- lerna-circleci run testWith the --split-by-timings option, projects will be split between nodes based on previous timings in order to reduce the total time
spent. If no timings history is found then the projects will just be split up evenly.
To store timing data between runs you need to pass --report to the run or exec command you want to store timings from. Then add a
store_test_results step to your CircleCI config in order to persist the timings between runs.
# .circleci/config.yml
jobs:
test:
parallelism: 5
steps:
# The two commands will be split based on the same data since they use the same ID
- lerna circleci list --id=testId --split-by-timings
- lerna-circleci exec --id=testId --split-by-timings --report -- exampleExec.sh
- store_test_results:
path: logs/lerna-circleci/testId/results.xml lerna-circleci run script [options]
Be aware that Lerna's run filters projects that don't have a script with the specified name, so it might split tasks differently than
e.g. list even if they use the same ID.
Supports all of the regular lerna run options, plus:
--id | -i--split-by-timings | -t--report | -r--report-file | -f--timings-file--node-total--node-index
lerna-circleci exec [options] -- command
Supports all of the regular lerna exec options, plus:
--id | -i--split-by-timings | -t--report | -r--report-file | -f--timings-file--node-total--node-index
lerna-circleci list [options]
Supports all of the regular lerna list options, plus:
lerna-circleci changed [options]
Supports all of the regular lerna changed options, plus:
All regular Lerna commands work with the lerna-circleci commands.
Global options can be passed to any command.
String used to tag reports and package timings. The ID should only contain letters, numbers, - and _.
Required in order to make use of timings features (like --split-by-timings and --report).
Determines whether or not to split the command by timings or not.
Requires an ID to be set with --id.
Path to the CircleCI test results file. Uses the CircleCI default path by default. Should probably not be changed.
Total node count to split tasks across. Uses CircleCI's env variable by default (CIRCLE_NODE_TOTAL).Must be 1 or higher.
Current node index to run related tasks for. Uses CircleCI's env variable by default (CIRCLE_NODE_INDEX).
Must be 0 or higher, and lower than --node-total.
Compatible with: run, exec
Generates a JUnit report containing timing data for all tasks performed by the command. The report should be passed to CircleCI's
store_test_results step in order to use the results in future runs.
Requires an ID to be set with --id.
Compatible with: run, exec
Generates a JUnit report containing timing data for all tasks performed by the command. The report should be passed to CircleCI's
store_test_results step in order to use the results in future runs.
Requires an ID to be set with --id.
Lerna's --concurrency and --parallel only affects how Lerna runs command on the current machine. They can be safely used together with
lerna-circleci, though it's recommended to avoid --parallel in general.
As the name implies, lerna-circleci is tailored for CircleCI (and their parallelism features in particular). That said, it's still
possible to simulate the parallelism in most other CI providers by defining multiple jobs and using the --nodeTotal and --nodeIndex
parameters to separate split tasks between jobs in the same way.