From d9c53e14fc1a00ef8270162c0500d78650bcabaf Mon Sep 17 00:00:00 2001 From: Austin Fahsl Date: Wed, 24 Jan 2024 14:33:39 -0700 Subject: [PATCH] chore(release): add nx release recipes (#21294) --- docs/generated/manifests/menus.json | 90 ++++++ docs/generated/manifests/nx.json | 123 ++++++++ docs/generated/manifests/tags.json | 23 ++ docs/map.json | 25 ++ ...cally-version-with-conventional-commits.md | 84 ++++++ .../nx-release/get-started-with-nx-release.md | 277 ++++++++++++++++++ .../release-projects-independently.md | 93 ++++++ docs/shared/reference/sitemap.md | 4 + 8 files changed, 719 insertions(+) create mode 100644 docs/shared/recipes/nx-release/automatically-version-with-conventional-commits.md create mode 100644 docs/shared/recipes/nx-release/get-started-with-nx-release.md create mode 100644 docs/shared/recipes/nx-release/release-projects-independently.md diff --git a/docs/generated/manifests/menus.json b/docs/generated/manifests/menus.json index c058187937ba4..7b3ef3ff07cb6 100644 --- a/docs/generated/manifests/menus.json +++ b/docs/generated/manifests/menus.json @@ -2377,6 +2377,39 @@ ], "disableCollapsible": false }, + { + "name": "Nx Release", + "path": "/recipes/nx-release", + "id": "nx-release", + "isExternal": false, + "children": [ + { + "name": "Get Started with Nx Release", + "path": "/recipes/nx-release/get-started-with-nx-release", + "id": "get-started-with-nx-release", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, + { + "name": "Release Projects Independently", + "path": "/recipes/nx-release/release-projects-independently", + "id": "release-projects-independently", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, + { + "name": "Automatically Version with Conventional Commits", + "path": "/recipes/nx-release/automatically-version-with-conventional-commits", + "id": "automatically-version-with-conventional-commits", + "isExternal": false, + "children": [], + "disableCollapsible": false + } + ], + "disableCollapsible": false + }, { "name": "Other", "path": "/recipes/other", @@ -4177,6 +4210,63 @@ "children": [], "disableCollapsible": false }, + { + "name": "Nx Release", + "path": "/recipes/nx-release", + "id": "nx-release", + "isExternal": false, + "children": [ + { + "name": "Get Started with Nx Release", + "path": "/recipes/nx-release/get-started-with-nx-release", + "id": "get-started-with-nx-release", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, + { + "name": "Release Projects Independently", + "path": "/recipes/nx-release/release-projects-independently", + "id": "release-projects-independently", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, + { + "name": "Automatically Version with Conventional Commits", + "path": "/recipes/nx-release/automatically-version-with-conventional-commits", + "id": "automatically-version-with-conventional-commits", + "isExternal": false, + "children": [], + "disableCollapsible": false + } + ], + "disableCollapsible": false + }, + { + "name": "Get Started with Nx Release", + "path": "/recipes/nx-release/get-started-with-nx-release", + "id": "get-started-with-nx-release", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, + { + "name": "Release Projects Independently", + "path": "/recipes/nx-release/release-projects-independently", + "id": "release-projects-independently", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, + { + "name": "Automatically Version with Conventional Commits", + "path": "/recipes/nx-release/automatically-version-with-conventional-commits", + "id": "automatically-version-with-conventional-commits", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, { "name": "Other", "path": "/recipes/other", diff --git a/docs/generated/manifests/nx.json b/docs/generated/manifests/nx.json index f6dce4ba6a23b..8eeb9269111ff 100644 --- a/docs/generated/manifests/nx.json +++ b/docs/generated/manifests/nx.json @@ -3256,6 +3256,51 @@ "path": "/recipes/nx-console", "tags": [] }, + { + "id": "nx-release", + "name": "Nx Release", + "description": "Recipes for releasing with Nx release.", + "mediaImage": "", + "file": "", + "itemList": [ + { + "id": "get-started-with-nx-release", + "name": "Get Started with Nx Release", + "description": "", + "mediaImage": "", + "file": "shared/recipes/nx-release/get-started-with-nx-release", + "itemList": [], + "isExternal": false, + "path": "/recipes/nx-release/get-started-with-nx-release", + "tags": ["nx-release"] + }, + { + "id": "release-projects-independently", + "name": "Release Projects Independently", + "description": "", + "mediaImage": "", + "file": "shared/recipes/nx-release/release-projects-independently", + "itemList": [], + "isExternal": false, + "path": "/recipes/nx-release/release-projects-independently", + "tags": ["nx-release"] + }, + { + "id": "automatically-version-with-conventional-commits", + "name": "Automatically Version with Conventional Commits", + "description": "", + "mediaImage": "", + "file": "shared/recipes/nx-release/automatically-version-with-conventional-commits", + "itemList": [], + "isExternal": false, + "path": "/recipes/nx-release/automatically-version-with-conventional-commits", + "tags": ["nx-release"] + } + ], + "isExternal": false, + "path": "/recipes/nx-release", + "tags": [] + }, { "id": "other", "name": "Other", @@ -5724,6 +5769,84 @@ "path": "/recipes/nx-console/console-troubleshooting", "tags": ["integrate-with-editors"] }, + "/recipes/nx-release": { + "id": "nx-release", + "name": "Nx Release", + "description": "Recipes for releasing with Nx release.", + "mediaImage": "", + "file": "", + "itemList": [ + { + "id": "get-started-with-nx-release", + "name": "Get Started with Nx Release", + "description": "", + "mediaImage": "", + "file": "shared/recipes/nx-release/get-started-with-nx-release", + "itemList": [], + "isExternal": false, + "path": "/recipes/nx-release/get-started-with-nx-release", + "tags": ["nx-release"] + }, + { + "id": "release-projects-independently", + "name": "Release Projects Independently", + "description": "", + "mediaImage": "", + "file": "shared/recipes/nx-release/release-projects-independently", + "itemList": [], + "isExternal": false, + "path": "/recipes/nx-release/release-projects-independently", + "tags": ["nx-release"] + }, + { + "id": "automatically-version-with-conventional-commits", + "name": "Automatically Version with Conventional Commits", + "description": "", + "mediaImage": "", + "file": "shared/recipes/nx-release/automatically-version-with-conventional-commits", + "itemList": [], + "isExternal": false, + "path": "/recipes/nx-release/automatically-version-with-conventional-commits", + "tags": ["nx-release"] + } + ], + "isExternal": false, + "path": "/recipes/nx-release", + "tags": [] + }, + "/recipes/nx-release/get-started-with-nx-release": { + "id": "get-started-with-nx-release", + "name": "Get Started with Nx Release", + "description": "", + "mediaImage": "", + "file": "shared/recipes/nx-release/get-started-with-nx-release", + "itemList": [], + "isExternal": false, + "path": "/recipes/nx-release/get-started-with-nx-release", + "tags": ["nx-release"] + }, + "/recipes/nx-release/release-projects-independently": { + "id": "release-projects-independently", + "name": "Release Projects Independently", + "description": "", + "mediaImage": "", + "file": "shared/recipes/nx-release/release-projects-independently", + "itemList": [], + "isExternal": false, + "path": "/recipes/nx-release/release-projects-independently", + "tags": ["nx-release"] + }, + "/recipes/nx-release/automatically-version-with-conventional-commits": { + "id": "automatically-version-with-conventional-commits", + "name": "Automatically Version with Conventional Commits", + "description": "", + "mediaImage": "", + "file": "shared/recipes/nx-release/automatically-version-with-conventional-commits", + "itemList": [], + "isExternal": false, + "path": "/recipes/nx-release/automatically-version-with-conventional-commits", + "tags": ["nx-release"] + }, "/recipes/other": { "id": "other", "name": "Other", diff --git a/docs/generated/manifests/tags.json b/docs/generated/manifests/tags.json index 7702d9a0b9ddc..a675ea26c5cd8 100644 --- a/docs/generated/manifests/tags.json +++ b/docs/generated/manifests/tags.json @@ -1110,6 +1110,29 @@ "path": "/recipes/tips-n-tricks/flat-config" } ], + "nx-release": [ + { + "description": "", + "file": "shared/recipes/nx-release/get-started-with-nx-release", + "id": "get-started-with-nx-release", + "name": "Get Started with Nx Release", + "path": "/recipes/nx-release/get-started-with-nx-release" + }, + { + "description": "", + "file": "shared/recipes/nx-release/release-projects-independently", + "id": "release-projects-independently", + "name": "Release Projects Independently", + "path": "/recipes/nx-release/release-projects-independently" + }, + { + "description": "", + "file": "shared/recipes/nx-release/automatically-version-with-conventional-commits", + "id": "automatically-version-with-conventional-commits", + "name": "Automatically Version with Conventional Commits", + "path": "/recipes/nx-release/automatically-version-with-conventional-commits" + } + ], "database": [ { "description": "", diff --git a/docs/map.json b/docs/map.json index f811a3f718f06..ff57da90bebf5 100644 --- a/docs/map.json +++ b/docs/map.json @@ -1163,6 +1163,31 @@ } ] }, + { + "name": "Nx Release", + "id": "nx-release", + "description": "Recipes for releasing with Nx release.", + "itemList": [ + { + "name": "Get Started with Nx Release", + "id": "get-started-with-nx-release", + "tags": ["nx-release"], + "file": "shared/recipes/nx-release/get-started-with-nx-release" + }, + { + "name": "Release Projects Independently", + "id": "release-projects-independently", + "tags": ["nx-release"], + "file": "shared/recipes/nx-release/release-projects-independently" + }, + { + "name": "Automatically Version with Conventional Commits", + "id": "automatically-version-with-conventional-commits", + "tags": ["nx-release"], + "file": "shared/recipes/nx-release/automatically-version-with-conventional-commits" + } + ] + }, { "name": "Other", "id": "other", diff --git a/docs/shared/recipes/nx-release/automatically-version-with-conventional-commits.md b/docs/shared/recipes/nx-release/automatically-version-with-conventional-commits.md new file mode 100644 index 0000000000000..e2ccee3f9175b --- /dev/null +++ b/docs/shared/recipes/nx-release/automatically-version-with-conventional-commits.md @@ -0,0 +1,84 @@ +# Automatically Version with Conventional Commits + +If you wish to bypass the versioning prompt, you can configure Nx Release to defer to the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) standard to determine the version bump automatically. This is useful for automating the versioning process in a CI/CD pipeline. + +## Enable Automatic Versioning + +To enable automatic versioning via conventional commits, set the `release.version.conventionalCommits` property to `true` in `nx.json`: + +```json nx.json +{ + "release": { + "version": { + "conventionalCommits": true + } + } +} +``` + +## Determine the Version Bump + +Nx Release will use the commit messages since the last release to determine the version bump. It will look at the type of each commit and determine the highest version bump from the following list: + +- 'feat' -> minor +- 'fix' -> patch + +For example, if the git history looks like this: + +``` + - fix(pkg-1): fix something + - feat(pkg-2): add a new feature + - chore(pkg-3): update docs + - chore(release): 1.0.0 +``` + +then Nx Release will select the `minor` version bump and elect to release version 1.1.0. This is because there is a `feat` commit since the last release of 1.0.0. + +{% callout type="info" title="No changes detected" %} +If Nx Release does not find any relevant commits since the last release, it will skip releasing a new version. This works with [independent releases](/recipes/nx-release/release-projects-independently) as well, allowing for only some projects to be released and some to be skipped. +{% /callout %} + +## Usage with Independent Releases + +If you are using [independent releases](/recipes/nx-release/release-projects-independently), Nx Release will determine the version bump for each project independently. For example, if the git history looks like this: + +``` + - fix(pkg-1): fix something + - feat(pkg-2): add a new feature + - chore(pkg-3): update docs + - chore(release): publish +``` + +Nx Release will select the `patch` version bump for `pkg-1` and `minor` for `pkg-2`. `pkg-3` will be skipped entirely, since it has no `feat` or `fix` commits. + +{% callout type="info" title="Determining if a commit affects a project" %} +Note that this determination is made based on files changed by each commit, _not_ by the scope of the commit message itself. This means that `feat(pkg-2): add a new feature` could trigger a version bump for a project other than `pkg-2` if it updated files in another project. +{% /callout %} + +An example partial output of running Nx Release with independent releases and conventional commits enabled: + +```{% command="nx release" %} + + > NX Running release version for project: pkg-1 + +pkg-1 ๐Ÿ” Reading data for package "@myorg/pkg-1" from packages/pkg-1/package.json +pkg-1 ๐Ÿ“„ Resolved the current version as 0.4.0 from git tag "pkg-1@0.4.0". +pkg-1 ๐Ÿ“„ Resolved the specifier as "minor" using git history and the conventional commits standard. +pkg-1 โœ๏ธ New version 0.5.0 written to packages/pkg-1/package.json + + > NX Running release version for project: pkg-2 + +pkg-2 ๐Ÿ” Reading data for package "@myorg/pkg-2" from packages/pkg-2/package.json +pkg-2 ๐Ÿ“„ Resolved the current version as 0.4.0 from git tag "pkg-2@0.4.0". +pkg-2 ๐Ÿ“„ Resolved the specifier as "patch" using git history and the conventional commits standard. +pkg-2 โœ๏ธ New version 0.4.1 written to packages/pkg-2/package.json +pkg-2 โœ๏ธ Applying new version 0.4.1 to 1 package which depends on pkg-2 + + > NX Running release version for project: pkg-3 + +pkg-3 ๐Ÿ” Reading data for package "@myorg/pkg-3" from packages/pkg-3/package.json +pkg-3 ๐Ÿ“„ Resolved the current version as 0.4.0 from git tag "pkg-3@0.4.0". +pkg-3 ๐Ÿšซ No changes were detected using git history and the conventional commits standard. +pkg-3 ๐Ÿšซ Skipping versioning "@myorg/pkg-3" as no changes were detected. + +``` diff --git a/docs/shared/recipes/nx-release/get-started-with-nx-release.md b/docs/shared/recipes/nx-release/get-started-with-nx-release.md new file mode 100644 index 0000000000000..6e931196b1fb6 --- /dev/null +++ b/docs/shared/recipes/nx-release/get-started-with-nx-release.md @@ -0,0 +1,277 @@ +# Get Started with Nx Release + +This recipe guides you through versioning packages, generating changelogs, and publishing packages in a JavaScript monorepo with Nx Release. + +## Initialize Nx Release in Your Workspace + +### Install Nx + +Ensure that Nx is installed in your monorepo. Check out the [Installation docs](/getting-started/installation) for instructions on created a new Nx workspace or adding Nx to an existing project. + +### Add the JavaScript Plugin + +The [`@nx/js` package](/nx-api/js) is required for Nx Release to manage and release JavaScript packages. Add it if it is not already installed: + +```shell +nx add @nx/js +``` + +### Configure Projects to Release + +Nx Release uses Nx's powerful [Project Graph](/core-features/explore-graph) to understand your projects and their dependencies. + +If you want to release all of the projects in your workspace, such as when dealing with a series of npm library packages, no configuration is required. + +If you have a mixed workspace in which you also have some applications, e2e testing projects or other things you don't want to release, you can configure `nx release` to target only the projects you want to release. + +Configure which projects to release by adding the `release.projects` property to nx.json. The value is an array of strings, and you can use any of the same specifiers that are supported by `nx run-many`'s [projects filtering](/nx-api/nx/documents/run-many), such as explicit project names, Nx tags, directories and glob patterns, including negation using the `!` character. + +For example, to release just the projects in the `packages` directory: + +```json nx.json +{ + "release": { + "projects": ["packages/*"] + } +} +``` + +## Create the First Release + +The first time you release with Nx Release in your monorepo, you will need to use the `--first-release` option. This tells Nx Release not to expect the existence of any git tags, changelog files, or published packages. + +{% callout type="info" title="Use the --dry-run option" %} +The `--dry-run` option is useful for testing your configuration without actually creating a release. It is always recommended to run Nx Release once with `--dry-run` first to ensure everything is configured correctly. +{% /callout %} + +To preview your first release, run: + +```shell +nx release --first-release --dry-run +``` + +### Pick a New Version + +Nx Release will prompt you to pick a version bump for all the packages in the release. By default, all package versions are kept in sync, so the prompt only needs to be answered one time. + +```{% command="nx release --first-release --dry-run" %} + + > NX Running release version for project: pkg-1 + +pkg-1 ๐Ÿ” Reading data for package "@myorg/pkg-1" from packages/pkg-1/package.json +pkg-1 ๐Ÿ“„ Resolved the current version as 0.0.1 from packages/pkg-1/package.json +? What kind of change is this for the 3 matched projects(s)? โ€ฆ +โฏ major + premajor + minor + preminor + patch + prepatch + prerelease + Custom exact version +``` + +### Preview the Results + +After this prompt, the command will finish, showing you the preview of changes that would have been made if the `--dry-run` option was not passed. + +```{% command="nx release --first-release --dry-run" %} + + > NX Running release version for project: pkg-1 + +pkg-1 ๐Ÿ” Reading data for package "@myorg/pkg-1" from packages/pkg-1/package.json +pkg-1 ๐Ÿ“„ Resolved the current version as 0.0.1 from packages/pkg-1/package.json +โœ” What kind of change is this for the 3 matched projects(s)? ยท patch +pkg-1 โœ๏ธ New version 0.0.2 written to packages/pkg-1/package.json + + > NX Running release version for project: pkg-2 + +pkg-2 ๐Ÿ” Reading data for package "@myorg/pkg-2" from packages/pkg-2/package.json +pkg-2 ๐Ÿ“„ Resolved the current version as 0.0.1 from packages/pkg-2/package.json +pkg-2 โœ๏ธ New version 0.0.2 written to packages/pkg-2/package.json +pkg-2 โœ๏ธ Applying new version 0.0.2 to 1 package which depends on pkg-2 + + > NX Running release version for project: pkg-3 + +pkg-3 ๐Ÿ” Reading data for package "@myorg/pkg-3" from packages/pkg-3/package.json +pkg-3 ๐Ÿ“„ Resolved the current version as 0.0.1 from packages/pkg-3/package.json +pkg-3 โœ๏ธ New version 0.0.2 written to packages/pkg-3/package.json + +UPDATE packages/pkg-1/package.json [dry-run] + + "name": "@myorg/pkg-1", +- "version": "0.0.1", ++ "version": "0.0.2", + "dependencies": { + "tslib": "^2.3.0", +- "@myorg/pkg-2": "0.0.1" ++ "@myorg/pkg-2": "0.0.2" + }, + +UPDATE packages/pkg-2/package.json [dry-run] + + "name": "@myorg/pkg-2", +- "version": "0.0.1", ++ "version": "0.0.2", + "dependencies": { + +UPDATE packages/pkg-3/package.json [dry-run] + + "name": "@myorg/pkg-3", +- "version": "0.0.1", ++ "version": "0.0.2", + "dependencies": { + + + > NX Updating npm lock file + + + > NX Staging changed files with git + + +NOTE: The "dryRun" flag means no changes were made. + + > NX Previewing an entry in CHANGELOG.md for v0.0.2 + + +CREATE CHANGELOG.md [dry-run] ++ ## 0.0.2 (2024-01-23) ++ ++ This was a version bump only, there were no code changes. + + > NX Staging changed files with git + + +NOTE: The "dryRun" flag means no changelogs were actually created. + + > NX Committing changes with git + + + > NX Tagging commit with git + +Skipped publishing packages. +``` + +### Run Without `--dry-run` + +If the preview looks good, run the command again without the `--dry-run` option to actually create the release. + +```shell +nx release --first-release +``` + +The command will proceed as before, prompting for a version bump and showing a preview of the changes. However, this time, it will prompt you to publish the packages to the remote registry. If you say no, the publishing step will be skipped. If you say yes, the command will publish the packages to the npm registry. + +```{% command="nx release --first-release" %} +... + +โœ” Do you want to publish these versions? (y/N) ยท true + + > NX Running target nx-release-publish for 3 projects: + + - pkg-1 + - pkg-2 + - pkg-3 + + โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€” + +> nx run pkg-1:nx-release-publish + + +๐Ÿ“ฆ @myorg/pkg-1@0.0.2 +=== Tarball Contents === + +233B README.md +277B package.json +53B src/index.ts +61B src/lib/pkg-1.ts +=== Tarball Details === +name: @myorg/pkg-1 +version: 0.0.2 +filename: testorg-pkg-1-0.0.2.tgz +package size: 531 B +unpacked size: 624 B +shasum: {shasum} +integrity: {integrity} +total files: 12 + +Published to https://registry.npmjs.org with tag "latest" + +> nx run pkg-2:nx-release-publish + + +๐Ÿ“ฆ @myorg/pkg-2@0.0.2 +=== Tarball Contents === + +233B README.md +277B package.json +53B src/index.ts +61B src/lib/pkg-2.ts +=== Tarball Details === +name: @myorg/pkg-2 +version: 0.0.2 +filename: testorg-pkg-2-0.0.2.tgz +package size: 531 B +unpacked size: 624 B +shasum: {shasum} +integrity: {integrity} +total files: 12 + +Published to https://registry.npmjs.org with tag "latest" + +> nx run pkg-3:nx-release-publish + + +๐Ÿ“ฆ @myorg/pkg-3@0.0.2 +=== Tarball Contents === + +233B README.md +277B package.json +53B src/index.ts +61B src/lib/pkg-3.ts +=== Tarball Details === +name: @myorg/pkg-3 +version: 0.0.2 +filename: testorg-pkg-3-0.0.2.tgz +package size: 531 B +unpacked size: 624 B +shasum: {shasum} +integrity: {integrity} +total files: 12 + +Published to https://registry.npmjs.org with tag "latest" + + โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€” + + > NX Successfully ran target nx-release-publish for 3 projects + +``` + +## Manage Git Operations + +By default, Nx Release will stage all changes it makes with git. This includes updating `package.json` files, creating changelog files, and updating the `package-lock.json` file. After staging the changes, Nx Release will commit the changes and create a git tag for the release. + +### Customize the Commit Message and Tag Pattern + +The commit message created by Nx Release defaults to 'chore(release): publish {version}', where `{version}` will be dynamically interpolated with the relevant value based on your actual release, but can be customized with the `release.git.commitMessage` property in nx.json. + +The structure of the git tag defaults to `v{version}`. For example, if the version is `1.2.3`, the tag will be `v1.2.3`. This can be customized by setting the `release.releaseTagPattern` property in nx.json. + +For this same example, if you want the commit message to be 'chore(release): 1.2.3' and the tag to be `release/1.2.3`, you would configure nx.json like this: + +```json nx.json +{ + "release": { + "releaseTagPattern": "release/{version}", + "git": { + "commitMessage": "chore(release): {version}" + } + } +} +``` + +## Future Releases + +After the first release, the `--first-release` option will no longer be required. Nx Release will expect to find git tags and changelog files for each package. It will also use `npm view` to look up the current version of packages before publishing, ensuring that the package has not already been published and therefore avoid any conflict errors, meaning you can run the same publish action multiple times without any negative side-effects. + +Future releases will also generate entries in `CHANGELOG.md` based on the changes since the last release. Nx Release will parse the commits according to the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) specification and sort them into the appropriate sections of the changelog. An example of these changelogs can be seen on the [Nx releases page](https://github.com/nrwl/nx/releases). diff --git a/docs/shared/recipes/nx-release/release-projects-independently.md b/docs/shared/recipes/nx-release/release-projects-independently.md new file mode 100644 index 0000000000000..ba69c467f1062 --- /dev/null +++ b/docs/shared/recipes/nx-release/release-projects-independently.md @@ -0,0 +1,93 @@ +# Release Projects Independently + +Nx Release supports releasing projects independently. This is useful when you have a monorepo with projects that are not released on the same schedule. + +## Configure Independent Releases + +To configure independent releases, add the following property to your `nx.json` file: + +```nx.json +{ + "release": { + "projectsRelationship": "independent" + } +} +``` + +## Differences from Fixed Releases + +Nx release will behave differently when configured for independent releases. + +### Prompt for Multiple Version Bumps + +When configured for independent releases, Nx Release will prompt for a version bump for each project that is being released. This allows the version of each project to differ over time. + +### Create a Git Tag for Each Project + +Since each project can have a different version, Nx Release will create a git tag for each project that is being released. By default, the tag for each project will follow the pattern `{projectName}@{version}`. For example, if the `pkg-1` project is being released with version `1.1.0`, its git tag will be `pkg-1@1.1.0`. + +This can still be changed with the `release.releaseTagPattern` property in `nx.json`, but be sure to include `{projectName}` in the pattern so that each generated tag is unique. + +For example, to generate the tags `release/pkg-1/1.1.0` and `release/pkg-2/1.2.1` for the `pkg-1` and `pkg-2` projects respectively, you would use the following configuration in nx.json: + +```json nx.json +{ + "release": { + "releaseTagPattern": "release/{projectName}/{version}" + } +} +``` + +### Different Commit Message Structure + +Even though Nx Release creates a git tag for each project, it will still create a single commit for the entire release. The commit message will still include all of the projects being released with their corresponding version. For example: + +``` +chore(release): publish + + - project: pkg-1 1.1.0 + + - project: pkg-2 1.2.1 + + - project: pkg-3 2.5.7 +``` + +### Changelogs + +Nx Release will no longer generate and update a workspace level `CHANGELOG.md` file when configured for independent releases. If you still want changelog generation, you will need to enable project level changelogs. These are similar to the workspace level changelog, but they are generated for each project individually and only contain changes for that specific project. They can be configured with the `release.changelog.projectChangelogs` property in `nx.json`. + +```json nx.json +{ + "release": { + "changelog": { + "projectChangelogs": true + } + } +} +``` + +Just like with [fixed releases](/recipes/nx-release/get-started-with-nx-release), you can preview changes to the changelog files by running Nx Release with the `--dry-run` option. + +## Use the Projects Filter + +One of the key benefits of independent releases is the ability to release only a subset of projects. Nx Release supports this with the `--projects` option. The value is an array of strings, and you can use any of the same specifiers that are supported by `nx run-many`'s [projects filtering](/nx-api/nx/documents/run-many), such as explicit project names, Nx tags, directories and glob patterns, including negation using the `!` character. A few examples: + +Release only the `pkg-1` and `pkg-2` projects: + +```shell +nx release --projects=pkg-1,pkg-2 +``` + +Release all projects in the `server` directory: + +```shell +nx release --projects=server/* +``` + +Release all projects except those in the `ui` directory: + +```shell +nx release --projects='!ui/*' +``` + +All other projects in the workspace will be ignored and only those that match the filter will be versioned, have their changelogs updated, and published. diff --git a/docs/shared/reference/sitemap.md b/docs/shared/reference/sitemap.md index 33997654452c8..5382a5bc487c8 100644 --- a/docs/shared/reference/sitemap.md +++ b/docs/shared/reference/sitemap.md @@ -191,6 +191,10 @@ - [Project Pane](/recipes/nx-console/console-project-pane) - [Keyboard Shortcuts](/recipes/nx-console/console-shortcuts) - [Troubleshooting](/recipes/nx-console/console-troubleshooting) + - [Nx Release](/recipes/nx-release) + - [Get Started with Nx Release](/recipes/nx-release/get-started-with-nx-release) + - [Release Projects Independently](/recipes/nx-release/release-projects-independently) + - [Automatically Version with Conventional Commits](/recipes/nx-release/automatically-version-with-conventional-commits) - [Other](/recipes/other) - [Rescope Packages from @nrwl to @nx](/recipes/other/rescope) - [Showcase](/showcase)