yarnpkg / berry

📦🐈 Active development trunk for Yarn ⚒
https://yarnpkg.com
BSD 2-Clause "Simplified" License
7.45k stars 1.11k forks source link

[Feature] version plugin: add --all flag to version command #1229

Open fggrimshaw opened 4 years ago

fggrimshaw commented 4 years ago

Describe the user story

My team would like to add versioning to a CI system, and we need a way to set a versioning strategy on all modified workspaces.

Describe the solution you'd like

The version command should have an --all flag which allows for setting a versioning strategy for all modified workspaces, including workspaces which depend on a modified workspace.

Describe the drawbacks of your solution

Describe alternatives you've considered

The best alternative is to add some scripting which uses the version plugin. Berry's core methods can already handle the heavy lifting of detecting modified workspaces and workspace dependency so it seems silly to not use this.

Additional context

N/A

fggrimshaw commented 4 years ago

For what it's worth I have already implemented this to fit my own needs in my fork: https://github.com/fggrimshaw/berry/commit/143ed6845e68391dcbb5759b173985917c04bc18

atoiv commented 4 years ago

This would be a handy addition.

As an improvement on the concept, I wonder if it would be useful to also be able to declare in a versions file that packages are kept in sync with the root's version.

This would make the versioning scheme explicit and less temporary than using just a flag. In many use cases, I would guess, one wants to keep updating workspaces in a monorepo in a single manner also in the future, and not just temporarily. For temporal use cases, like bumping major version, the flag would be great.

I'd expect that if fixed versioning would be set in versions file, when root's version would be updated, it would resonate to other workspaces as well.

There could also be use for either a whitelist or blacklist in versions file, for keeping only some of the packages in sync with root version.

Another, a bit different use case, would be one where you want to keep multiple different version schemes inside a same monorepo. Say, you have a frontend and backend workspaces, multiple workspaces in both groups, that need to have internally the same versions inside their respective groups, but they don't need to follow the other group's version externally. So there would be a need to group workspaces by a shared version scheme, and be able to set simultaneously version for every workspace in a group.

kasperisager commented 4 years ago

As an improvement on the concept, I wonder if it would be useful to also be able to declare in a versions file that packages are kept in sync with the root's version.

This would make the versioning scheme explicit and less temporary than using just a flag. In many use cases, I would guess, one wants to keep updating workspaces in a monorepo in a single manner also in the future, and not just temporarily. For temporal use cases, like bumping major version, the flag would be great.

I'd expect that if fixed versioning would be set in versions file, when root's version would be updated, it would resonate to other workspaces as well.

This is precisely the use case I'm currently investigating as I'm looking for a way to move off of Lerna as we only use it for fixed version releases. For context, I'm working on https://github.com/siteimprove/alfa which is marketed as a single product with a single version, but structured as a workspace with 80+ packages. Our release workflow is kicked off by doing lerna version, which bumps all packages in the workspace, creates a single tag, and pushes it. The release workflow picks up on this and builds, tests, and publishes all packages using lerna publish from-package. The only headache we currently face is therefore deciding on a release strategy by inspecting all changes across all packages, which is assisted by labels assigned to pull requests.

The way I imagine it, I'd be able to do yarn version <strategy> --deferred at the workspace root and have yarn version apply apply the root strategy across all packages in the workspace, including the root, and create a single tag for the root version. This could replace lerna version. Once the version has been bumped across all packages, I imagine the release workflow could just do yarn workspaces foreach npm publish which could replace lerna publish

kasperisager commented 3 years ago

We went ahead with the upgrade to Berry and found that Lerna didn't want to play along when we tried cutting our first release post-upgrade today. As a replacement of lerna version and lerna publish, we now use the following release flow:

  1. The public packages are marked for version bump:

    yarn workspaces foreach \
        --no-private \
        --topological \
        version --deferred <patch | minor | major>
  2. The new versions are applied:

    yarn version apply --all
  3. The new versions are committed and tagged:

    git commit --message <version>
    git tag --message <version> --annotate <version>
  4. The public packages are packed and published:

    yarn workspaces foreach \
        --no-private \
        --topological \
        npm publish

Previously, lerna version would take care of steps 1-3 and lerna publish would take care of 4. It's not really an issue having to put in some more keystrokes to achieve the same thing, especially since it can easily be thrown in a script. I do actually like how well workspace specific commands compose with workspaces foreach.

Kudos to the entire Yarn team! ❤️