Skip to content

Commit ba7fc8b

Browse files
committed
build: add workspace versioning script
1 parent 16022ba commit ba7fc8b

File tree

3 files changed

+51
-1
lines changed

3 files changed

+51
-1
lines changed

package-lock.json

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
"build-monorepo": "cross-env-shell ./scripts/build-monorepo.sh",
1515
"prepare": "husky install",
1616
"build": "cross-env NODE_ENV=production npm run --workspaces build",
17-
"clean": "npm run --workspaces clean"
17+
"clean": "npm run --workspaces clean",
18+
"version": "cross-env-shell ./scripts/npm-version.sh"
1819
},
1920
"config": {
2021
"commitizen": {
@@ -30,6 +31,7 @@
3031
"devDependencies": {
3132
"@commitlint/cli": "17.8.1",
3233
"@commitlint/config-conventional": "17.8.1",
34+
"cross-env": "7.0.3",
3335
"husky": "8.0.3",
3436
"npm": "10.9.2",
3537
"ts-node": "10.9.2"

scripts/npm-version.sh

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#!/usr/bin/env bash
2+
3+
# `npm version 1.2.3` does the following:
4+
# 1. Update `/package.json` and `/package-lock.json` with the new version
5+
# 2. `git add package.json package-lock.json`
6+
# 3. `git commit -m 1.2.3`
7+
# 4. `git --no-replace-objects tag -m 1.2.3 v1.2.3`
8+
9+
# `npm --workspaces version 1.2.3` changes step 1 to update the version of each workspace but NOT the root.
10+
# The other steps are executed as-is: step 2 will say there's nothing to commit and the process will stop.
11+
# The version numbers in `/packages/*/package.json` will be updated but not committed.
12+
13+
# `npm --workspaces --include-workspace-root version 1.2.3` changes step 1 to update the version of each workspace AND
14+
# the root. However, the remaining steps are still unaltered. You'll end up with a commit that only updates the
15+
# workspace root, and the version numbers in `/packages/*/package.json` will be updated but not committed.
16+
17+
# Fortunately, npm runs the `version` script as part of this process. Unfortunately, the script runs after
18+
# `/package.json` and `/package-lock.json` are updated, but before `/packages/*/package.json` are updated. That
19+
# means the `--workspaces` flag isn't helping, and we need to update workspace versions ourselves. We can do that with
20+
# `npm --workspaces version --no-git-tag-version ${npm_package_version}` and then stage the files.
21+
22+
# (Props to this post: <https://blog.chlod.net/technical/easy-npm-version-synchronization-for-monorepos/>)
23+
24+
# BUT WAIT!
25+
26+
# What about `--no-git-tag-version`? The normal behavior for `npm version` in that case is to adjust version numbers
27+
# but not stage or commit anything. If this script stages `/packages/*/package.json` in that case, that's no good.
28+
29+
# The only way I've found to detect `--no-git-tag-version` is to check for the existence of an environment variable
30+
# called `npm_config_git_tag_version`. Unfortunately, it's considered "true" when the value is an empty string, so we
31+
# need to check for that as well. Big thanks to this StackOverflow answer: <https://serverfault.com/a/382740>
32+
# TL;DR: `[ -z "${npm_config_git_tag_version+set}" ]` is test we want.
33+
34+
# So, the plan is:
35+
# 1. The user should run `npm version 1.2.3`
36+
# 2. npm will update `/package.json` and `/package-lock.json` for the workspace root
37+
# 3. npm will run this script (it should be set as the `version` script in `/package.json`)
38+
# 4. This script will stage `/packages/*/package.json` if `npm_config_git_tag_version` exists
39+
# 5. npm will choose whether to commit / tag afterward on its own
40+
41+
npm --workspaces version --no-git-tag-version "${npm_package_version}"
42+
43+
if [ -z "${npm_config_git_tag_version+set}" ]; then
44+
npm query .workspace | jq -r '.[].location' | while read WS; do
45+
git add "$WS/package.json"
46+
done
47+
fi

0 commit comments

Comments
 (0)