semver icon indicating copy to clipboard operation
semver copied to clipboard

Replace syncVersions by version grouping

Open yjaaidi opened this issue 3 years ago • 2 comments

This is a follow-up to the following discussion https://github.com/jscutlery/semver/discussions/98.

Given a repo with 3 packages a, b & c, one should be able to sync versions for a & b but still keep independent versioning for c; meaning that changing a would have to bump b as well.

The solution we agreed to is to use the project structure for grouping (using folders).

By creating a "group" project in workspace config, like we already do in sync mode with a root path set to the group folder. This way, Nx cache, and Nx dep graph might work. This will just run the sync mode with a filter of projects that are in the group path. we also have to be careful about the root changelog.

Example:

{
  "name": "lumberjack",
  "root": "packages/lumberjack",
  "architect": {
    "version": {
      "builder": "@jscutlery/semver:version"
    },
  },
},
{
  "name": "spectacular",
  "root": "packages/spectacular",
  "architect": {
    "version": {
      "builder": "@jscutlery/semver:version"
    },
  },
},
{
  "name": "angular-group",
  "root": "packages/angular",
  "architect": {
    "version": {
      "builder": "@jscutlery/semver:version"
    },
  },
},
{
  "name": "angular-cdk",
  "root": "packages/angular/cdk",
  "architect": {"build": "..."}
},

2021-04-29 update

{
  "name": "workspace",
  "root": ".",
  "architect": {
    "version": {
      "builder": "@jscutlery/semver:version",
      "options": {
        "configs": [
          {
            "name": "rx-state",
            "type": "independent",
            // path is optional for independent versioning
            // as we can just pick the projectRoot in workspace.json
            // "path": "packages/rx-state", // we need this for git log & changelog path & root package.json
          },
          {
            "name": "cdk",
            "type": "group",
            "path": "packages/cdk",
            "packages": [
              "packages/cdk/operators",
              "packages/cdk/helpers", // or even a wildcard "packages/cdk/*"
            ]
          }
        ]
      }
    }
  }
}

  • [ ] If group root is "." then it's a workspace sync versioning so tag is vMAJOR.MINOR.PATCH
  • [ ] If group root is not "." then it's a group so tag is group-name-MAJOR.MINOR.PATCH
  • [ ] It would be nice to be compatible with both the current configuration syntax and the new one so we can rollout this new feature progressively in 2.x. The migration script can come later with 3.0 when the legacy syntax is not supported anymore.
  • [ ] Throw an error if a package has semver version while it's also in a group.
  • [ ] Consider adding a tagPrefix/--tag-prefix option in case a grouping folder needs to be renamed--for whatever reason--without breaking the version tags (maybe we should open a distinct issue)

cc. @LayZeeDK, @NachoVazquez, @santoshyadavdev, and @SerkanSipahi.

yjaaidi avatar Mar 18 '21 17:03 yjaaidi

Challenges with current approach

Considering the following issues:

  1. grouping needs "virtual projects" which make angular.json / workspace.json less readable than it already is 😉... plus, we (with @edbzn) feel that it could lead to conflicts & issues with other tools,
  2. as we rely on nx to run semver on the different projects in independent mode, we have less control to solve issues like this one https://github.com/jscutlery/semver/issues/61.

💡 Idea

A single virtual project named "workspace" with a global configuration should allow more control. In the future, if we need it for some reason, we can even run a semver cli and feed it with a semver.json configuration.

The new configuration could look something like this.

{
  "name": "workspace",
  "root": ".",
  "architect": {
    "version": {
      "builder": "@jscutlery/semver:version",
      "options": {
        "configs": [
          {
            "name": "rx-state",
            "type": "independent",
            // path is optional for independent versioning
            // as we can just pick the projectRoot in workspace.json
            // "path": "packages/rx-state", // we need this for git log & changelog path & root package.json
          },
          {
            "name": "cdk",
            "type": "group",
            "path": "packages/cdk",
            "packages": [
              "packages/cdk/operators",
              "packages/cdk/helpers", // or even a wildcard "packages/cdk/*"
            ]
          }
        ]
      }
    }
  }
}

Later, this could evolve into something like:

{
 ...
 "configs": [
    "packages/*/semver.json"
 ]
}

in order to move semver.json configs inside projects and stop the workspace.json clutter.

Drawback

The main drawback is that we can't use nx options like --affected etc... to run semver for independent projects... but that's not really important as semver is idempotent and won't bump if no changes occurred since last bump.

yjaaidi avatar Apr 29 '21 06:04 yjaaidi

Is this still a planned feature?

tomjamesallen avatar Jan 13 '23 10:01 tomjamesallen