From cc64f1f48c032a60f1d58057df8e08f517c76d33 Mon Sep 17 00:00:00 2001 From: Gabriel Terwesten Date: Fri, 23 Sep 2022 13:05:28 +0200 Subject: [PATCH] docs: document versioning (#377) Co-authored-by: Mike Diarmid --- docs/configuration/overview.mdx | 100 ++++++--- docs/guides/automated-releases.mdx | 201 +++++++++++++++--- .../melos/lib/src/command_runner/version.dart | 6 +- 3 files changed, 235 insertions(+), 72 deletions(-) diff --git a/docs/configuration/overview.mdx b/docs/configuration/overview.mdx index 2f5db7b9..f2ba5536 100644 --- a/docs/configuration/overview.mdx +++ b/docs/configuration/overview.mdx @@ -12,7 +12,7 @@ all the configurable fields and their purpose. > required -The name of this project, using for display purposes within IO environments and IDEs. +The name of this project for display purposes within IO environments and IDEs. ```yaml name: My Awesome Project @@ -20,7 +20,7 @@ name: My Awesome Project ## `repository` -The URL of where the git repository, which contains this project, is centrally hosted. +The URL of the git repository that contains the Melos workspace. Supported hosts: @@ -33,13 +33,16 @@ repository: https://github.com/invertase/melos ## `sdkPath` +> optional + Path to the Dart/Flutter SDK that should be used. Relative paths are resolved relative to the `melos.yaml` file. To use the system-wide SDK, provide the special value "auto". -If the SDK path is specified though multiple mechanisms, the precedence from highest to lowest is: +If the SDK path is specified though multiple mechanisms, the precedence from +highest to lowest is: 1. `--sdk-path` global command line option 2. `MELOS_SDK_PATH` environment variable @@ -53,8 +56,8 @@ sdkPath: .fvm/flutter_sdk > required -A list of paths to local packages that are included in the Melos workspace. Each entry can be -specific path or a [glob] pattern. +A list of paths to local packages that are included in the Melos workspace. Each +entry can be a specific path or a [glob] pattern. ```yaml packages: @@ -66,70 +69,85 @@ packages: - . ``` -> You can also reduce the scope of packages on a per-command basis via the [`--scope` filter](/filters#scope) flag. +> You can also reduce the scope of packages on a per-command basis via the +> [`--scope` filter](/filters#scope) flag. ## `ignore` -A list of paths to local packages that are excluded from the Melos workspace. Each entry can be -specific path or a [glob] pattern. +> optional + +A list of paths to local packages that are excluded from the Melos workspace. +Each entry can be a specific path or a [glob] pattern. ```yaml ignore: # e.g. ignore example apps - - "packages/**/example" + - 'packages/**/example' ``` -> You can also expand the scope of ignored packages on a per-command basis via the [`--scope` filter](/filters#scope) flag. +> You can also expand the scope of ignored packages on a per-command basis via +> the [`--scope` filter](/filters#scope) flag. + +## `ide` + +> optional + +Configuration for realting to IDE support. ## `ide/intellij/enabled` -Whether to generate IntelliJ IDEA config files to improve the developer experience when working -in a Melos workspace. +Whether to generate IntelliJ IDEA config files to improve the developer +experience when working in a Melos workspace. The default is `true`. ```yaml ide: intellij: - enabled: false # set to false to override default and disable + enabled: false # set to false to override default and disable ``` ## `ide/intellij/moduleNamePrefix` -Used when generating IntelliJ project modules files, this value specifies a string to prepend to a package's IntelliJ -module name. Use this to avoid name collisions with other IntelliJ modules you may already have in place. +Used when generating IntelliJ project modules files. This value specifies a +string to prepend to a package's IntelliJ module name. Use this to avoid name +collisions with other IntelliJ modules you may already have in place. -The default is 'melos_'. +The default is 'melos\_'. ## `scripts` > optional -Define custom scripts that can be executed in the workspace via the [`melos run`](/commands/run) command. +Define custom scripts that can be executed in the workspace via the +[`melos run`](/commands/run) command. Learn more about defining scripts [here](/configuration/scripts). ## `command` +> optional + Configuration relating to specific Melos commands such as versioning. +### `command/bootstrap` + +Configuration for the `bootstrap` command. + ### `command/bootstrap/usePubspecOverrides` -Whether to use `pubspec_overrides.yaml` for overriding workspace dependencies during development. +Whether to use `pubspec_overrides.yaml` for overriding workspace dependencies +during development. Enabling this option requires Dart **2.17.0** or greater. -When this option is enabled, Melos will generate a `pubspec_overrides.yaml` file in the root of -every package during bootstrapping. This file should not be tracked in version control and should -be added to `.gitignore`. +When this option is enabled, Melos will generate a `pubspec_overrides.yaml` file +in the root of every package during bootstrapping. This file should not be +tracked in version control and should be added to `.gitignore`. -This mechanism has the advantage that it does not conflict with other tooling such as the `dart` -and `flutter` tools and IDE plugins, compared to the original mechanism used to link local packages. - -A caveat is that because of a bug in `pub`, whose fix is not yet in the stable channel, publishing -of packages cannot be performed while `pubspec_overrides.yaml` exists. A workaround is to run -`melos clean` before `melos publish`, which removes `pubspec_overrides.yaml`s if they were -generated by Melos. +This mechanism has the advantage that it does not conflict with other tooling +such as the `dart` and `flutter` tools and IDE plugins, when compared to the +original mechanism used to link local packages. ### `command/bootstrap/runPubGetInParallel` @@ -145,13 +163,18 @@ Useful in closed network environments with pre-populated pubcaches. The default is `false`. +### `command/version` + +Configuration for the `version` command. + ### `command/version/message` A template for the commit message, that is generated by `melos version`. Templates must use mustache syntax and have the following variables available: -- `new_package_versions`: A list of the versioned packages and their new versions. +- `new_package_versions`: A list of the versioned packages and their new + versions. The default is: @@ -172,7 +195,8 @@ command: ### `command/version/branch` -If specified, prevents `melos version` from being used inside branches other than the one specified. +If specified, prevents `melos version` from being used inside branches other +than the one specified. ```yaml command: @@ -192,7 +216,8 @@ command: ### `command/version/includeCommitId` -Whether to add short commit id (no links) in the CHANGELOG.md, that is generated by `melos version`. +Whether to add short commit ids to commits (no links) in the CHANGELOG.md that +is generated by `melos version`. ```yaml command: @@ -202,7 +227,8 @@ command: ### `command/version/linkToCommits` -Whether to add links to commits in the CHANGELOG.md, that is generated by `melos version`. +Whether to add links to commits in the CHANGELOG.md that is generated by +`melos version`. Enabling this option, requires [`repository`](#repository) to be specified. @@ -214,7 +240,8 @@ command: ### `command/version/workspaceChangelog` -Whether to additionally build a CHANGELOG.md at the root of the workspace when running `melos version`. +Whether to additionally build a CHANGELOG.md at the root of the workspace when +running `melos version`. ```yaml command: @@ -224,7 +251,12 @@ command: ### `command/version/updateGitTagRefs` -When running `melos version` this option will allow updates to `pubspec.yaml` for locally (git) hosted packages part of this melos workspace, see [here](/guides/automated-releases#git-hosted-packages) +Whether to update package version tags in git dependencies of dependents when +versioning packages. + +See the +[automated releases documentation](/guides/automated-releases#git-hosted-packages) +for more information. ```yaml command: diff --git a/docs/guides/automated-releases.mdx b/docs/guides/automated-releases.mdx index 6e6b2ed2..f97d29c6 100644 --- a/docs/guides/automated-releases.mdx +++ b/docs/guides/automated-releases.mdx @@ -1,50 +1,177 @@ --- title: Automated Releases -description: Automate your workflow by versioning and publishing packages with Melos and Conventional Commits. +description: + Automate your workflow by versioning and publishing packages with Melos and + Conventional Commits. --- # Automated Releases -Melos is able to automatically version, generate changelogs and publish to [pub.dev](https://pub.dev) -automatically. It's also intelligent enough to detect any package dependencies which require a new -version too. +Melos is able to automate **versioning** and **publishing** of your packages. -Your Git project must be using [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/), -a widely used specification for commit messages which are readable by humans and machines. Melos parses -messages and detects exactly what sort of version upgrade is required. +This includes: -Melos supports prefixes (like the `Merge ...` and `Merged ...` for example) before the conventional -commit type, this is useful since some collaborative version control systems use these -non-configurable prefixes when they merge pull requests. +- incrementing of versions based on commit messages. +- updating version constraints of dependents. +- generating of changelogs. +- running versioning hook scripts. +- update package version tags in git dependencies. +- publishing of packages to [pub.dev](https://pub.dev). -### Not using Conventional Commits? +## Versioning -If an existing Git project is already established and does not use Conventional Commits, it is still -possible to adopt the convention and use Melos for future releases. +Packages can be versioned automatically based on their commit history. For this +to work, Melos needs to be able to parse commit messages and detect exactly what +sort of version upgrade is required. Melos understands +[Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/), a widely +used specification for commit messages which are readable by humans and +machines. -TODO how to adopt conventional commits with melos docs +Alternatively, packages can be versioned manually by specifing a version +increase (`major`, `minor`, `patch` or `build`) or an exact version. -## Versioning +For customizing the versioning process, see the +[configuration options](/configuration/overview#commandversion) for the +`version` command. + +### Automatic Versioning + +To determine which packages to version and how, Melos performs the following +steps: + +1. Apply [filters](/filters) to the list of workspace packages. +2. Load the commit history for each package. If the `--since` option is + specified, Melos will only load commits since the specified commit. Otherwise + it will load all commits since the last version tag (e.g. `foo-v1.0.0`). +3. Parse commit messages as Conventional Commits. If a commit message does not + follow the Conventional Commits specification, it will be ignored. +4. Filter out commits with types that don't trigger a version bump. For example, + `chore` commits will be ignored. +5. If at this point no commits remain, the package will not be versioned. +6. Determine the version upgrade required for each package based on the commit + with the most significant version bump. For example, if a package has a + `feat` commit and a `fix` commit, the package will be versioned with a + `minor` upgrade. + +#### Conventional Commits + +Currently the following commit types trigger a version bump: + +- `docs` - A documentation change. +- `feat` - A new feature. +- `fix` - A bug fix. +- `bug` - A bug fix. +- `perf` - A change that improves performance. +- `refactor` - A change that neither fixes a bug nor adds a feature. +- `revert` - A change that reverts a previous commit. + +The first matching rule in the list below determines the version bump for a +commit: + +1. A breaking change will trigger a **major** version bump. +2. A feature will trigger a **minor** version bump. +3. All other changes will trigger a **patch** version bump. + +Melos supports prefixes (like `Merge ...` and `Merged ...` for example) before +the conventional commit type. This is useful since some collaborative version +control systems use these non-configurable prefixes when they merge pull +requests. + +#### Not using Conventional Commits? + +If an existing Git project is already established and does not use Conventional +Commits, it is still possible to adopt the convention and use Melos for future +releases. + +Just start writing commit messages that follow Conventional Commits. When you +are ready to release a package for the first time with Melos use [manual +versioning][#manual-versioning]. This will ensure that the version increment is +appropriate for all commits, including those that Melos cannot interpret. + +Once you have manullay versioning every packages at least once, you can savely +use automatic versioning. + +### Manual Versioning + +Manual versioning allows you to specify a version increment (`major`, `minor`, +`patch` or `build`) or an exact version for one or more packages. + +If you only want to manually version a single package, you can use the following +syntax: + +```sh +melos version +``` + +To manually version multiple packages use the `--manual-version` (short `-V`) +option: + +```sh +melos version --manual-version : +``` + +Note that when using the `--manual-version` option, the automatic versioning +process is executed normally, execpt for the packages that are manually +versioned. This allows you to mix automatic and manual versioning. The +[`--ignore`](/filters#--ignore) filter can be used to exclude all package from +automatic versioning, by passing `--ignore '*'`. + +### Dependents Versioning + +By default, Melos also updates the constraints in the `pubspec.yaml` files of +dependents of the packages that were versioned. This can be disabled by passing +`--no-dependent-constraints`. + +If such a dependent is not already being versioned, a **patch** version bump +will be created for it. This can be disabled by passing +`--no-dependent-versions`. -TODO docs on: +Note that dependents of versioned packages are not filtered by the specified +package filters. -- Scoping -- Major/minor/patches -- build versions -- dependency versioning -- bad commit messages? -- manual versioning +### Commiting and Taging Version Changes + +After updating the `pubspec.yaml` files and changelogs of the versioned +packages, Melos will commit the changes and add a package version tag for each +package. + +Package version tags have the format `-v`. + +This behavior can be disabled by passing `--no-git-tag-version`. + +#### Hook + +After updating `pubspec.yaml` files and changelogs but before creating the +version commit, the `version` script in `melos.yaml` is executed. This allows +you to run custom code before the version commit is created. + +Note that you have to stage changes that you make in the hook and want to have +included in the version commit yourself. + +### Changelog + +Melos updates the changelog for each package that is versioned by prepending a +section for the new version. You can disable this behavior by passing +`--no-changelog`. + +See the [configuration options](/configuration/overview#commandversion) for the +`version` command for customizing changelog generation. + +Optionally, Melos can also write a +[workspace changelog](/configuration/overview#commandversionworkspacechangelog). +This is disabled by default. ## Publishing To publish packages on [pub.dev](https://pub.dev) you must: 1. Have permission to publish all the packages. -2. Be on a machine which is authenticated with Pub (read: not possible to publish via CIs). +2. Be on a machine which is authenticated with Pub. > Internally, Melos uses `pub publish` to publish the packages. -Once you have [versioned](#versioning) your packages, run the publish command to check everything is good to go: +Once you have [versioned](#versioning) your packages, run the publish command to +check everything is good to go: ```dart melos publish @@ -52,24 +179,22 @@ melos publish By default, a dry-run is performed (nothing will be published). -Once satisfied with your pending releases, release them to [pub.dev](https://pub.dev): +Once satisfied with your pending releases, release them to +[pub.dev](https://pub.dev): ```dart melos publish --no-dry-run ``` -## Git hosted packages - -To use this feature enable it in `melos.yaml` -```yaml -command: - version: - updateGitTagRefs: true # defaults to false -``` +## Git Hosted Packages -If your packages are private and don't publish to [pub.dev](https://pub.dev), you can use the tag generated as git reference in your `pubspec.yaml` file and Melos will ensure the versions are updated accordingly. +If your packages are private and you don't publish them to +[pub.dev](https://pub.dev), you can use package version tags as git reference in +your `pubspec.yaml` files and Melos will ensure that the tags are updated +accordingly. Example: + ```yaml dependencies: internal_dep: @@ -87,3 +212,11 @@ dependencies: path: packages/internal_dep ref: internal_dep-v0.0.2 ``` + +To use this feature enable it in `melos.yaml` + +```yaml +command: + version: + updateGitTagRefs: true # defaults to false +``` diff --git a/packages/melos/lib/src/command_runner/version.dart b/packages/melos/lib/src/command_runner/version.dart index 0b4ecf2f..9a7714dc 100644 --- a/packages/melos/lib/src/command_runner/version.dart +++ b/packages/melos/lib/src/command_runner/version.dart @@ -79,8 +79,7 @@ class VersionCommand extends MelosCommand { defaultsTo: true, help: 'Make a new patch version and changelog entry in packages that are ' 'updated due to "--dependent-constraints" changes. Only usable ' - 'with "--dependent-constraints" enabled and Conventional Commits ' - 'based versioning.', + 'with "--dependent-constraints" enabled.', ); argParser.addFlag( 'git-tag-version', @@ -104,8 +103,7 @@ class VersionCommand extends MelosCommand { argParser.addFlag( 'yes', negatable: false, - help: 'Skip the Y/n confirmation prompt. Note that for manual versioning ' - '--no-changelog must also be passed to avoid prompts.', + help: 'Skip the Y/n confirmation prompt.', ); argParser.addFlag( 'all',