---
# System prepended metadata

title: '[Engineering] Understanding Semantic Versioning'

---

# [Engineering] Understanding Semantic Versioning
:::info
:bulb: Semantic Versioning (often abbreviated as SemVer) is a versioning system that uses a three-part version number to communicate changes in software.
:::

## :question: What is Semantic Versioning
Semantic Versioning (SemVer) is a widely adopted convention for versioning software. It provides a clear and consistent way to communicate the nature of changes in releases through version numbers.
SemVer uses a three-part version number: MAJOR.MINOR.PATCH. Each part conveys specific information about the release.

## :question: Why Semantic Versioning

* Consistent versioning helps developers understand the potential impact of upgrading to a new version of a dependency. It reduces conflicts and improves dependency management.
* Tools like `npm`, `pip`, and `cargo` use it to decide which versions are compatible. 
* and more . . .

## :bulb: Versioning
### Overview of MAJOR.MINOR.PATCH format

**MAJOR**: Incremented when there are incompatible API changes. This means code using the previous version's API may break.
**MINOR**: Incremented when backward-compatible functionality is added. Existing code using the API should still work.
**PATCH**: Incremented when backward-compatible bug fixes are made. The API and functionality remain the same.
**Ex: 1.0.0**

**Pre-Release Versions:**
Release Candidate:
`vMAJOR.MINOR.PATCH-rc.X`
Use when your release is stable and feature-completeyou still want to catch any remaining issues before the stable release.

It's a step closer to the final release and should have minimal changes between the rc and stable versions.

## :feet: Steps 
To apply semantic versioning to for example a package you have follow these steps:
### 1- Add new tag

* Create a new tag which points to your latest changes and push it to github, you can do this locally or from github release page.
```
git tag -a v1.0.0 -m "Version 1.0.0"
```

```
git push origin v1.0.0
```

for pre-release tags use Release Candidate format:
`vMAJOR.MINOR.PATCH-rc.X`

:::info
:bulb:Tags are snapshots, not live pointers.
:::

you can see commit your tags points to using:
```
git show-ref --tags
```
for specific tag:
```
git show v1.0.0
```

### 2- Publish Release
* Go to github releases page and draft a new release
![image](https://hackmd.io/_uploads/r16-4oEwgl.png)
* Choose your tag or add new one and make sure to set release title same as version you added, then set as latest release and publish the release
![image](https://hackmd.io/_uploads/rJK2EiNwgl.png)
* For Development enviroment use the RC format and set as pre-release
![image](https://hackmd.io/_uploads/HJXvroNPgl.png)

### 3- Update your requirements.txt file in needed Microservices or Lambdas
* open a PR to targeted env and use the suitable release version, for example for dev env open PR using the pre-release version and merge it.
![image](https://hackmd.io/_uploads/HkRaIh4wlg.png)

:::info
:bulb: 
You don't have to update the version in the MS (master source) because the latest pre-release version is seen as the same as the released version, but it's a good practice to update it.
:::

* for stable releases once all of your changes are confirmed and you added stable tag version and release it open PR to master env and use the stable release.
```
git+ssh://git@github.com/HarriLLC/BreakEngine.git@v1.1.0
```


 
:::danger
make sure to not delete a release which is already used in MS or Lambda requirements file. as if so this will cause software releases failures.
:::

## :question: How to Deal With Multiple Features and Frequent Changes
we mentioned the very straigth forward case of adding a new change(feature or bug fix) and add a tag with suitable version and release, but what if we have multiple features on development branches what could we do?
* Team Collaboration
* Prioritize changes
* Each change to have its own seperate branch
* Those Changes that will be tested togehter to be merged to common branch taken basically from master.
* Add a tag from this branch and a release for it.
* Open PR for specific env on MSs or Lambdas that usee suitable pre-release version then merge.
* Changes shouldn't stay long on development enviroments. we need to keep updated and push as soon as we could to avoid having features conflicts and versioning confusion.

### ✍️ Lets describe this step by step with the following ex:
how to apply manual semantic versioning to lets say `FinancialModel` package where we have:

* Multi-environment setup
* 5 dependent microservices
* many features in development
* Uncertain release order of features

lets say we have those 3 features in development `(es-feature, minor-feature, ot-feature)`

Currently, `(es-feature, minor-feature, ot-feature)` are merged to dev
 `es-feature` and `minor-feature` are merged into stage and beta


### 🧩 Current Feature and Env Status:
| Feature         | Status    | Environments Merged Into |
| --------------- | --------- | ------------------------ |
| `es-feature`    | Completed | `dev`, `stage`, `beta`   |
| `minor-feature` | Completed | `dev`, `stage`, `beta`   |
| `ot-feature`    | In Dev    | `dev` only               |


### :footprints: Step-by-Step Versioning Per Environment
#### 🔨 dev Environment
You are testing 3 features (including one not ready for stage/prod).

What to do:
* After merging `es-feature`, `minor-feature`, and `ot-feature` into dev:

```
git checkout dev
git tag v1.0.0-dev.1
git push origin v1.0.0-dev.1
```
in `requirements.txt` of microservices in dev env:
```
git+ssh://git@github.com/HarriLLC/FinancialModel.git@v1.0.0-dev.1
```

#### 🔨 stage Environment (UAT)
In stage, only `es-feature` and `minor-feature` are merged, `ot-feature` is NOT there.

What to do:
After merging those 2 features:
```
git checkout stage
git tag v1.0.0-uat.1
git push origin v1.0.0-uat.1
```

In `requirements.txt` of microservices in stage env:
```
git+ssh://git@github.com/HarriLLC/FinancialModel.git@v1.0.0-uat.1
```

#### 🚨 What if es-feature is Ready for Prod First?
If only `es-feature` is approved and `minor-feature` is delayed:
1- Create a new branch from the last commit where only `es-feature` was merged.

2- Tag it:
```
git tag v1.0.0-rc.1
git push origin v1.0.0-rc.1
```
3- When approved to go prod:
```
git tag v1.0.0
git push origin v1.0.0
```

4- Then in `requirements.txt` of microservices in stage env:
```
git+ssh://git@github.com/HarriLLC/FinancialModel.git@v1.0.0
```

#### ✅  Versioning Timeline Example
| Tag            | Environment | Features Included | Purpose                     |
| -------------- | ----------- | ----------------- | --------------------------- |
| `v1.0.0-dev.1` | `dev`       | es, minor, ot     | Dev testing snapshot        |
| `v1.0.0-uat.1` | `stage`     | es, minor         | UAT testing                 |
| `v1.0.0-rc.1`  | `beta`      | es                | Release candidate (only es) |
| `v1.0.0`       | `master`    | es                | Final prod release          |
| `v1.1.0-rc.1`  | `beta`      | es + minor        | Next release                |
| `v1.1.0`       | `master`    | es + minor        | Later prod release          |


#### :question: Now what to do when you want to add a new feature?

suppose we have a new feature `break-feature` which will break/change behavior in all microservices not backward compatabile change:

**What You Should Do?**
1. Merge break-feature into dev
now you have those on dev
 ```
dev = es + minor + ot + break-feature
```
2. Tag the new dev version as the start of v2.x
```
git checkout dev
git tag v2.0.0-dev.1
git push origin v2.0.0-dev.1
```
 3. Update requirements.txt in all 5 microservices (in their dev branches):
```
git+ssh://git@github.com/HarriLLC/FinancialModel.git@v2.0.0-dev.1
```

When ready:

Merge to stage, tag:
```
git tag v2.0.0-uat.1
git push origin v2.0.0-uat.1
```

Merge to beta, tag:

```
git tag v2.0.0-rc.1
git push origin v2.0.0-rc.1
```
Then finally:

```
git tag v2.0.0
git push origin v2.0.0
```

And update all microservices’ prod `requirements.txt` to:

```
git+ssh://git@github.com/HarriLLC/FinancialModel.git@v2.0.0
```

### ✅ Conclusion:
For our current situation:
* Tag dev as `vx.x.x-dev.x` for dev env versions including all dev features.
* Tag stage as `vx.x.x-uat.x` for stage env versions including all stage features.
* Later, choose which feature(s) to promote to beta and tag as `vx.x.x-rc.x`
* Merge targeted features branch to master and the final production tag goes to master as `vx.x.x`
* Update `requirements.txt` file for affected MSs for each env.



## :bulb: Team-Friendly Practices
to make things organized more we can add `CHANGELOG.md` file and keep it updated, this is a documentation file used in software projects to track all notable changes made over time — such as new features, bug fixes, breaking changes, and version updates.
ex:

```
# Changelog

All notable changes to this package will be documented in this file.

This project uses [Semantic Versioning](https://semver.org/).

---

## [v2.2.0] – 2025-09-15
### Added
- `ot-feature`: Added overtime cost calculation module.

### Changed
- Improved logging in financial methods.

---

## [v2.1.0] – 2025-08-20
### Added
- `minor-feature`: Introduced minor break calculations

---

## [v2.0.0] – 2025-08-01
### ⚠️ Breaking Changes
- Introduced `break-feature`: Update break financials calculations across all consumers (required changes in all 5 microservices).
- Removed deprecated `BreakForecastModel` class.

### Added
- Update Role APIs
- Improved internal mapping for user financials info.

---

## [Unreleased]

### Planned
- `forecast-feature`: Predictive model for calculations.
- `fww-refactor`: Refactor FWW model

---

## Notes

- `v1.0.0` was **intended but never released** due to early breaking change introduction.
- First production version is `v2.0.0`.
- All versions follow manual semantic versioning and are released via Git tags (e.g. `v2.1.0-rc.1`, `v2.1.0-uat.1`, etc.)

```
