RepoPlone
Overview
The RepoPlone is a tool designed to manage mono repos containing a repository.toml configuration file at the repository root.
It provides various commands to streamline repository management, versioning, and release processes.
Setup
Installation
To use the latest version of this tool, run the command:
uvx repoplone
Authentications
PyPi
We use uv to make the release, please make sure authentication is in place by setting the environment variable UV_PUBLISH_TOKEN:
export UV_PUBLISH_TOKEN=<MYTOKEN>
or by using the uv auth login pypi.org command, as explained here.
NPM
npm whoami
GitHub
To add releases to GitHub, you should have an environment variable GITHUB_TOKEN set -- with a valid token -- before running this tool.
export GITHUB_TOKEN='<token>'
Usage
Prepare the repository
Ensure that your monorepo contains a repository.toml file. Below is an example of such a configuration:
[repository]
name = "fake-distribution"
changelog = "CHANGELOG.md"
version = "version.txt"
version_format = "semver"
container_images_prefix = "ghcr.io/collective/fake-distribution"
compose = ["docker-compose.yml"]
[repository.towncrier]
section = "Project"
settings = "towncrier.toml"
[backend.package]
name = "fake.distribution"
path = "backend"
python_version = "3.13"
python_versions = ["3.11", "3.12", "3.13"]
plone_versions = ["6.1", "6.2"]
changelog = "backend/CHANGELOG.md"
towncrier_settings = "backend/pyproject.toml"
base_package = "Products.CMFPlone"
publish = false
[frontend.package]
name = "fake-distribution"
path = "frontend/packages/fake-distribution"
changelog = "frontend/packages/fake-distribution/CHANGELOG.md"
towncrier_settings = "frontend/packages/fake-distribution/towncrier.toml"
publish = false
Please refer to repository.toml Specification for more information.
List Available Commands
To see all available commands, run:
uvx repoplone
Check Installed Version
To check the installed version of the tool, use:
uvx repoplone --version
Check repository versions
Current versions
List current versions for:
- Repository
- Backend package
- Frontend package
uvx repoplone versions current
Next versions
Report next version of all components of this repository:
- Repository
- Backend package
- Frontend package
uvx repoplone versions next
Dependencies
Report version information for major dependencies:
- Backend base package
- Frontend base package
- Frontend @plone/volto package
uvx repoplone versions dependencies
Preview Changelog
To generate and display the draft changelog, run:
uvx repoplone changelog
Releasing Monorepo Packages
The release command creates a new release and accepts the following arguments:
desired_version
The desired_version argument defines the new version to be used in the release. It can be a specific version number or a version segment.
Semantic Versioning
For projects using Semantic Versioning -- the default for repoplone --, below is a reference table showing how version segments modify an existing 1.0.0 version:
| Segment | New Version |
|---|---|
release |
1.0.0 |
major |
2.0.0 |
minor |
1.1.0 |
micro / patch / fix |
1.0.1 |
a / alpha |
1.0.0a0 |
b / beta |
1.0.0b0 |
c / rc / pre / preview |
1.0.0rc0 |
r / rev / post |
1.0.0.post0 |
dev |
1.0.0.dev0 |
If not provided, you will be prompted to select a version from a list of most probable version options:
01/09 Select the next version
1 - 1.0.1 (micro)
2 - 1.1.0 (minor)
3 - 2.0.0 (release)
Choose from [1/2/3] (1):
Calendar Versioning
For projects that have the value of version_format set as calver, the desired_version, by default, will compute the next available version.
Examples:
| Current Version | Date | Next Version |
|---|---|---|
| 20250404.1 | 2026-02-13 | 20260213.1 |
| 20260213.1 | 2026-02-13 | 20260213.2 |
--dry-run
Use this flag to simulate the release process without actually publishing the new version.
Example:
uvx repoplone release a
This will create an alpha release.
Configuring the release pipeline
By default, repoplone runs a fixed sequence of steps when releasing. Projects
can override that sequence in repository.toml under [repository.release].
Built-in step ids: changelog, version, repository, release_backend,
release_frontend, git, gh_release, bye. The default order matches
that list.
Reordering or omitting built-in steps
[repository.release]
steps = [
"changelog",
"version",
"repository",
"release_backend",
"git",
"bye",
]
The example above skips release_frontend and gh_release.
Running a project-local hook
The local_step built-in imports a callable from the project root and runs
it under the standard step contract:
def step(step_id, title, settings, state, **kwargs) -> bool: ...
Wire it via a registry alias. The alias id is what you put in steps:
[repository.release]
steps = ["changelog", "version", "repository", "notify_slack", "git", "bye"]
[repository.release.registry.notify_slack]
title = "Notify internal Slack"
function = "local_step"
args = { entrypoint = "scripts.notify:hook", channel = "#releases" }
Repoplone adds the project root to sys.path before resolving the
entrypoint, so a hook at scripts/notify.py is reachable as
scripts.notify:hook. Any keys in args other than entrypoint are
forwarded to the hook as keyword arguments.
uvx caveat. Because
uvx repoploneruns in an isolated environment, a local hook may only use the standard library plus packages repoplone itself depends on. Third-party packages installed in the project's own environment are not available to the hook.
local_step cannot appear in steps directly — it must be wrapped in a
registry alias that supplies args.entrypoint.
Validating the configuration
Before committing a [repository.release] change, validate it:
uvx repoplone settings sanity-check
This loads the settings and resolves every local_step entrypoint. It
exits non-zero with a precise message if anything fails.
To inspect the resolved pipeline:
uvx repoplone settings release-steps # human-readable table
uvx repoplone settings release-steps --json # machine-readable
Dependencies
Manage backend's base package
The following commands are available exclusively for projects managed by UV and with a base_package set in the [backend.package] section of repository.toml.
Report the base package
To check which is the current base package, run:
uvx repoplone deps info
Check version
To check the current base package version, run:
uvx repoplone deps check
Upgrade version
To upgrade the base package to a specific version, use:
uvx repoplone deps upgrade backend 6.1.1
Upgrade a frontend distribution
Repoplone can take care of upgrading a frontend distribution and ensuring that all frontend package versions in the project remain consistent with the distribution.
It reads the base_package set in the [frontend.package] section of repository.toml.
uvx repoplone deps upgrade frontend 3.0.0
you can also use latest to upgrade to the most recent version of the frontend distribution.
uvx repoplone deps upgrade frontend latest
When you have a project that is based on a distribution, we need to make sure that the versions of the frontend packages in the project are consistent with the versions in the distribution and that these versions are all in sync across all the build.
When creating a distribution, make sure to stamp the Volto version as described in the next section.
Then repoplone can use that stamped Volto version to enforce consistency across all frontend packages in the project.
When the distribution has the volto_version field stamped in package.json, repoplone also fetches its enforced dependencies and volto_version from the npm registry and writes them to frontend/distribution.json.
That file is consumed by the project's .pnpmfile.cjs hook, which overrides those versions across the whole
workspace at install time.
The @plone/volto tag in the project's mrs.developer.json is aligned to the distribution's volto_version as well.
Stamp the Volto version when releasing a distribution
The volto_version field described above is what identifies a package as a Volto
distribution. When you release a distribution, stamp that field from the Volto
core tag checked out via mrs.developer.json:
uvx repoplone deps stamp-volto-version
This reads the @plone/volto tag from mrs.developer.json and writes it verbatim
to the frontend package's package.json volto_version field. It is typically
wired into a release-it hook so the published package advertises the Volto core
it targets. For example, in the distribution package's .release-it.json:
{
"hooks": {
"after:bump": [
"uvx repoplone deps stamp-volto-version",
"git add package.json"
]
}
}
The command is cwd-independent inside the repository (it locates repository.toml
by walking up), so it works from the package directory where release-it runs.
Install from a Git branch
To track an unreleased branch of the base package, pass the branch name prefixed
with @:
uvx repoplone deps upgrade backend @main
This resolves the constraints from the branch's pyproject.toml and pins the
base package to the branch through a [tool.uv.sources] entry instead of a
version specifier. The base package must declare repository information to be
installable this way.
repository.toml Specification
This section outlines the format and available options for the repository.toml file used in the project. Each section is detailed below, along with the available options and their default values.
| Section | Option | Description | Example Value | Default Value Source |
|---|---|---|---|---|
repository |
name |
Name of the repository. | "collective-addon" |
|
changelog |
Path to the changelog file. | "CHANGELOG.md" |
||
version |
Path to the version file of this repository. | "version.txt" |
||
container_images_prefix |
Prefix for container images. We will add the -backend and -frontend suffixes to generate the final images. |
"ghcr.io/collective/collective-addon" |
||
compose |
List of Docker Compose files. | ["docker-compose.yml"] |
||
version_format |
Format of the versioning. | "semver" or "calver" |
||
issues_url |
URL where issues for this repository are tracked. | "https://github.com/plone/repoplone/issues" |
Empty by default. When unset and the git origin points at GitHub, the value is derived as https://github.com/<owner>/<repo>/issues. |
|
repository.towncrier |
enabled |
Whether a top-level Towncrier is enabled. | true or false |
Calculated if a section is present in repository.toml |
section |
Section name used by Towncrier. | "Project" |
||
settings |
Path to Towncrier settings. | "towncrier.toml" |
||
backend.package |
enabled |
Whether the backend package is enabled. | true or false |
Calculated if a section is present in repository.toml |
name |
Name of the backend package. | "collective.addon" |
||
path |
Path to the backend package. | "backend" |
||
python_version |
Base Python version for the package. (Used in tests) | "3.11" |
If value is not present in repository.toml, repoplone will inspect pyproject.toml project.classifiers and return the first supported Python version. |
|
python_versions |
List of supported Python versions. | ["3.10", "3.11", "3.12"] |
If value is not present in repository.toml, repoplone will inspect pyproject.toml project.classifiers and return all supported Python versions. |
|
plone_versions |
List of supported Plone versions. | ["6.0", "6.1"] |
If value is not present in repository.toml, repoplone will inspect pyproject.toml project.classifiers and return all supported Plone versions. |
|
changelog |
Path to the changelog for the backend. | "backend/CHANGELOG.md" |
||
code_path |
Path to the source code. | "src/collective/addon" |
||
towncrier_settings |
Path to Towncrier settings for backend. | "backend/pyproject.toml" |
||
publish |
Whether to publish the backend package to PyPI. | true or false |
||
frontend.package |
enabled |
Whether the frontend package is enabled. | true or false |
Calculated if a section is present in repository.toml |
name |
Name of the frontend package. | "@plone-collective/volto-addon" |
||
path |
Path to the frontend package. | "frontend/packages/volto-addon" |
||
code_path |
Path to the source code. | "src" |
||
changelog |
Path to the changelog for the frontend. | "frontend/CHANGELOG.md" |
||
towncrier_settings |
Path to Towncrier settings for frontend. | "frontend/packages/volto-addon/towncrier.toml" |
||
publish |
Whether to publish the frontend package to npm. | true or false |
||
base_package |
Name of the frontend base package (e.g. a Volto distribution). | "@kitconcept/intranet" |
Defaults to "@plone/volto". |
Contribute 🤝
We welcome contributions to RepoPlone.
You can create an issue in the issue tracker, or contact a maintainer.
Development requirements
Setup
Clone this repository:
git clone git@github.com:plone/repoplone.git
Install UV, and create a local virtual environment with the following command.
make install
Run the checked out branch of RepoPlone
uv run repoplone
Check and format the codebase
make check
Run tests
pytest is this package's test runner.
Run all tests with the following command.
make test
Run all tests, but stop on the first error and open a pdb session with the following command.
uv run pytest -x --pdb
Run only tests that match test_release_backend with the following command.
uv run pytest -k test_release_backend
Run only tests that match test_release_backend, but stop on the first error and open a pdb session with the following command.
uv run pytest -k test_release_backend -x --pdb
Run type checker
We use mypy to run static type checking for this codebase.
Run the checker with the following command.
uv run mypy src
Support 📢
For support, questions, or more detailed documentation, visit the official RepoPlone repository.
This project is supported by
License
The project is released under the MIT License.
Metadata
Release files for RepoPlone 1.1.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| repoplone-1.1.3.tar.gz | 4.2 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| repoplone-1.1.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 4.3 MB
Release files / repoplone-1.1.3.tar.gz
| Download URL | repoplone-1.1.3.tar.gz |
|---|---|
| Size | 4.2 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
dc270654be185ce1a2319e3f8d120fa217fe3dfce18352084fcacb28cfab7e90
|
|
BLAKE2b-256 checksum How to use checksums |
2a310078535273c4f280fa95990f2fd89ac0fdfa2d830f0396da5ae6344b1a0f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / repoplone-1.1.3-py3-none-any.whl
| Download URL | repoplone-1.1.3-py3-none-any.whl |
|---|---|
| Size | 63.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f696c11dc6621260937d8be7956ee9c8673ebfd36dd76b8f7f4cda425c36b4de
|
|
BLAKE2b-256 checksum How to use checksums |
925a5f58a5fac12b9d90e2dc0569cd03af6fc3631f47adcd236a35f8557581ee
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|