googleapis / release-please

generate release PRs based on the conventionalcommits.org spec
https://www.conventionalcommits.org
Apache License 2.0
4.44k stars 331 forks source link

Scope Based Versioning #1989

Open ehakan opened 1 year ago

ehakan commented 1 year ago

Problem

As far as I understand release-please only considers paths of edited files and commit messages when determining version.

For most projects this is fine, but depending solely on paths start to break down when trying to version more complicated structures.

Conventional Commit scopes can provide significant context in these situations because they are decided by developers.

Cases such as:

Proposal

Let's add a recursive "scoped-package" field to the spec, with fields inherited from package spec, and two extra fields:

"Simple" Manifest Example

{
  "packages": {
    // is a path
    "src/multiplayer-game": {
      "scoped-packages": {
        // not a path and not a scope,
        // just the package name
        "client": {
          // anything not explicitly scoped and under this path
          // should also bump versions for this component
          "include-nonscoped": true,
          "scopes": [ "client", "ui" ],
          "release-type": "simple"
        },
        "server": {
          "include-nonscoped": true,
          "scopes": [ "server" ],
          "release-type": "simple"
        }
      }
    },
  "separate-pull-requests": true,
  "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json"
}

Assuming both client and server is at v1.0.0, and the game provides backwards compatibility on major version (as it should):

Nested Manifest Example

{
  "packages": {
    "src/mobile-multiplayer-game": {
      "scoped-packages": {
        "server": {
          "include-nonscoped": true,
          "scopes": [ "server" ],
          "release-type": "simple"
        },
        // example nested components
        "client": {
          "include-nonscoped": true,
          // a commit message with scope client, 
          // will also effect scopes client/ios and client/android
          "scopes": [ "client", "ui" ],
          "scoped-packages": {
            "ios": {
              "include-nonscoped": true,
              // nested scope
              "scopes": [ "client/ios" ],
              "release-type": "simple"
            },
            "android": {
              "include-nonscoped": true,
              "scopes": [ "client/android" ],
              "release-type": "simple"
            }
          }
        }
      }
    }
  },
  "tag-separator": "/",
  "separate-pull-requests": true,
  "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json",
}

Server is the same but now client has "ios" and "android" subscopes.

Note that bumping strategy is just semver, not the one I mentioned in cases.

Alternatives

I haven’t come across a tool that supports both monorepos and multiple languages as well as release-please.

dscpd commented 4 months ago

Scope-based versioning perhaps has the potential to gain larger user base. Can it be implemented in an abstract way? That is, the selection of commits to associate to a component is implemented as a “strategy”. Like, path-based, scope-based, etc.