Skip to main content

Runtime Version Management

Framework M enforces reproducible and predictable language execution environments across both backend (Python) and frontend (Node.js) codebases using a declarative configuration file: runtime-config.json.

The m runtime CLI suite provides commands to inspect, synchronize, and automatically upgrade runtime versions across repository configuration files.


1. Principles: Runtimes vs. Package Managers​

A central architectural principle of Framework M is the clear separation between language runtimes and package managers:

AspectRuntimesPackage Managers
ScopeExecution environments (Node.js, Python)Dependency resolution & installation tools
Governed byruntime-config.jsonProject developer preference (pnpm, yarn, bun, npm for JS; uv, poetry, pip for Python)
StrategyNode: Latest Even LTS; Python: Distro-aligned baselinesUser-managed lockfiles (pnpm-lock.yaml, uv.lock, etc.)

:::tip No Forced Package Managers Framework M does not hardcode package managers into runtime management. When m runtime updates package.json, it updates only devEngines.runtime (node). It preserves the project's existing devEngines.packageManager configuration without overriding it with pnpm. :::


2. Declarative Configuration: runtime-config.json​

The root of any Framework M project or monorepo contains a runtime-config.json file. It specifies the resolution strategy and target files for each language runtime.

{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"runtimes": [
{
"name": "node",
"strategy": "latest_even",
"feed_url": "https://nodejs.org/dist/index.json",
"targets": [
{
"file": ".gitlab-ci.yml",
"pattern": "(NODE_VERSION:\\s*)\"?\\d+\"?",
"replacement": "$1\"{{version}}\""
},
{
"file": "package.json",
"pattern": "(\"name\":\\s*\"node\",\\s*\"version\":\\s*\">=)\\d+\\.0\\.0\"",
"replacement": "$1{{version}}.0.0\""
}
]
},
{
"name": "python",
"strategy": "distro_aligned",
"min_version": "3.12",
"default_version": "3.12",
"supported_versions": ["3.12", "3.15"],
"distro_matrix": {
"debian": { "12_bookworm": "3.11", "13_trixie": "3.13" },
"ubuntu": { "22.04_lts": "3.10", "24.04_lts": "3.12", "26.04_lts": "3.14" },
"rhel": { "rhel_9": "3.11", "rhel_10": "3.12" }
},
"targets": [
{
"file": ".gitlab-ci.yml",
"pattern": "(PYTHON_VERSION:\\s*)\"?3\\.\\d+\"?",
"replacement": "$1\"{{default_version}}\""
},
{
"file": "pyproject.toml",
"pattern": "(requires-python\\s*=\\s*\">=)3\\.\\d+\"",
"replacement": "$1{{min_version}}\""
}
]
}
]
}

Strategies​

  • latest_even (Node.js): Queries the official release feed and filters for the highest even major version (e.g. Node 24, 26).
  • distro_aligned (Python): Ensures Python baselines align with major enterprise Linux distributions (Debian, Ubuntu LTS, RHEL). Enforces a minimum baseline of >=3.12.
  • fixed: Pin to a specific explicit version.

3. CLI Commands​

The m runtime CLI commands are available via the Studio CLI (framework-m-studio).

Check Runtime Versions​

Inspect the current runtime configuration, resolve upstream versions, and detect active package managers:

uv run m runtime check

Options:

  • --root <PATH>: Path to the workspace root directory (default: current directory).

Synchronize Target Files​

Apply the resolved or specified runtime versions to all target files declared in runtime-config.json:

uv run m runtime sync

Options:

  • --root <PATH>: Workspace root directory.
  • --node-version <VER>: Override Node.js target version explicitly (e.g. --node-version 24).

Automated Upgrade & Lockfile Refresh​

m runtime upgrade runs the full automated update lifecycle:

  1. Checks and updates all targets in runtime-config.json.
  2. Synchronizes package.json devEngines.runtime.
  3. Auto-detects the repository's package managers and refreshes the lockfiles:
    • For JS/TS: Runs pnpm install, yarn install, or npm install depending on what is detected.
    • For Python: Runs uv lock or poetry lock.
  4. Stashes changes in a dedicated git branch (runtime/upgrade-<timestamp>), commits them with conventional format (chore(runtime): ...), and opens a Merge Request (GitLab) or Pull Request (GitHub) if credentials are provided.
uv run m runtime upgrade

Options:

  • --root <PATH>: Workspace root directory.
  • --provider <gitlab|github>: Git forge provider (default: gitlab).
  • --token <TOKEN>: Personal access token or CI token.
  • --project-id <ID>: GitLab project ID or GitHub owner/repo.
  • --dry-run: Preview updates without modifying files, committing, or pushing.
  • --skip-branch: Apply updates and refresh lockfiles directly in the current working tree without creating a git branch or commit.

4. CI/CD Integration​

In .gitlab-ci.yml, the runtime maintenance job can be triggered on a scheduled pipeline or manually:

runtime-maintenance:
extends: .maintenance-base
stage: test
script:
- uv sync --all-packages --all-extras --all-groups --cache-dir ${UV_CACHE_DIR}
- uv run m runtime upgrade
rules:
- if: $CHECK_RUNTIMES == "true"
when: always
- if: $CI_PIPELINE_SOURCE == "schedule"
when: always

To trigger manually via the GitLab UI:

  1. Navigate to Pipelines > Run Pipeline.
  2. Add environment variable: CHECK_RUNTIMES = true.