Calaf is a command-line tool for managing Calendar Versioning (CalVer) of .NET projects, written in F#.
- Features
- Requirements
- Versioning Scheme
- Quick Start
- Commands Reference
- Changelog Generation
- Further Use
- License
- Special Thanks
- Automatic Calendar Versioning based on the current UTC date
- Support for
stable,alpha,beta,rcandnightlyrelease types - Git integration with automatic tagging and aversion commit for new versions
- Automatic
CHANGELOG.mdgeneration based on Conventional Commits - Works with C#/F# project files (
*.csproj/*.fsproj) - Generates versions compatible with Semantic Versioning 2.0.0
- Tool installation via the
dotnetCLI
- .NET 8.0 or later
- Git (required for automatic commiting and tagging when creating new versions)
Calaf implements a Calendar Versioning (CalVer) scheme that is compatible with Semantic Versioning 2.0.0. This ensures that versions are chronological, sortable, and widely supported.
Format: YYYY.MM[.MICRO][-BUILD.FORMAT]
- Examples:
2001,2025,2150 - Range:
1to9999
- Examples:
1,6,12 - Range:
1to12
- Examples:
1,2,3 - Range:
1to4294967295
BUILD.FORMAT - Pre-release build identifier with a specific format suffix to indicate non-stable builds:
- Alpha releases:
alpha.NUMBER- Example:
2025.10.1-alpha.1 - Range
NUMBER:1to4294967295
- Example:
- Beta releases:
beta.NUMBER- Example:
2025.10.1-beta.1 - Range
NUMBER:1to4294967295
- Example:
- Release Candidate:
rc.NUMBER- Example:
2025.10.1-rc.1 - Range
NUMBER:1to4294967295
- Example:
- Nightly builds:
0.nightly.DAY.NUMBER- The leading
0ensures that nightly builds have lower precedence than other pre-release builds likealpha,beta. DAY: The day of the monthNUMBER: A sequential number for builds on the same day- Example:
2025.10.1-0.nightly.30.1 - Range
NUMBER:1to4294967295
- The leading
- Alpha nightly builds:
alpha.ALPHA_NUMBER.DAY.NIGHTLY_NUMBER- Example:
2025.10.1-alpha.1.30.1
- Example:
- Beta nightly builds:
beta.BETA_NUMBER.DAY.NIGHTLY_NUMBER- Example:
2025.10.1-beta.1.30.1
- Example:
- Release Candidate nightly builds:
rc.RC_NUMBER.DAY.NIGHTLY_NUMBER- Example:
2025.10.1-rc.1.30.1
- Example:
Versions are compared according to SemVer 2.0.0 rules. The following list shows an example of version progression from lowest to highest precedence:
2025.10.1-0.nightly.30.1(Nightly)2025.10.1-alpha.1(Alpha)2025.10.1-alpha.1.30.1(Alpha Nightly)2025.10.1-alpha.2(Later Alpha)2025.10.1-beta.1(Beta)2025.10.1-beta.1.30.1(Beta Nightly)2025.10.1-beta.2(Later Beta)2025.10.1-rc.1(Release Candidate)2025.10.1-rc.1.8.1(Release Candidate Nightly)2025.10.1(Stable Release)
dotnet tool install -g Calaf<PropertyGroup>
<Version>2025.10</Version>
</PropertyGroup>calaf make stableSynopsis:
calaf make <stable|alpha|beta|rc|nightly>Description: Generates and applies a new Calendar Version to all .csproj and .fsproj files in the current directory. Automatically creates Git commit and tag if repository is detected.
Automatic Changelog Generation: When calaf make is run in a Git repository, it also automatically generates or updates a CHANGELOG.md file. The tool analyzes commits since the last version tag that follow the Conventional Commits specification.
- Commits like
feat(scope): descriptionare added under a### Featuressection, grouped by scope. - Commits like
fix(scope): descriptionare added under a### Bug Fixessection, grouped by scope. - Commits with a
!after the type/scope (e.g.,feat(api)!:) are added under a### Breaking Changessection.
Arguments:
| Argument | Description |
|---|---|
stable |
Stable release. Creates a production-ready version. |
alpha |
Alpha release. Creates an early pre-release version for testing. Increments the alpha number. Alpha numbering starts from 1 and increments with each new alpha release. |
beta |
Beta release. Creates a pre-release version for testing. Increments the beta number. Beta numbering starts from 1 and increments with each new beta release. |
rc |
Release Candidate. Creates a version for final testing before stable release. Increments the rc number. Rc numbering starts from 1 and increments with each new rc release. |
nightly |
Nightly (development) build. Creates a development build version. Uses the current day and an incremental number that's starts from 1 for that day. |
Examples:
Stable Release
Creates a production version based on current UTC date on running system (System.DateTimeOffSet.UtcNow).
2025.10 → 2025.10.1
- Command:
calaf make stable- Output:
Version applied: 2025.10.1- Project file(s) change:
<!-- Before -->
<Version>2025.10</Version>
<!-- After -->
<Version>2025.10.1</Version>Alpha Release
Creates an early pre-release version.
2025.10.1 → 2025.10.2-alpha.1
calaf make alpha - Output:
Version applied: 2025.10.2-alpha.1- Project file(s) change:
<!-- Before -->
<Version>2025.10.1</Version>
<!-- After -->
<Version>2025.10.2-alpha.1</Version>Beta Release
Creates a pre-release version.
2025.10.1 → 2025.10.2-beta.1
calaf make beta - Output:
Version applied: 2025.10.2-beta.1- Project file(s) change:
<!-- Before -->
<Version>2025.10.1</Version>
<!-- After -->
<Version>2025.10.2-beta.1</Version>RC Release
Creates a release candidate version for final testing before stable release.
2025.10.1 → 2025.10.2-rc.1
calaf make rc- Output:
Version applied: 2025.10.2-rc.1- Project file(s) change:
<!-- Before -->
<Version>2025.10.1</Version>
<!-- After -->
<Version>2025.10.2-rc.1</Version>Nightly Build
Creates a development build with daily identifier.
2025.10.1 → 2025.10.2-0.nightly.27.1
calaf make nightly- Output:
Version applied: 2025.10.2-0.nightly.27.1Note: Subsequent runs on the same day increment the build number: 2025.10.2-0.nightly.27.2, 2025.10.2-0.nightly.27.3, etc.
Project file change:
<!-- Before -->
<Version>2025.10.1</Version>
<!-- After -->
<Version>2025.10.2-0.nightly.27.1</Version>Note: Nightly from Alpha
You can create nightly builds from existing alpha versions.
2025.10.1-alpha.1 → 2025.10.1-alpha.2.27.1
- Output:
Version applied: 2025.10.1-alpha.2.27.1Project file change:
<!-- Before -->
<Version>2025.10.1-alpha.1</Version>
<!-- After -->
<Version>2025.10.1-alpha.1.27.1</Version>Note: Nightly from Beta
You can create nightly builds from existing beta versions.
2025.10.1-beta.1 → 2025.10.1-beta.2.27.1
- Output:
Version applied: 2025.10.1-beta.2.27.1Project file change:
<!-- Before -->
<Version>2025.10.1-beta.1</Version>
<!-- After -->
<Version>2025.10.1-beta.2.27.1</Version>Note: Nightly from Release Candidate
You can create nightly builds from existing rc versions.
2025.10.1-rc.1 → 2025.10.2-rc.1.27.1
- Output:
Version applied: 2025.10.2-rc.1.27.1Project file change:
<!-- Before -->
<Version>2025.10.1-rc.1</Version>
<!-- After -->
<Version>2025.10.2-rc.1.27.1</Version>Calaf automatically maintains CHANGELOG.md during calaf make:
- Commit range: from the last version Git tag to
HEAD. If no tag exists, all commits are considered. - Source: commits conforming to Conventional Commits are categorized. The format
type(scope): descriptionis supported, where(scope)is optional. - Categories:
### Breaking Changes: commits with!after the type/scope (e.g.,feat(api)!: drop support for old format).### Features: commits withfeat:.### Fixed: commits withfix:.
- File handling: creates
CHANGELOG.mdif missing; prepends the new release entry if present. - Git integration:
CHANGELOG.mdis staged together with project file updates and included in the version commit and tag.
Example entry:
## 2025.10.1
**2025-10-20**
### Features
- **core:** add RC pre-release support
- **versioning:** change version format to YYYY.MM[.MICRO][-BUILD.FORMAT]
### Fixed
- **fs:** correct content duplication in markdown writer
### Breaking Changes
- **versioning:** change version format to YYYY.MM[.MICRO][-BUILD.FORMAT]The following example illustrates how to integrate Calaf into a CI/CD pipeline for automated Calendar Versioning:
jobs:
release:
name: Release
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
# Fetch all history for accurate version calculation
fetch-depth: 0
- name: Install Calaf
run: dotnet tool install -g Calaf
- name: Make a new stable version
id: versioning
run: calaf make stable
continue-on-error: false
- name: Push version changes
run: |
git push origin ${{ github.ref_name }}
git push origin --tagsThis project is licensed under the Apache License 2.0. See the LICENSE file for details.
Special thanks to Anna Mazhaieva for designing the graphic assets used in this project.