diff --git a/docs/design/design-patterns/rest-api-design-guidance.md b/docs/design/design-patterns/rest-api-design-guidance.md index dba5bc8b3b..ff311439e8 100644 --- a/docs/design/design-patterns/rest-api-design-guidance.md +++ b/docs/design/design-patterns/rest-api-design-guidance.md @@ -91,6 +91,5 @@ In particular, when working in an existing API ecosystem, be sure to align with * [Detailed HTTP status code definitions](https://www.restapitutorial.com/httpstatuscodes.html) * [Semantic Versioning](https://semver.org/) * [Other Public API Guidelines](http://apistylebook.com/design/guidelines/) -* [OpenAPI Design Practices](https://oai.github.io/Documentation/best-practices.html) * [Microsoft TypeSpec](https://github.com/Microsoft/typespec) * [Microsoft TypeSpec GitHub Workflow samples](https://github.com/cse-labs/typespec-workflow-samples/) diff --git a/docs/source-control/assets/monorepo-git-tags.png b/docs/source-control/assets/monorepo-git-tags.png new file mode 100644 index 0000000000..748aba49e7 Binary files /dev/null and b/docs/source-control/assets/monorepo-git-tags.png differ diff --git a/docs/source-control/assets/monorepo.png b/docs/source-control/assets/monorepo.png new file mode 100644 index 0000000000..3e8b5c26c6 Binary files /dev/null and b/docs/source-control/assets/monorepo.png differ diff --git a/docs/source-control/component-versioning.md b/docs/source-control/component-versioning.md index ec6951e207..083efb34b9 100644 --- a/docs/source-control/component-versioning.md +++ b/docs/source-control/component-versioning.md @@ -58,8 +58,96 @@ Version updates happen through: * Branch names (e.g. develop, release/..) for Alpha / Beta / RC * Otherwise: Number of commits (+12, ...) +## Semantic Versioning within a Monorepo + +A monorepo, short for "monolithic repository", is a software development practice where multiple related projects, components, or modules are stored within a single version-controlled repository as opposed to maintaining them in separate repositories. + +drawing + +### Challenges with Versioning in a monorepo structure + +Versioning in a monorepo involves making decisions about how to assign version numbers to different projects and components contained within the repository. + +Assigning a single version number to all projects in a monorepo can lead to frequent version increments if changes in one project don't match the significance of changes in another. This might be excessive if some projects undergo rapid development while others evolve more slowly. + +Ideally, we would want each project within the monorepo to have its own version number. Changes in one project shouldn't necessarily trigger version changes in others. +This strategy allows projects to evolve at their own pace, without forcing all projects to adopt the same version number. It aligns well with the differing release cadences of distinct projects. + +### semantic-release package for versioning + +[semantic-release](https://github.com/semantic-release/semantic-release) simplifies the entire process of releasing a package, which encompasses tasks such as identifying the upcoming version number, producing release notes, and distributing the package. This process severs the direct link between human sentiments and version identifiers. Instead, it rigorously adheres to the Semantic Versioning standards and effectively conveys the significance of alterations to end users. + +`semantic-release` relies on commit messages to assess how codebase changes impact consumers. By adhering to structured conventions for commit messages, `semantic-release` autonomously identifies the subsequent semantic version, compiles a changelog, and releases the software. + +[Angular Commit Message](https://gist.github.com/brianclements/841ea7bffdb01346392c) Conventions serve as the default for `semantic-release`. However, the configuration options of the @semantic-release/commit-analyzer and @semantic-release/release-notes-generator plugins, including presets, can be adjusted to modify the commit message format. + +The table below shows which commit message gets you which release type when `semantic-release` runs (using the default configuration): + +| Commit message | Release type | +|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------| +| fix(pencil): stop graphite breaking when too much pressure applied | Patch Fix Release | +| feat(pencil): add 'graphiteWidth' option | Minor Feature Release | +| perf(pencil): remove graphiteWidth option
BREAKING CHANGE: The graphiteWidth option has been removed. The default graphite width of 10mm is always used for performance reasons. | Major Breaking Release
(Note that the BREAKING CHANGE: token must be in the footer of the commit) | + + +The inherent setup of `semantic-release` presumes a direct correspondence between a GitHub repository and a package. Hence changes anywhere in the project result in a version upgrade for the project. + +The [semantic-release-monorepo](https://github.com/pmowrer/semantic-release-monorepo) tool permits the utilization of `semantic-release` within a solitary GitHub repository that encompasses numerous packages. + +Instead of attributing all commits to a single package, commits are assigned to packages based on the files that a commit touched. + +If a commit touches a file in or below a package's root, it will be considered for that package's next release. A single commit can belong to multiple packages and may trigger the release of multiple packages. + +In order to avoid version collisions, generated git tags are namespaced using the given package's name: ``-``. + +![monorepo-git-tags](./assets/monorepo-git-tags.png) + +### semantic-release configurations + +`semantic-release`’s options, mode and plugins can be set via either: + +- A .releaserc file, written in YAML or JSON, with optional extensions: .yaml/.yml/.json/.js/.cjs +- A release.config.(js|cjs) file that exports an object +- A release key in the project's package.json file + +Here is an example .releaserc file which contains the configuration for: +1. git tags for the releases from different types of branches +2. Any plugins required, list of supported plugins can be found [here](https://semantic-release.gitbook.io/semantic-release/extending/plugins-list). In this file *semantic-release-monorepo* plugin is extended. + +```json +{ + "ci": true, + "repositoryUrl": "your repository url", + "branches": [ + "master", + { + "name": "feature/*", + "prerelease": "beta-${name.replace(/\\//g, '-').replace(/_/g, '-')}" + }, + { + "name": "[a-zA-Z0-9_]+/[a-zA-Z0-9-_]+", + "prerelease": "dev-${name.replace(/\\//g, '-').replace(/_/g, '--')}" + } + ], + "plugins": [ + "@semantic-release/commit-analyzer", + "@semantic-release/release-notes-generator", + [ + "@semantic-release/exec", + { + "verifyReleaseCmd": "echo ${nextRelease.name} > .VERSION" + } + ], + "semantic-release-ado" + ], + "extends": "semantic-release-monorepo" + } +``` + ## Resources * [GitVersion](https://gitversion.net/) * [Semantic Versioning](https://semver.org/) * [Versioning in C#](https://learn.microsoft.com/en-us/dotnet/csharp/versioning) +* [semantic-release](https://github.com/semantic-release/semantic-release) +* [semantic-release-monorepo](https://github.com/pmowrer/semantic-release-monorepo)