standard-version icon indicating copy to clipboard operation
standard-version copied to clipboard

Usage in monorepo nx workspace

Open sidyes opened this issue 4 years ago • 13 comments

Hi, I am using nx workspace to handle multiple angular projects as well as shared libraries. Let' s assume a folder structure like this:

|_package.json
|_CHANGELOG.md
|_projectA
  |_package.json
  |__CHANGELOG.md
|_projectB
  |_package.json
  |_CHANGELOG.md

I am trying to figure out a way to use conventional-changelog in my release process. I want to have seperated changelogs for each project and one root changelog. By using conventional commits I would like to somehow define the scope of the commit (e.g. that this feat() only affects projectA and thus, is only mentioned in this specific changelog.

Is this possible or is this a wrong approach in a monorepo?

Help appreciated.

sidyes avatar Aug 26 '19 08:08 sidyes

@sidyes did you make any progress on this? I'm trying to do the exact same

snebjorn avatar Mar 14 '20 13:03 snebjorn

@sidyes did you make any progress on this? I'm trying to do the exact same

Unfortunatelly, I did not and currently I am just living with the all-in-one changelog. I would still love to have a solution for this...

sidyes avatar Mar 16 '20 06:03 sidyes

@sidyes I think I've found a solution. It's not ideal, but it'll do for now.

You put an .versionrc file in each sub folder with the "path": "." config. Then you run standard-version from each sub folder you want to update the changelog for.

Example https://github.com/snebjorn/akita/blob/refactor/nx-workspace/libs/akita-ng-entity-service/

snebjorn avatar Mar 16 '20 08:03 snebjorn

@sidyes I think I've found a solution. It's not ideal, but it'll do for now.

You put an .versionrc file in each sub folder with the "path": "." config. Then you run standard-version from each sub folder you want to update the changelog for.

Example https://github.com/snebjorn/akita/blob/refactor/nx-workspace/libs/akita-ng-entity-service/

Ok, so it automatically recognizes the changes only for this specific folder and creates a CHANGELOG for this? Other commits from other scopes are automatically ignored?

sidyes avatar Mar 17 '20 08:03 sidyes

I believe so. My initial test worked. But haven't used it in the wild yet. But wait. There's more! 🎈 🎉

I managed to improve upon it quite a bit. This combo makes it work from the repo root and without standard-version globally installed!

files in project folder: .yarnrc .versionrc

npm script in root: "release:akita-entity-service": "yarn --cwd libs/akita-entity-service run standard-version"

snebjorn avatar Mar 17 '20 08:03 snebjorn

Working for me, thank you. 👍

sidyes avatar Mar 27 '20 13:03 sidyes

In case someone else runs into the same problem as me:

Since each repo in my mono repo has a different version and standard-version assumes you only want tags for one version, it often ended up mixing up the tags of the different repos. Causing the compareUrl to compare 3.0.9 with 10.12.5 and obviously not finding anything.

I solved this by using -t/--tag-prefix. With this, you can make sure, that each repo in your mono repo has their own version tags. This option is documented when running standard-version --help but not documented in the docs.

Hope this helps someone else as well.

StefanieJaeger avatar Mar 02 '21 08:03 StefanieJaeger

Hi, Thanks @josteph that recommended this solution. And indeed it worked.

I launch another question, and @snebjorn maybe you can throught a bit of light here

Should we upgrade the monorepo version number? or stick it to 0.0.0 forever? If for example we do any change in dependency versions, or add new scripts in the main package.json, should that be versioned too? or it does not have sense anymore?

sauldeleon avatar Jun 27 '21 17:06 sauldeleon

Anyone using the .versionrc files in each package, do you know if it inherits the parent .versionrc properly? On our case, we have the "types" definition on the root, haven't tried the proposed solution yet.

ianldgs avatar Aug 09 '21 11:08 ianldgs

@sidyes I think I've found a solution. It's not ideal, but it'll do for now.

You put an .versionrc file in each sub folder with the "path": "." config. Then you run standard-version from each sub folder you want to update the changelog for.

Example https://github.com/snebjorn/akita/blob/refactor/nx-workspace/libs/akita-ng-entity-service/

It worked for me, but I don't know why! How does it know which commits should be picked? Where should we specify the scope name?

movahedan avatar Jun 05 '22 13:06 movahedan

Maybe y'all wanna try https://github.com/jscutlery/semver

ianldgs avatar Jun 06 '22 20:06 ianldgs

how does standard-version account for transitive changes in the repo?

Assuming the npm scope for everything is @lmfao

package.json
CHANGELOG.md
apps/
  projectA/
    package.json //v1.0.0
    CHANGELOG.md
  projectB/
    package.json //v1.0.0
    CHANGELOG.md
packages/
  design-system/
    button/
      package.json //v1.0.0
      CHANGELOG.md
    flex/
      package.json //v1.0.0
      CHANGELOG.md
    stack/
      package.json //v1.0.0
      CHANGELOG.md
    field/
      package.json //v1.0.0
      CHANGELOG.md
    forms/
      package.json //v1.0.0
      CHANGELOG.md
    icon/
      package.json //v1.0.0
      CHANGELOG.md

if apps/projectA uses :

  • packages/button
  • packages/stack
  • packages/flex

and apps/projectB uses :

  • packages/button
  • packages/forms
  • packages/field

and then in the following PRs i make these changes:

PR1

- `apps/projectA` fix
- `packages/button` fix

PR2

- `packages/icon` feature

PR3

- `packages/form` fix
- `packages/button` feature
- `packages/icon` fix
- `apps/projectB` feature

Will the CHANGELOG.md for the above look like:

PR1

apps/projectA/CHANGELOG.md
  # @lmfao/projecta

  ## 1.0.1
  
  Fix
  
  - #1 pr title from pr 1

packages/button/CHANGELOG.md
  # @lmfao/button

  ## 1.0.1

  Fix
  
  - #1 pr title from pr 1

???

and what commands need to be run in order to achieve that?

if not 👉🏻 https://www.npmjs.com/package/@changesets/cli

airtonix avatar Jun 26 '22 02:06 airtonix

Hi, for NX monoropero projects I'm using @jscutlery/semver. Lets try a look :)

  1. create package.json in the root of all of the projects, just with the initial version: { "version": "0.0.0" }

  2. define target in project.json for all of the projects: "version": { "executor": "@jscutlery/semver:version", "options": { "changelogHeader": "# Changelog YOUR-APP-NAME \n", "baseBranch": "master", // or main, it depends on your git "syncVersions": false, "commitMessageFormat": "chore(${projectName}): release: v${version}", "push": false } }

  3. try run nx run {YOUR-APP-NAME}:version --dry-run in your terminal It should create CHANGELOG.md for the specified project that you run the npm script (I assume that you know what --dry-run means)

Good luck!

rtkac avatar Nov 18 '22 08:11 rtkac