Rewrite: Release & publishing strategy
Closed this issue ยท 11 comments
Now that we have a monorepo with npm workspaces, it's not so easy to create releases anymore.
For publishing the options are:
- Release everything at once, update all module versions to the same version and publish them all. Create a "global" version tag that is synced with all modules.
- Release modules individually and only publish what was updated. Create tags for each module with a naming scheme, e.g.
cli-v1.0.0
. -
Your idea here
For option 2 to work with @studio/changes
, we need a change there too. It generates the changelog by listing all commits from a specific tag onwards. We'd need a "filter" option of sorts to only list commits that changed files in the corresponding module directory.
Here is a suggestion how we could continue to release with @studio/changes
: javascript-studio/studio-changes#40
What do you think @m90?
How would that work for someone who's trying to publish a new version of say a driver? Would you
npm run version -- -w driver-puppeteer
I'm currently doing releases with
cd cli
npm version patch
cd ..
npm install
The version
script of each module would be changes -w
.
We can also do
npm version patch -w cli
which has pretty much the same effect as the above, afaict. The npm status bar messes up the console output though.
I didn't find any documentation about npm behavior of version
with -w
. Hopefully this is going to be improved.
npm version patch -w cli
Ah ok, now I start to understand what the PR in changes
actually does and it seems to make sense.
Would a "release every package always" workflow look much different?
Here is my view of what is good and bad about the "release very package workflow":
Good
It would be easier to generate the changelog on the top level project, or we could still try the per-module changelog with the new changes
feature.
Tagging would also be easier since the tag name could align with the version numbers of all packages. With the suggested per-module release workflow, there would be version commits like cli v1.2.3
which would be tagged cli/v1.2.3
.
Bad
The "release every package workflow" would mean that a patch in one of the drivers would cause a release of everything, also unrelated drivers, the cli
and the shared mochify
package. I'm not a fan of creating unnecessary noise in package updates. I expect the cli
and the shared mochify
package to become relatively stable and updates to happen more frequently in the the drivers.
The whole npm workspaces thing is new to me and I still consider this an experiment and there is certainly some learning required. I would vote for trying the "release each module separately" approach.
What I quite like about npm workspaces in general is that the tooling for releasing, formatting and linting can be shared between all modules via the top level package.json
. Updates in the toolchain wouldn't be reflected in the changelog of the sub-modules, which removes noise for readers. Also the package.json
of individual modules only contains devDependencies
that are acutally require
d in the module tests (to make the linter happy and to be able to migrate tests to new library versions per sub-module).
By now I also feel that a project of this scale is better off releasing modules individually.
I do like the convenience aspect of "same version number all over" as a consumer, but being honest all of the projects I've seen doing this are a. constantly being worked on (allowing a fixed release schedule), b. almost never release breaking changes (or just disregard SemVer proper in some aspects) and c. do not rely on upstream dependencies too much (not tying themselves to their releases or features).
Considering Mochify will probably never grow into a hundred packages and will see fluctuating patterns of commit and release activity, I think releasing per module is a good choice. For example, imagine there is some change in the shape of the options passed to puppeteer (something got deprecated because Chrome or something) which would require a breaking change for driver-puppeteer
: would we want to not update puppeteer or would we want to needlessly release a major version for everything else? Probably neither.
The only thing I am slightly worried about is us getting the peer dep version ranges wrong on releases (how would that even work?) but I guess we'll see how that goes.
Also: if we find this to be not working well, we still have the escape hatch of "pulling a React", hoist everything to the same highest version number (potentially skipping a few versions) and switch over to the other strategy.
Regarding peer dependencies, I have previously used them with multiple major versions, like ^1.0.0 || ^2.0.0
. If one of the other dependencies requires v1, that is installed. If v2 is compatible with the rest of the tree, that is preferred.
On more question for my understanding about the peer dependency handling:
In case we release a new major version of @mochify/mochify
, each driver would have to release a new version so the new major would also be allowed in its range of peerDependencies
. This release would not necessarily have to be a major release though.
Is that correct?
This whole npm workspaces situation with npm version
isn't working. npm is not creating tags and there doesn't seem to be any recent development.
So I gave up on it and moved all sub projects into own repositories in a new org:
https://github.com/mochify-js