Simple CLI for monorepo/multipackage.
sui-mono
is a tool that aims to simplify management for monorepo/multipackage projects (sui
for example) but it also works with monopackage projects.
sui-mono
provides:
- Commit template →
sui-mono commit
- Release manager (parses commits to publish packages according to their changes) →
sui-mono check
,sui-mono release
- Run commands inside each package →
sui-mono run npm install
,sui-mono run-parallel npm install
We use:
- ComVer as our versioning system
- Commit Message Conventions as our standard for commit messages
sui-mono
provides, among other things, a standard template for commit messages (sui-mono commit
) and is able to decide what needs to be released for you (sui-mono check
& sui-mono release
).
$ npm install @s-ui/mono --save-dev
You can run a single command on each package of the monorepo (each subfolder with its own package.json
), in series
$ sui-mono run <command>
$ sui-mono run npx rimraf node_modules
$ sui-mono run npm install
You can also run them in parallel
$ sui-mono run-parallel <command>
$ sui-mono run-parallel npx rimraf node_modules
$ sui-mono run-parallel npm install
To reset your project and all its contained packages.
sui-mono phoenix
Equivalent to npx rimraf node_modules && npm i
but it works on any environment and sui-mono phoenix
executes it concurrently on each package (and/or on your project root folder).
By default commands will be executed on chunks of 20 packages, but you can change it with -c, --chunk
option:
sui-mono phoenix -c 5
So, if executing many commands as the same time in your machine is too heavy, you can adjust it. You can also disable the chunks with 0 value and always execute all commands in parallel:
sui-mono phoenix -c 0
If you don't want a fancy progress output (for instance in CI env), you can force a plain text output:
sui-mono phoenix --no-progress
Reinstalls all scope packages but ignores the node_modules
folder and package-lock.json
file at the root level of your project
sui-mono phoenix --no-root
Ables you to just reinstall the dependencies from a single scope
sui-mono phoenix --no-root --scope atom/button
You do your normal git workflow, but when commiting you should use:
sui-mono commit
It will prompt you with questions regarding your changes and will generate a standard commit message for you
You can commit the same message for all packages that actually contained stageable files.
sui-mono commit-all -t "feat" -m "Refactor of dependencies"
The precommit will be executed only for the first commit.
In order to release the steps are:
Preview what will be released
sui-mono check
Release all the packages
sui-mono release
In case you want to release a single package use the --scope
param
sui-mono release --scope "packages/sui-test"
Your packages could use a
prepublish
script that will be executed before any release.
👉
sui-mono
creates a newMINOR
version for the package only whenfix
,perf
orfeat
commits are detected, and a newMAJOR
version if there is some commit marked asBREAKING CHANGES
. Otherwise (any other types of commits detected), no new version will be generated and nothing will be released
Automatic release (only CI)
In case you want to release via CI the --github-user
--github-email
and --github-token
must be passed by like follows:
sui-mono release --github-user [username] --github-email [user email] --github-token [TOKEN]
If you want the package-lock.json
to be committed once the packages are released, use the --lock flag.
sui-mono release --lock
First you need to install the @s-ui/mono
package in your project
npm i --save-dev @s-ui/mono
Then, you can configure your package.json
to suit your needs
sui-mono
allows you to configure some parts of its functioning, but it also defines a few defaults for convenience.
Here's a full example of the options:
"private": true,
"workspaces": ["components/**"],
"config": {
"sui-mono": {
"access": "public",
"overrides": {
"literals": [{
"regex": "Lokalise:"
}]
}
},
"validate-commit-msg": {
"types": "@s-ui/mono/src/types"
},
}
If you specify that your package is private ("private": true,
), it will be ignored by @s-ui/mono releases and thus it won't get pushed to the npm repository.
By default packages will be published as restricted
in npm. If you want them to be public you will need to set "access": "public"
. It is possible to set the access property by package, for example:
Root
├── Package A - Access set to "public"
├── Package B - Access set to "restricted"
└── Package C - No access prop set
- Package A will always be released as "public" no matter Root's value
- Package B will always be released as "restricted" no matter Root's value
- Package C will be released as "public" or "restricted" depending on the Root's value, if not set there either, it will be released as "restricted"
👉 Setting the proper scope in the commit message is important, because this is used for
sui-mono check
andsui-mono release
to assign changes to specific packages and release them to the proper packages
Workspaces is a generic term that refers to the set of features that provides support to managing multiple packages from your local files system from within a singular top-level, root package.
These workspaces
are defined in the root package.json
of the project and uses glob pattern. The pattern will search all the folders with a valid package.json
file and not inside a node_modules
folder in order to get all the available scopes.
This information will be used for releases and commitizen
scopes.
There are some cases when the commit message is automatically generated by a third-party (e.g. Lokalise). For this kind of case the overrides
field could be used.
"overrides": {
"literals": [{
"regex": "Lokalise:"
}, {
"regex": "Update lokalise"
}],
"domain": [{
"regex": "Tracker"
}]
}
The overrides field takes an object of scopes, where each scope can have a collection of regular expressions defined under the literals key. When the commit header matches any of the specified regexes, a minor package update will be performed.
This feature grants you the flexibility to seamlessly manage automatic commit messages from external sources, maintaining versioning accuracy.
So, if you have a project like this:
src/
i18n/
users/
search/
...
You will have to add the next config on workspaces
in your package.json
root file:
{
"workspaces": ["src/**"]
}
This will give you a list of scopes like this one for your commit:
```text
src/i18n
src/users
src/search
In the case of sui-studio
, which generates a folder like this one:
components/
ads/
big/
small/
card/
featured/
normal/
If you set the configuration of your project like this:
"workspaces": ["components/**"]
You will have a list of scopes like this one when performing a commit:
components/ads/big
components/ads/small
components/card/featured
components/card/normal
There may be cases that you may want to add scopes for informative purposes but not related in any way with the releases
Take in care that this scopes will not be relevant for the release, and if you commit to one package that has his own scope, but you use a custom scope, a release will not be generated. Custom scopes are for a very rare cases and you may not need it most of the times.
Use customScopes
in this cases like in the example. The scopes will be added to the automatically generated ones.
You should use workspaces
based on npm
and yarn
native config instead.
Before:
{
"config": {
"sui-mono": {
"packagesFolder": "components",
"deepLevel": 2
}
}
}
After:
{
"workspaces": ["components/**"]
}
Instead, you should rely on using prepublish
script