Multi-Package Release Management (m release)
Framework M provides the m release command suite to automate the complex lifecycle of versioning, changelog generation, dependency pinning, and release tagging across multi-package monorepos and standalone applications.
1. How It Works
The release system follows the Conventional Commits specification (feat:, fix:, chore:, etc.):
- Commit Inspection: Scans git commit messages affecting specific package directories.
- SemVer Calculation:
- Commits with
feat(...)trigger minor version bumps (0.1.0->0.2.0). - Commits with
fix(...)trigger patch version bumps (0.1.0->0.1.1). - Breaking changes (
feat!:orBREAKING CHANGE:) trigger major bumps (1.0.0->2.0.0). - Commits with
chore,docs,refactor,testdo not trigger version bumps on their own.
- Commits with
- Workspace Dependency Sync: Automatically updates dependent packages to point to the newly bumped internal versions.
- Changelog Generation: Generates clean, grouped release notes prepended to each package's
CHANGELOG.md. - SBOM Generation: Produces a Software Bill of Materials (SBOM) using Syft.
- Tagging & Forge Release: Creates annotated git tags (e.g.
package-name@v1.2.0) and GitLab/GitHub Releases with release notes.
2. Configuration: release-config.json
Every project or monorepo using m release defines a release-config.json file in its root directory:
{
"packages": [
{
"name": "my-app-core",
"publish_name": "my-app-core",
"version_file": "packages/core/pyproject.toml",
"paths": ["packages/core"],
"scopes": ["core"],
"include_global": false
},
{
"name": "my-app-ui",
"publish_name": "@my-app/ui",
"version_file": "packages/ui/package.json",
"paths": ["packages/ui"],
"scopes": ["ui"],
"include_global": false
}
],
"sync": [
{
"file": "apps/**/package.json",
"package_name": "my-app-ui"
}
],
"target_branch": "main",
"release_branch": "release/next",
"enable_sbom": true,
"provider": "gitlab"
}
Key Properties
packages: Array of managed packages.name: Internal workspace name.publish_name: Name used for package registry publication (PyPI / NPM).version_file: Path to file holding version string (pyproject.tomlorpackage.json).paths: List of directory paths belonging to this package.scopes: Conventional commit scope names associated with this package (e.g.,feat(core): ...).
sync: Target files outside the package directory that need their dependency versions synchronized when a package is bumped.provider: Default forge provider (gitlaborgithub).
3. CLI Commands
The m release commands are available via framework-m-studio.
1. m release plan
Preview which packages require version bumps and what those bumps will be without making any changes:
uv run m release plan
# Output as JSON
uv run m release plan --json
2. m release prepare
Prepares the release branch locally or in CI:
- Updates version numbers in
pyproject.tomlorpackage.json. - Synchronizes dependent workspace packages and sync targets.
- Prepend entries to each package's
CHANGELOG.md. - Generates SBOM files when
enable_sbomis true.
uv run m release prepare --branch release/next
# Dry-run preview
uv run m release prepare --dry-run
3. m release mr
Creates or updates a Merge Request / Pull Request from the release branch (e.g. release/next) targeting main:
uv run m release mr --branch release/next --target-branch main
4. m release tag
Scans changelogs and commit history, creates annotated git tags (<package>@v<version>), pushes them to the remote origin, and publishes release entries on GitLab or GitHub:
uv run m release tag
# Preview tags without creating or pushing
uv run m release tag --dry-run
5. m release auto
Runs the complete automated end-to-end pipeline (used in CI on push to main):
- Evaluates commit history.
- Checks out the release branch (
release/next). - Executes
prepare. - Pushes the release branch.
- Opens or updates the release Merge Request.
uv run m release auto --provider gitlab
6. m release lint-scopes
Validates that all files modified in a commit or MR range belong to a known package scope defined in release-config.json:
uv run m release lint-scopes --base origin/main --head HEAD