Skip to content

Commit 7e99f5c

Browse files
committed
docs(versioning): update versioning documentation for clarity and detail
Expand the VERSIONING.md to provide a comprehensive guide on the versioning scheme, detection logic, and release process for the Tux project. The document now includes detailed explanations of the Semantic Versioning scheme, dynamic version detection methods, and release cycle procedures. This update aims to ensure that developers and users have a clear understanding of how versioning is managed, facilitating consistent and reliable versioning across different environments. The addition of Docker image tagging instructions enhances traceability and ensures the correct version is reported even in detached production environments.
1 parent be53f61 commit 7e99f5c

File tree

1 file changed

+89
-44
lines changed

1 file changed

+89
-44
lines changed

VERSIONING.md

Lines changed: 89 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,91 @@
11
# Versioning
22

3-
## Auto Generated Version Examples
4-
These are examples of how our configuration of [poetry-dynamic-versioning](https://github.com/mtkennerly/poetry-dynamic-versioning) will generate the version number.
5-
6-
If branch is not main and there are commits since last tag:
7-
```
8-
tux 0.0.0.dev2106+b731156.dynamicversioning
9-
^ ^ ^ ^ ^
10-
name^ commits commit branch (escaped), is empty if its main
11-
ver since hash
12-
last
13-
tag
14-
```
15-
If branch is main and there are commits since last tag:
16-
```
17-
tux 0.0.0.dev2106+b731156
18-
^ ^ ^ ^
19-
name^ commits commit
20-
ver since hash
21-
last
22-
tag
23-
```
24-
If branch is main and there are no commits since last tag:
25-
```
26-
tux 0.0.0
27-
^ ^
28-
name^
29-
ver
30-
```
31-
32-
## Scheme
33-
We use PEP 440 for formatting our version numbers, however we use SemVer for the versioning scheme.
34-
> Keep in mind you cannot use .dev(NUMBER) as it clashes with the auto generated versioning. (e.g 0.1.0rc1.dev1 is invalid and won't show up properly)
35-
36-
## SemVer Summary
37-
A example in tux would be:
38-
Given a version number MAJOR.MINOR.PATCH, increment the:
39-
40-
MAJOR version when you make changes that may need significant manual setup from the last version (example would be a web panel, config overhaul, major db changes)
41-
MINOR version when you make changes that needs little to no manual interference (at most maybe tweaking a config value or updating the db)
42-
PATCH version when you make changes that need no manual interference
43-
44-
You can add stuff like "0.1.0**rc1**" to mark small changes leading up to a release. (release candidates)
45-
46-
You do not need to stick to this absolutely all the time, this is a guideline on how to make your versioning.
3+
This document outlines the versioning scheme, detection logic, and release process for the Tux project. Our system is designed to provide consistent and reliable versioning across development, testing, and production environments.
4+
5+
## Versioning Scheme
6+
7+
We follow the [Semantic Versioning (SemVer)](https://semver.org/) specification for our release cycle. Version numbers are formatted as `MAJOR.MINOR.PATCH`.
8+
9+
- **MAJOR**: Incremented for incompatible API changes or significant architectural shifts that may require manual intervention during an upgrade (e.g., major config or database schema changes).
10+
- **MINOR**: Incremented for new, backward-compatible functionality.
11+
- **PATCH**: Incremented for backward-compatible bug fixes.
12+
13+
Release candidates can be denoted with suffixes (e.g., `1.0.0-rc1`).
14+
15+
## Version Detection
16+
17+
The application version is determined dynamically at runtime. The `tux/__init__.py` module contains a robust detection mechanism that checks multiple sources in a specific order of priority. This ensures that the version is always available, regardless of the environment.
18+
19+
The `version` field in `pyproject.toml` is intentionally set to a static placeholder (`0.0.0`) because the true version is resolved dynamically.
20+
21+
### Priority Order
22+
23+
The version is sourced by trying the following methods in order, stopping at the first success:
24+
25+
1. **`TUX_VERSION` Environment Variable**:
26+
- **Usage**: A runtime override.
27+
- **Example**: `TUX_VERSION=1.2.3-custom tux --dev start`
28+
- **Priority**: Highest. If set, this value is always used.
29+
30+
2. **`VERSION` File**:
31+
- **Usage**: The primary versioning method for Docker images. This file is generated during the Docker build process.
32+
- **Location**: Project root (`/app/VERSION` inside the container).
33+
34+
3. **Git Tags (`git describe`)**:
35+
- **Usage**: The standard for development environments where the Git history is available.
36+
- **Format**: It produces version strings like:
37+
- `1.2.3`: For a commit that is tagged directly.
38+
- `1.2.3-10-gabc1234`: For a commit that is 10 commits ahead of the `v1.2.3` tag.
39+
- `1.2.3-10-gabc1234-dirty`: If there are uncommitted changes.
40+
- **Note**: The leading `v` from tags (e.g., `v1.2.3`) is automatically removed.
41+
42+
4. **Package Metadata (`importlib.metadata`)**:
43+
- **Usage**: For when Tux is installed as a package from PyPI or a wheel file.
44+
- **Mechanism**: Reads the version from the installed package's metadata.
45+
46+
5. **Fallback to `"dev"`**:
47+
- **Usage**: A final fallback if all other methods fail, ensuring the application can always start.
48+
49+
## Release Cycle and Git Tagging
50+
51+
The release process is centered around Git tags.
52+
53+
1. **Create a Release**: To create a new version, create and push an annotated Git tag:
54+
55+
```sh
56+
# Example for a patch release
57+
git tag -a v1.2.3 -m "Release v1.2.3"
58+
git push origin v1.2.3
59+
```
60+
61+
2. **Development Version**: Between releases, any new commits will result in a development version string (e.g., `1.2.3-5-g567def8`), indicating progress since the last tag.
62+
63+
## Docker Image Tagging
64+
65+
Our Docker build process is designed to bake the version directly into the image, ensuring traceability.
66+
67+
- **Build Process**: The `Dockerfile` uses a build argument (`VERSION`) to create a `VERSION` file inside the image. This file becomes the source of truth for the version within the container.
68+
69+
- **Building an Image**: To build a versioned image, pass the `VERSION` argument, preferably derived from `git describe`:
70+
71+
```sh
72+
# Recommended command to build a production image
73+
docker build \
74+
--build-arg VERSION=$(git describe --tags --always --dirty | sed 's/^v//') \
75+
--target production \
76+
-t your-registry/tux:latest .
77+
```
78+
79+
You can also tag the image with the specific version:
80+
81+
```sh
82+
# Tag with the specific version for better tracking
83+
VERSION_TAG=$(git describe --tags --always --dirty | sed 's/^v//')
84+
docker build \
85+
--build-arg VERSION=$VERSION_TAG \
86+
--target production \
87+
-t your-registry/tux:$VERSION_TAG \
88+
-t your-registry/tux:latest .
89+
```
90+
91+
This ensures that even in a detached production environment without Git, the application reports the correct version it was built from.

0 commit comments

Comments
 (0)