mantoni / mochify.js

☕️ TDD with Browserify, Mocha, Headless Chrome and WebDriver
MIT License
346 stars 57 forks source link

Rewrite: Release & publishing strategy #250

Closed mantoni closed 8 months ago

mantoni commented 3 years ago

Now that we have a monorepo with npm workspaces, it's not so easy to create releases anymore.

For publishing the options are:

  1. 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.
  2. Release modules individually and only publish what was updated. Create tags for each module with a naming scheme, e.g. cli-v1.0.0.
  3. 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.

mantoni commented 2 years ago

Here is a suggestion how we could continue to release with @studio/changes: https://github.com/javascript-studio/studio-changes/pull/40

What do you think @m90?

m90 commented 2 years ago

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
mantoni commented 2 years ago

I'm currently doing releases with

cd cli
npm version patch 
cd ..
npm install

The version script of each module would be changes -w.

mantoni commented 2 years ago

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.

m90 commented 2 years ago

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?

mantoni commented 2 years ago

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 required in the module tests (to make the linter happy and to be able to migrate tests to new library versions per sub-module).

m90 commented 2 years ago

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.

mantoni commented 2 years ago

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.

m90 commented 2 years ago

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?

mantoni commented 2 years ago

@m90 That is correct.

mantoni commented 8 months ago

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