# RepoPlone

<div align="center">

[![PyPI](https://img.shields.io/pypi/v/repoplone)](https://pypi.org/project/repoplone/)
[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/repoplone)](https://pypi.org/project/repoplone/)
[![PyPI - Wheel](https://img.shields.io/pypi/wheel/repoplone)](https://pypi.org/project/repoplone/)
[![PyPI - License](https://img.shields.io/pypi/l/repoplone)](https://pypi.org/project/repoplone/)
[![PyPI - Status](https://img.shields.io/pypi/status/repoplone)](https://pypi.org/project/repoplone/)


[![Code Quality](https://github.com/plone/repoplone/actions/workflows/main.yml/badge.svg)](https://github.com/plone/repoplone/actions/workflows/main.yml)

[![GitHub contributors](https://img.shields.io/github/contributors/plone/repoplone)](https://github.com/plone/repoplone)
[![GitHub Repo stars](https://img.shields.io/github/stars/plone/repoplone?style=social)](https://github.com/plone/repoplone)

</div>

## 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:

```sh
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`:

```sh
export UV_PUBLISH_TOKEN=<MYTOKEN>
```

or by using the `uv auth login pypi.org` command, as explained [here](https://docs.astral.sh/uv/concepts/authentication/cli/#the-uv-auth-cli).

#### NPM

```sh
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.

```sh
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:

```toml
[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](#repositorytoml-specification) for more information.

### List Available Commands
To see all available commands, run:

```bash
uvx repoplone
```

### Check Installed Version
To check the installed version of the tool, use:

```bash
uvx repoplone --version
```

## Check repository versions

### Current versions

List current versions for:

- Repository
- Backend package
- Frontend package

```bash
uvx repoplone versions current
```

### Next versions

Report next version of all components of this repository:

- Repository
- Backend package
- Frontend package

```bash
uvx repoplone versions next
```

### Dependencies

Report version information for major dependencies:

- Backend base package
- Frontend base package
- Frontend @plone/volto package

```bash
uvx repoplone versions dependencies
```

## Preview Changelog

To generate and display the draft changelog, run:

```bash
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:**

```bash
uvx repoplone release a
```

This will create an `alpha` release.

---

## 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:

```bash
uvx repoplone deps info
```

#### Check version
To check the current base package version, run:

```bash
uvx repoplone deps check
```

#### Upgrade version

To upgrade the base package to a specific version, use:

```bash
uvx repoplone deps upgrade 6.1.1
```

## `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"`                        |                                                                                                                                                              |
| `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`                               |                                                                                                                                                              |

## Contribute 🤝

We welcome contributions to RepoPlone.

You can create an issue in the issue tracker, or contact a maintainer.

- [Issue Tracker](https://github.com/plone/repoplone/issues)
- [Source Code](https://github.com/plone/repoplone/)

### Development requirements

- [uv](https://docs.astral.sh/uv/)

### Setup

Clone this repository:

```sh
git clone git@github.com:plone/repoplone.git
```

Install `UV`, and create a local virtual environment with the following command.

```shell
make install
```

### Run the checked out branch of RepoPlone

```shell
uv run repoplone
```

### Check and format the codebase

```shell
make check
```

### Run tests

[`pytest`](https://docs.pytest.org/) is this package's test runner.

Run all tests with the following command.

```shell
make test
```

Run all tests, but stop on the first error and open a `pdb` session with the following command.

```shell
uv run pytest -x --pdb
```

Run only tests that match `test_release_backend` with the following command.

```shell
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.

```shell
uv run pytest -k test_release_backend -x --pdb
```

### Run type checker

We use [`mypy`](https://www.mypy-lang.org/) to run static type checking for this codebase.

Run the checker with the following command.

```shell
uv run mypy src
```


## Support 📢

For support, questions, or more detailed documentation, visit the [official RepoPlone repository](https://github.com/plone/repoplone).


## This project is supported by

<p align="left">
    <a href="https://plone.org/foundation/">
      <img alt="Plone Foundation Logo" width="200px" src="https://raw.githubusercontent.com/plone/.github/main/plone-foundation.png">
    </a>
</p>

## License

The project is released under the [MIT License](./LICENSE).
