From 0712fde47f277db668f255277defbc9fdff6680e Mon Sep 17 00:00:00 2001 From: Adir Amsalem Date: Thu, 18 Jun 2026 14:57:14 +0300 Subject: [PATCH 1/2] chore: single-source version + one-command release script - Generate from version.h.in via configure_file so the version has one source of truth: project(VERSION) in CMakeLists.txt. Removes the hand-maintained header and any drift from the release tag. - Add scripts/release.sh X.Y.Z: bump the version, commit, tag, and push from main; the Release workflow publishes the GitHub release on the tag. --- AGENTS.md | 9 ++++ CMakeLists.txt | 14 ++++- include/decart/{version.h => version.h.in} | 11 ++-- scripts/release.sh | 63 ++++++++++++++++++++++ 4 files changed, 92 insertions(+), 5 deletions(-) rename include/decart/{version.h => version.h.in} (51%) create mode 100755 scripts/release.sh diff --git a/AGENTS.md b/AGENTS.md index 74ae372..464235c 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -8,6 +8,15 @@ - `./scripts/format.sh` / `clang-format -i` — format (`.clang-format`, 110 cols, Google base) - Auth/tokens-only build (no LiveKit): `cmake -B build -S . -DDECART_BUILD_REALTIME=OFF` (compiles out `Client::realtime()` via the `DECART_NO_REALTIME` interface define) +- Release: `scripts/release.sh X.Y.Z` (from `main`) bumps the version, tags, and + pushes; the Release workflow publishes the GitHub release on the tag. + +## Versioning + +The version lives in exactly one place — `project(decart VERSION ...)` in the +top-level CMakeLists.txt. `` is generated from `version.h.in` +via `configure_file`, so it can't drift from the release tag. Never hand-edit a +version number anywhere else. ## Architecture diff --git a/CMakeLists.txt b/CMakeLists.txt index e467b28..80c140c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -115,9 +115,17 @@ endif() add_library(decart ${DECART_SOURCES}) add_library(decart::decart ALIAS decart) +# Single source of truth for the version: the project() VERSION above. Generate +# from it so headers can never drift from the release tag. +configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/include/decart/version.h.in" + "${CMAKE_CURRENT_BINARY_DIR}/generated/decart/version.h" + @ONLY) + target_include_directories(decart PUBLIC $ + $ $ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src) @@ -207,7 +215,11 @@ install(TARGETS decart ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) -install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) +# Public headers, excluding the .in template (the generated header is installed below). +install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + PATTERN "*.in" EXCLUDE) +install(FILES "${CMAKE_CURRENT_BINARY_DIR}/generated/decart/version.h" + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/decart) install(EXPORT decartTargets FILE decartTargets.cmake diff --git a/include/decart/version.h b/include/decart/version.h.in similarity index 51% rename from include/decart/version.h rename to include/decart/version.h.in index 9810738..a7cfec9 100644 --- a/include/decart/version.h +++ b/include/decart/version.h.in @@ -1,16 +1,19 @@ // Copyright 2026 Decart. SPDX-License-Identifier: MIT +// +// Generated from version.h.in by CMake — do not edit. The version is the single +// source of truth in the top-level CMakeLists.txt `project(... VERSION ...)`. #pragma once #include /// Major version of the Decart C++ SDK. -#define DECART_SDK_VERSION_MAJOR 0 +#define DECART_SDK_VERSION_MAJOR @PROJECT_VERSION_MAJOR@ /// Minor version of the Decart C++ SDK. -#define DECART_SDK_VERSION_MINOR 1 +#define DECART_SDK_VERSION_MINOR @PROJECT_VERSION_MINOR@ /// Patch version of the Decart C++ SDK. -#define DECART_SDK_VERSION_PATCH 0 +#define DECART_SDK_VERSION_PATCH @PROJECT_VERSION_PATCH@ /// Full version string of the Decart C++ SDK. -#define DECART_SDK_VERSION "0.1.0" +#define DECART_SDK_VERSION "@PROJECT_VERSION@" namespace decart { diff --git a/scripts/release.sh b/scripts/release.sh new file mode 100755 index 0000000..aa81f44 --- /dev/null +++ b/scripts/release.sh @@ -0,0 +1,63 @@ +#!/usr/bin/env bash +# +# Cut a release: bump the version (single source of truth in CMakeLists.txt), +# commit, tag, and push. The Release workflow then verifies the tag matches the +# project version and publishes the GitHub release. +# +# scripts/release.sh 0.2.0 +# +set -euo pipefail +cd "$(dirname "$0")/.." + +if [[ $# -ne 1 ]]; then + echo "Usage: $0 (e.g. $0 0.2.0)" >&2 + exit 1 +fi +new="$1" + +if [[ ! "$new" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "error: version must be semver X.Y.Z (got '$new')" >&2 + exit 1 +fi + +branch="$(git rev-parse --abbrev-ref HEAD)" +if [[ "$branch" != "main" ]]; then + echo "error: releases are cut from 'main' (on '$branch')" >&2 + exit 1 +fi +if [[ -n "$(git status --porcelain)" ]]; then + echo "error: working tree is not clean; commit or stash first" >&2 + exit 1 +fi + +git pull --ff-only origin main + +current="$(sed -n -E 's/^[[:space:]]*VERSION[[:space:]]+([0-9]+\.[0-9]+\.[0-9]+).*/\1/p' CMakeLists.txt | head -1)" +if [[ -z "$current" ]]; then + echo "error: could not find the project VERSION line in CMakeLists.txt" >&2 + exit 1 +fi +if [[ "$new" == "$current" ]]; then + echo "error: version is already $current" >&2 + exit 1 +fi + +if git rev-parse -q --verify "refs/tags/v$new" >/dev/null; then + echo "error: tag v$new already exists" >&2 + exit 1 +fi + +echo "Releasing v$new (was v$current)" + +# Bump the single source of truth; version.h is generated from it at build time. +sed -i.bak -E "s/^([[:space:]]*VERSION[[:space:]]+)[0-9]+\.[0-9]+\.[0-9]+/\1$new/" CMakeLists.txt +rm -f CMakeLists.txt.bak + +git add CMakeLists.txt +git commit -m "chore: release v$new" +git tag -a "v$new" -m "decart-cpp v$new" + +git push origin main +git push origin "v$new" + +echo "Pushed v$new — the Release workflow will publish the GitHub release." From 4f93eee495b733c299a7deee2b0eda40183cb134 Mon Sep 17 00:00:00 2001 From: Adir Amsalem Date: Thu, 18 Jun 2026 15:04:23 +0300 Subject: [PATCH 2/2] chore: bump vcpkg.json version in release.sh so it can't drift --- scripts/release.sh | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/scripts/release.sh b/scripts/release.sh index aa81f44..b436655 100755 --- a/scripts/release.sh +++ b/scripts/release.sh @@ -49,11 +49,14 @@ fi echo "Releasing v$new (was v$current)" -# Bump the single source of truth; version.h is generated from it at build time. +# Bump the version. CMakeLists.txt is the single source of truth (version.h is +# generated from it at build time); keep vcpkg.json's manifest version in lockstep +# so it can't drift from the release tag. sed -i.bak -E "s/^([[:space:]]*VERSION[[:space:]]+)[0-9]+\.[0-9]+\.[0-9]+/\1$new/" CMakeLists.txt -rm -f CMakeLists.txt.bak +sed -i.bak -E "s/(\"version\"[[:space:]]*:[[:space:]]*\")[0-9]+\.[0-9]+\.[0-9]+(\")/\1$new\2/" vcpkg.json +rm -f CMakeLists.txt.bak vcpkg.json.bak -git add CMakeLists.txt +git add CMakeLists.txt vcpkg.json git commit -m "chore: release v$new" git tag -a "v$new" -m "decart-cpp v$new"