From ddf6387a7686c0bb95ae04da047d8a1b52d02880 Mon Sep 17 00:00:00 2001 From: Frank Niessink Date: Sat, 8 Jun 2024 23:29:51 +0200 Subject: [PATCH] Added a versioning policy to the documentation. Closes #8748. --- docker/docker-compose.yml | 2 +- docs/src/changelog.md | 13 +-- docs/src/deployment.md | 14 +++- docs/src/development.md | 12 +-- docs/src/index.md | 1 + docs/src/software.md | 8 +- docs/src/versioning.md | 79 +++++++++++++++++++ .../config/vocabularies/Base/accept.txt | 1 + .../config/vocabularies/Base/reject.txt | 3 + release/release.py | 34 ++++++-- 10 files changed, 141 insertions(+), 26 deletions(-) create mode 100644 docs/src/versioning.md diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index d9e80ca256..d9e8d5bf4d 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -1,4 +1,4 @@ -# Base docker composition. For development, this composition is augmented in docker-compose.override.yml. +# Base Docker-composition. For development, this composition is augmented in docker-compose.override.yml. services: www: diff --git a/docs/src/changelog.md b/docs/src/changelog.md index eb8dd9c037..eb4f5afed7 100644 --- a/docs/src/changelog.md +++ b/docs/src/changelog.md @@ -12,7 +12,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) ### Deployment notes -If your currently installed *Quality-time* version is v4.10.0 or older, please read the v5.0.0 deployment notes first. +If your currently installed *Quality-time* version is not v5.13.0, please first check the upgrade path in the [versioning policy](versioning.md). ### Fixed @@ -23,6 +23,7 @@ If your currently installed *Quality-time* version is v4.10.0 or older, please r - Group digits in numbers. Closes [#8076](https://github.com/ICTU/quality-time/issues/8076). - In the measurement entity status menu, the description of the menu items would say "undefined days" if the desired response time for the status had not been changed from its default value. Fixes [#8284](https://github.com/ICTU/quality-time/issues/8284). +- Added a [versioning policy](versioning.md) to the documentation. Closes [#8748](https://github.com/ICTU/quality-time/issues/8748). - Allow for specifying supported source versions in the data model. Show the supported source version in the UI and the reference documentation. Closes [#8786](https://github.com/ICTU/quality-time/issues/8786). ### Changed @@ -338,7 +339,7 @@ If your currently installed *Quality-time* version is v4.10.0 or older, please r If your currently installed *Quality-time* version is v4.0.0 or older, please read the v4.0.0 deployment notes first. -In this version of *Quality-time* the internal server component is no longer used. The notifier and collector components talk directly to the database, instead of using the internal server. This means that the docker composition **must** be changed: +In this version of *Quality-time* the internal server component is no longer used. The notifier and collector components talk directly to the database, instead of using the internal server. This means that the Docker-composition **must** be changed: - Remove the `internal_server` section. - Rename the `external_server` section to `api_server` and make the following changes in that section: @@ -646,7 +647,7 @@ If your currently installed *Quality-time* version is v4.0.0 or older, please re If your currently installed *Quality-time* version is not v3.37.0, please read the v3.37.0 deployment notes first. -This version of *Quality-time* splits the server component into two: an external server component serving the external API and an internal server component serving the collector and notifier components. This means that the docker composition **must** be changed: +This version of *Quality-time* splits the server component into two: an external server component serving the external API and an internal server component serving the collector and notifier components. This means that the Docker-composition **must** be changed: - Rename the `server` service to `external_server`. - Use the image `ictu/quality-time_external_server`. @@ -1153,7 +1154,7 @@ Background information: *Quality-time* uses MongoDB as database component. A Mon ### Changed -- Wrap the database (MongoDB), proxy (Caddy) and renderer (url-to-pdf-api) in *Quality-time* images, so these components have the same version number as the other components and don't need to be updated by downstream maintainers separately. Note that your Docker composition needs to be changed once to use these new *Quality-time* images. See the example [docker-compose.yml](https://github.com/ICTU/quality-time/blob/master/docker/docker-compose.yml). Closes [#1770](https://github.com/ICTU/quality-time/issues/1770). +- Wrap the database (MongoDB), proxy (Caddy) and renderer (url-to-pdf-api) in *Quality-time* images, so these components have the same version number as the other components and don't need to be updated by downstream maintainers separately. Note that your Docker-composition needs to be changed once to use these new *Quality-time* images. See the example [docker-compose.yml](https://github.com/ICTU/quality-time/blob/master/docker/docker-compose.yml). Closes [#1770](https://github.com/ICTU/quality-time/issues/1770). - Increase render timeout so that larger reports can be exported to PDF. Closes [#1771](https://github.com/ICTU/quality-time/issues/1771). - Add no-cache option for /api/v3/logo to the Caddy configuration. @@ -1273,7 +1274,7 @@ Background information: *Quality-time* uses MongoDB as database component. A Mon ### Added - Support for Forwarded Authentication in a situation where *Quality-time* is behind a reverse proxy that is responsible for authentication. See the [deployment instructions](deployment.md#forwarded-authentication). -- Notifications of new red metrics to Microsoft Teams, using webhooks. See the [user manual](usage.md#notifications). Note that your Docker composition needs to be changed to include the new notifier component. See the example [docker-compose.yml](https://github.com/ICTU/quality-time/blob/master/docker/docker-compose.yml) and the [deployment instructions](deployment.md). Partially implements [#1223](https://github.com/ICTU/quality-time/issues/1223). +- Notifications of new red metrics to Microsoft Teams, using webhooks. See the [user manual](usage.md#notifications). Note that your Docker-composition needs to be changed to include the new notifier component. See the example [docker-compose.yml](https://github.com/ICTU/quality-time/blob/master/docker/docker-compose.yml) and the [deployment instructions](deployment.md). Partially implements [#1223](https://github.com/ICTU/quality-time/issues/1223). ## v3.9.0 - 2020-10-11 @@ -1482,7 +1483,7 @@ Background information: *Quality-time* uses MongoDB as database component. A Mon ### Changed -- Moved the Copy and Move buttons next to the Add buttons, making the UI more consistent. This also allows the user to copy an existing item to the right position in one go, instead of having to copy and then move it. To support adding items by copying an existing item, the API has been updated to version 3. Version 2 of the API is deprecated. See , , and . Note that your Docker composition may need to be changed to use the new API version. See the Caddy proxy configuration in the example [docker-compose.yml](https://github.com/ICTU/quality-time/blob/master/docker/docker-compose.yml). Closes [#1197](https://github.com/ICTU/quality-time/issues/1197). +- Moved the Copy and Move buttons next to the Add buttons, making the UI more consistent. This also allows the user to copy an existing item to the right position in one go, instead of having to copy and then move it. To support adding items by copying an existing item, the API has been updated to version 3. Version 2 of the API is deprecated. See , , and . Note that your Docker-composition may need to be changed to use the new API version. See the Caddy proxy configuration in the example [docker-compose.yml](https://github.com/ICTU/quality-time/blob/master/docker/docker-compose.yml). Closes [#1197](https://github.com/ICTU/quality-time/issues/1197). ### Fixed diff --git a/docs/src/deployment.md b/docs/src/deployment.md index fc706325b0..dcc90b4d79 100644 --- a/docs/src/deployment.md +++ b/docs/src/deployment.md @@ -2,14 +2,22 @@ This document describes how to deploy, and if needed move, the *Quality-time* application. It is aimed at *Quality-time* operators. -*Quality-time* consists of a set of Docker containers that together form the application. See the [software documentation](software.md) for an overview of the different containers. It is assumed the containers are deployed using a docker-composition. An alternative deployment based on a Helm chart and intended for an OpenShift (Kubernetes) cluster is described in the [Helm for OpenShift README](https://github.com/ICTU/quality-time/tree/master/openshift/helm/README.md). +*Quality-time* consists of a set of Docker containers that together form the application. See the [software documentation](software.md) for an overview of the different containers. It is assumed the containers are deployed using a Docker-composition. An alternative deployment based on a Helm chart and intended for an OpenShift (Kubernetes) cluster is described in the [Helm for OpenShift README](https://github.com/ICTU/quality-time/tree/master/openshift/helm/README.md). *Quality-time* furthermore assumes an LDAP service is available to authenticate users or that forwarded authentication is used. +```{warning} +Before skipping versions or downgrading, see the [version policy](versioning.md). +``` + ## Docker-composition This document assumes docker-compose is used to deploy the containers. The [docker folder](https://github.com/ICTU/quality-time/tree/master/docker) of the *Quality-time* repository contains different compose files for running *Quality-time* in development and continuous integration mode. You can use these compose files as basis for your own deployment configuration. +```{note} +Per the [version policy](versioning.md), if the Docker-composition needs changes, this will be indicated by a new major release of *Quality-time*. +``` + To deploy *Quality-time* locally, follow these steps: 1. Make a directory, e.g. `quality_time` and change directory to it. @@ -126,7 +134,7 @@ By default, the notifier wakes up every minute to check for changed metric statu ## Configuring MongoDB credentials (optional) -The default MongoDB credentials can be changed as follows: +The default {index}`MongoDB` credentials can be changed as follows: ```yaml database: @@ -139,7 +147,7 @@ See the [documentation on the MongoDB image](https://hub.docker.com/_/mongo) for ## Configuring renderer localisation (optional) -The date/time format and timezone of the reports that user sees are determined by the user's browser. To configure the date/time format and timezone of exported PDFs, the renderer can be configured as follows: +The date/time format and timezone of the reports that a user sees are determined by the user's browser. To configure the date/time format and timezone of exported PDFs, the renderer can be configured as follows: ```yaml renderer: diff --git a/docs/src/development.md b/docs/src/development.md index ec18a47248..8cf5c72b4d 100644 --- a/docs/src/development.md +++ b/docs/src/development.md @@ -471,14 +471,16 @@ python release.py --help ### Decide the release type -*Quality-time* adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), so first you need to decide on the type of release you want to create: +*Quality-time* adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), so first you need to decide on the type of release you want to create, conform the [release policy](versioning.md#major-minor-and-patch-releases). -- Create a **major** release if the next release contains backwards incompatible changes, and optionally other changes and bug fixes. -- Create a **minor** release if the next release contains non-breaking changes, and optionally bug fixes. -- Create a **patch** release if the next release contains bug fixes only. +- Create a **major** release if an operator needs to make manual changes to the Docker-composition before deploying the next release. +- Create a **minor** release if the next release contains new or changed functionality. +- Create a **patch** release if the next release contains only bug fixes. If you want to test the release (for example, deploy it to a test environment, or roll out a release to early adopters), it's possible to create a **release candidate** for a major, minor, or patch release. +If the release type is major, minor, or patch, update the [version overview](versioning.md#version-overview). + ```{important} To determine whether a release is major, minor, or patch, compare the changes to the [previous most recent release](changelog.md), excluding release candidates. ``` @@ -534,7 +536,7 @@ Base images used in the Docker containers, and additionally installed software, - [Collector](https://github.com/ICTU/quality-time/blob/master/components/collector/Dockerfile): the Python base image. - [Notifier](https://github.com/ICTU/quality-time/blob/master/components/notifier/Dockerfile): the Python base image. - [Frontend](https://github.com/ICTU/quality-time/blob/master/components/frontend/Dockerfile): the Node base image, the curl version, the npm version, and the serve version. -- [Database](https://github.com/ICTU/quality-time/blob/master/components/database/Dockerfile): the MongoDB base image. +- [Database](https://github.com/ICTU/quality-time/blob/master/components/database/Dockerfile): the {index}`MongoDB` base image. - [Proxy](https://github.com/ICTU/quality-time/blob/master/components/proxy/Dockerfile): the Nginx base image. - [Renderer](https://github.com/ICTU/quality-time/blob/master/components/renderer/Dockerfile): the Node base image, the curl version, the Chromium version, and the npm version. - [Test data](https://github.com/ICTU/quality-time/blob/master/components/testdata/Dockerfile): the Python base image. diff --git a/docs/src/index.md b/docs/src/index.md index 4330d3a803..741f0788ca 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -37,6 +37,7 @@ reference.md ```{toctree} :maxdepth: 1 :caption: Technical documentation 🛠 +versioning.md deployment.md development.md software.md diff --git a/docs/src/software.md b/docs/src/software.md index f2d36451e5..a58e23c021 100644 --- a/docs/src/software.md +++ b/docs/src/software.md @@ -378,14 +378,12 @@ The proxy uses the following environment variables: ## Database -The database component consists of a [Mongo](https://www.mongodb.com) database to store reports and measurements. +The database component consists of a [MongoDB](https://www.mongodb.com) database to store reports and measurements. -The proxy [Dockerfile](https://github.com/ICTU/quality-time/blob/master/components/database/Dockerfile) wraps the MongoDB image in a *Quality-time* image so the MongoDB version number can be changed when needed. +The proxy [Dockerfile](https://github.com/ICTU/quality-time/blob/master/components/database/Dockerfile) wraps the {index}`MongoDB` image in a *Quality-time* image so the MongoDB version number can be changed when needed. *Quality-time* stores its data in a Mongo database using the following collections: `datamodels`, `measurements`, `reports`, `reports_overviews`, and `sessions`. -The two server components are the only components that directly interacts with the database. - Data models, reports, and reports overviews are [temporal objects](https://www.martinfowler.com/eaaDev/TemporalObject.html). Every time a new version of the data model is loaded or the user edits a report or the reports overview, an updated copy of the object (a "document" in Mongo-parlance) is added to the collection. Since each copy has a timestamp, this enables the API-server to retrieve the documents as they were at a specific moment in time and provide time-travel functionality. ### Environment variables @@ -425,7 +423,7 @@ This component contains test data for the example reports. The Docker image is p ### Running the test data component -The test data component is started as part of the [docker composition](https://github.com/ICTU/quality-time/blob/master/docker/docker-compose.override.yml) for development, see the [developer manual](development.md). +The test data component is started as part of the [Docker-composition](https://github.com/ICTU/quality-time/blob/master/docker/docker-compose.override.yml) for development, see the [developer manual](development.md). To serve the test data locally, you can also start a web server from a console, for example: diff --git a/docs/src/versioning.md b/docs/src/versioning.md new file mode 100644 index 0000000000..87057b0deb --- /dev/null +++ b/docs/src/versioning.md @@ -0,0 +1,79 @@ +# Versioning policy + +This document describes the *Quality-time* versioning policy. It is aimed at *Quality-time* operators and developers. + +## Major, minor, and patch releases + +*Quality-time* complies with [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +A new **major** release of *Quality-time* is made when operators need to make changes to the Docker-composition (besides upgrading version numbers) before upgrading *Quality-time*. + +A new **minor** release of *Quality-time* is made when the new version has new or changed functionality. + +A new **patch** release of *Quality-time* is made when the new version has only bug fixes. + +```{index} MongoDB +``` + +## Version overview + +The table below contains the *Quality-time* releases since the last minor of the previous major release. For each release it shows the release date, the MongoDB version included, the MongoDB feature compatibility (FC) version set in the database, whether migration code was added or removed, and whether up- or downgrading is possible, and if so, to which versions. + +| Version | Release date | MongoDB | MongoDB FC | Migrations | Downgrade | Upgrade | +|------------|--------------|---------|------------|------------|----------------|-----------------| +| v5.14.0 | (unreleased) | v7 | v6 | added | not possible | n/a | +| v5.13.0 | 2024-05-23 | v7 | v6 | added | not possible | v5.14.0 | +| v5.12.0 | 2024-05-17 | v7 | v6 | added | not possible | v5.13.0-v5.14.0 | +| v5.11.0 | 2024-04-22 | v7 | v6 | | v5.6.0-v5.10.0 | v5.12.0-v5.14.0 | +| v5.10.0 | 2024-04-15 | v7 | v6 | | v5.6.0-v5.9.0 | v5.11.0-v5.14.0 | +| v5.9.0 | 2024-03-22 | v7 | v6 | | v5.6.0-v5.8.0 | v5.10.0-v5.14.0 | +| v5.8.0 | 2024-02-16 | v7 | v6 | | v5.6.0-v5.7.0 | v5.9.0-v5.14.0 | +| v5.7.0 | 2024-01-31 | v7 | v6 | | v5.6.0 | v5.8.0-v5.14.0 | +| v5.6.0 | 2024-01-12 | v7 | v6 | added | not possible | v5.7.0-v5.14.0 | +| v5.5.0 | 2023-12-15 | v7 | v6 | | v5.1.0-v5.4.0 | v5.6.0-v5.14.0 | +| v5.4.0 | 2023-12-11 | v7 | v6 | | v5.1.0-v5.3.1 | v5.5.0-v5.14.0 | +| v5.3.1 | 2023-11-08 | v7 | v6 | | v5.1.0-v5.3.0 | v5.4.0-v5.14.0 | +| v5.3.0 | 2023-11-07 | **v7** | v6 | | v5.1.0-v5.2.0 | v5.3.1-v5.14.0 | +| v5.2.0 | 2023-09-29 | v6 | v6 | | v5.1.0 | v5.3.0-v5.14.0 | +| v5.1.0 | 2023-09-05 | v6 | **v6** | | not possible | v5.2.0-v5.14.0 | +| v5.0.1 | 2023-06-26 | v6 | v5 | | v4.10.0-v5.0.0 | v5.1.0-v5.2.0 | +| **v5.0.0** | 2023-06-23 | **v6** | v5 | | v4.10.0 | v5.0.1-v5.2.0 | +| v4.10.0 | 2023-04-26 | v5 | v5 | | n/a | v5.0.0-v5.2.0 | + +## Upgrade path + +To check whether versions can be skipped when upgrading *Quality-time*, look up the currently deployed *Quality-time* version in the table above. The "Upgrade" column shows which newer versions of *Quality-time* can be deployed. + +For example, if the currently deployed version is v5.0.0, the "Upgrade" column shows that all versions from v5.0.1 up to and including v5.2.0 can be deployed. + +```{warning} +When upgrading across a major version, the manual changes as documented in the [changelog](changelog.md) need to be applied. +``` + +## Downgrade path + +To check whether a version of *Quality-time* can be downgraded, look up the currently deployed *Quality-time* version in the table above. The "Downgrade" column shows which older versions of *Quality-time* can be deployed. + +For example, if the currently deployed version is v5.5.0, the "Downgrade" column shows that all versions from v5.1.0 up to and including v5.4.0 can be deployed. + +```{warning} +When downgrading across a major version, the manual changes as documented in the [changelog](changelog.md) need to be undone. +``` + +## Background information on down- and upgrade limitations + +There are two factors that limit to which versions an existing *Quality-time* instance can be upgraded or downgraded: MongoDB and migration code. + +### MongoDB + +*Quality-time* uses MongoDB as database. MongoDB sets a feature compatibility version in the database to specify which major version of MongoDB the persisted data is compatible with. When upgrading MongoDB to a new major version, the feature compatibility flag should be set to the previous major version, and only when the upgrade was successful should the feature compatibility flag set to the new major version of MongoDB. + +In general, when the feature compatibility of a database is set to version `x`, the database can only be used with MongoDB versions `x` and `x+1`. This limits the down- and upgrade options of *Quality-time* as documented in the table above. + +```{seealso} +See the [MongoDB documentation](https://www.mongodb.com/docs/manual/reference/command/setFeatureCompatibilityVersion/) on the feature compatibility version. +``` + +### Migration code + +To support changes in the *Quality-time* functionality, data in the database may need to be restructured. To this end, the API-server may run migration code on startup. This migration code is idempotent, meaning that whenever data already has been migrated it does not make any changes. However, migration code is not reversible, meaning that going back a minor or major update is not possible when a release contains new migration code. diff --git a/docs/styles/config/vocabularies/Base/accept.txt b/docs/styles/config/vocabularies/Base/accept.txt index e12b5e46ac..04ef8a44bb 100644 --- a/docs/styles/config/vocabularies/Base/accept.txt +++ b/docs/styles/config/vocabularies/Base/accept.txt @@ -4,6 +4,7 @@ Caddy Checkmarx Cobertura Dependabot +Docker-composition Dockerfile DTDs ESLint diff --git a/docs/styles/config/vocabularies/Base/reject.txt b/docs/styles/config/vocabularies/Base/reject.txt index e69de29bb2..70dde2307a 100644 --- a/docs/styles/config/vocabularies/Base/reject.txt +++ b/docs/styles/config/vocabularies/Base/reject.txt @@ -0,0 +1,3 @@ +docker composition +Docker composition +docker-composition diff --git a/release/release.py b/release/release.py index eac81b5c8d..2faddc037c 100755 --- a/release/release.py +++ b/release/release.py @@ -31,7 +31,7 @@ def get_version() -> str: return latest_tag.tag.tag.strip("v") -def parse_arguments() -> tuple[str, bool]: +def parse_arguments() -> tuple[str, str, bool]: """Return the command line arguments.""" current_version = get_version() description = f"Release Quality-time. Current version is {current_version}." @@ -42,7 +42,8 @@ def parse_arguments() -> tuple[str, bool]: - the workspace has no uncommitted changes - the workspace has no untracked files - the changelog has an '[Unreleased]' header - - the changelog contains no release candidates""" + - the changelog contains no release candidates + - the new release has been added to the version overview""" parser = ArgumentParser(description=description, epilog=epilog, formatter_class=RawDescriptionHelpFormatter) allowed_bumps_in_rc_mode = ["rc", "rc-major", "rc-minor", "rc-patch", "drop-rc"] # rc = release candidate allowed_bumps = ["rc-patch", "rc-minor", "rc-major", "patch", "minor", "major"] @@ -52,10 +53,10 @@ def parse_arguments() -> tuple[str, bool]: "-c", "--check-preconditions-only", action="store_true", help="only check the preconditions and then exit" ) arguments = parser.parse_args() - return arguments.bump, arguments.check_preconditions_only + return arguments.bump, current_version, arguments.check_preconditions_only -def check_preconditions(bump: str) -> None: +def check_preconditions(bump: str, current_version: str) -> None: """Check preconditions for version bump.""" messages = [] release_folder = get_release_folder() @@ -64,6 +65,7 @@ def check_preconditions(bump: str) -> None: root = release_folder.parent messages.extend(failed_preconditions_repo(root)) messages.extend(failed_preconditions_changelog(bump, root)) + messages.extend(failed_preconditions_version_overview(current_version, root)) if messages: formatted_messages = "\n".join([f"- {message}" for message in messages]) sys.exit(f"Please fix these issues before releasing Quality-time:\n{formatted_messages}\n") @@ -105,11 +107,31 @@ def failed_preconditions_changelog(bump: str, root: pathlib.Path) -> list[str]: return messages +def failed_preconditions_version_overview(current_version: str, root: pathlib.Path) -> list[str]: + """Check that the version overview is properly prepared.""" + version_overview = root / "docs" / "src" / "versioning.md" + with version_overview.open() as version_overview_file: + version_overview_lines = version_overview_file.readlines() + missing = f"The version overview ({version_overview}) does not contain" + previous_line = "" + for line in version_overview_lines: + if line.startswith(f"| v{current_version} "): + if previous_line.startswith("| v"): + today = datetime.date.today().isoformat() + release_date = previous_line.split(" | ")[1].strip() + if release_date != today: # Second column is the release date column + return [f"{missing} the release date. Expected today: '{today}', found: '{release_date}'."] + return [] # All good: current version, next version, and release date found + return [f"{missing}) the new version."] + previous_line = line + return [f"{missing} the current version ({current_version})."] + + def main() -> None: """Create the release.""" os.environ["RELEASE_DATE"] = datetime.date.today().isoformat() # Used by bump-my-version to update CHANGELOG.md - bump, check_preconditions_only = parse_arguments() - check_preconditions(bump) + bump, current_version, check_preconditions_only = parse_arguments() + check_preconditions(bump, current_version) if check_preconditions_only: return # See https://github.com/callowayproject/bump-my-version?tab=readme-ov-file#add-support-for-pre-release-versions