]> git.djapps.eu Git - pkg/ggml/sources/ggml/commitdiff
ggml : introduce semantic versioning (#1336)
authorDaniel Bevenius <redacted>
Tue, 16 Sep 2025 04:16:52 +0000 (06:16 +0200)
committerGitHub <redacted>
Tue, 16 Sep 2025 04:16:52 +0000 (06:16 +0200)
* ggml : introduce semantic versioning

This commit introduces semantic versioning for the GGML library.

The motivation for this is that the current versioning, using build
numbers, makes it difficult to track changes and releases for projects
that use ggml.

The release steps are the following:
1. Sync the changes from llama.cpp using sync-llama-am.sh and after the
   PR has been approved and merged move to step 2.
2. Run scripts/release.sh and specify the type of release, major, minor,
   or patch. This script will handle incrementing the version
   (major|minor|patch), create a new commit with the version change,
   create a tag for the version, and prepare for the next development
   iteration.
3. Inspect the commits/tag and push to master. This will trigger the
   github release workflow which is triggered for new tags which will
   then publish a new release on github.

Example usage:
```console
$ ./scripts/release.sh major --dry-run
[dry-run] - No changes will be made

Step 1: Reading current version...
Current version: 0.9.0-dev
New release version: 1.0.0

Step 2: Updating version in CMakeLists.txt...
  [dry-run] Would update GGML_VERSION_MAJOR to 1
  [dry-run] Would update GGML_VERSION_MINOR to 0
  [dry-run] Would update GGML_VERSION_PATCH to 0
  [dry-run] Would remove -dev suffix

Step 3: Committing version bump...
  [dry-run] Would commit: 'ggml : bump version to 1.0.0'

Step 4: Creating git tag...
  [dry-run] Would create tag: v1.0.0 with message 'Release version 1.0.0'

Step 5: Preparing for next development cycle...
  [dry-run] Would update GGML_VERSION_MINOR to 1
  [dry-run] Would add -dev suffix back

Step 6: Committing development version...
  [dry-run] Would commit: 'ggml : prepare for development of 1.1.0-dev'

[dry-run] Summary (no changes were made):
  • Would have released version: 1.0.0
  • Would have created tag: v1.0.0
  • Would have set next development version: 1.1.0-dev
```

Refs: https://github.com/ggml-org/ggml/issues/1333

* ggml: create branch for release candidate and check master

* ggml : sign the git tag

CMakeLists.txt
scripts/release.sh [new file with mode: 0755]

index 9ef88c6fd0a85945c3ec4e8f101f4e31655b6ae9..08215bf930550c03f14763499e9cd571d08649e2 100644 (file)
@@ -1,5 +1,41 @@
 cmake_minimum_required(VERSION 3.14) # for add_link_options and implicit target directories.
 project("ggml" C CXX ASM)
+
+### GGML Version
+set(GGML_VERSION_MAJOR 0)
+set(GGML_VERSION_MINOR 9)
+set(GGML_VERSION_PATCH 0)
+set(GGML_VERSION_DEV "-dev")  # "-dev" for development, "" for releases
+set(GGML_VERSION_BASE "${GGML_VERSION_MAJOR}.${GGML_VERSION_MINOR}.${GGML_VERSION_PATCH}")
+
+find_program(GIT_EXE NAMES git git.exe NO_CMAKE_FIND_ROOT_PATH)
+if(GIT_EXE)
+    # Get current git commit hash
+    execute_process(COMMAND ${GIT_EXE} rev-parse --short HEAD
+        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+        OUTPUT_VARIABLE GGML_BUILD_COMMIT
+        OUTPUT_STRIP_TRAILING_WHITESPACE
+        ERROR_QUIET
+    )
+
+    # Check if the working directory is dirty (i.e., has uncommitted changes)
+    execute_process(COMMAND ${GIT_EXE} diff-index --quiet HEAD -- .
+        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+        RESULT_VARIABLE GGML_GIT_DIRTY
+        ERROR_QUIET
+    )
+endif()
+
+# Build the version string with optional -dev suffix and dirty flag
+set(GGML_VERSION "${GGML_VERSION_BASE}${GGML_VERSION_DEV}")
+if(GGML_GIT_DIRTY AND NOT GGML_GIT_DIRTY EQUAL 0)
+    set(GGML_VERSION "${GGML_VERSION}-dirty")
+endif()
+
+if(NOT GGML_BUILD_COMMIT)
+    set(GGML_BUILD_COMMIT "unknown")
+endif()
+
 include(CheckIncludeFileCXX)
 
 set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
@@ -302,26 +338,6 @@ endif()
 # Create CMake package
 #
 
-# Generate version info based on git commit.
-
-if(NOT DEFINED GGML_BUILD_NUMBER)
-    find_program(GIT_EXE NAMES git git.exe REQUIRED NO_CMAKE_FIND_ROOT_PATH)
-    execute_process(COMMAND ${GIT_EXE} rev-list --count HEAD
-        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
-        OUTPUT_VARIABLE GGML_BUILD_NUMBER
-        OUTPUT_STRIP_TRAILING_WHITESPACE
-    )
-
-    if(GGML_BUILD_NUMBER EQUAL 1)
-        message(WARNING "GGML build version fixed at 1 likely due to a shallow clone.")
-    endif()
-
-    execute_process(COMMAND ${GIT_EXE} rev-parse --short HEAD
-        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
-        OUTPUT_VARIABLE GGML_BUILD_COMMIT
-        OUTPUT_STRIP_TRAILING_WHITESPACE
-    )
-endif()
 
 
 # Capture variables prefixed with GGML_.
@@ -350,7 +366,7 @@ set(GGML_VARIABLES_EXPANDED ${variable_set_statements})
 
 # Create the CMake package and set install location.
 
-set(GGML_INSTALL_VERSION 0.0.${GGML_BUILD_NUMBER})
+set(GGML_INSTALL_VERSION ${GGML_VERSION})
 set(GGML_INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_INCLUDEDIR} CACHE PATH "Location of header  files")
 set(GGML_LIB_INSTALL_DIR     ${CMAKE_INSTALL_LIBDIR}     CACHE PATH "Location of library files")
 set(GGML_BIN_INSTALL_DIR     ${CMAKE_INSTALL_BINDIR}     CACHE PATH "Location of binary  files")
diff --git a/scripts/release.sh b/scripts/release.sh
new file mode 100755 (executable)
index 0000000..0265927
--- /dev/null
@@ -0,0 +1,244 @@
+#!/bin/bash
+#
+# Automated release script for ggml.
+#
+# Note: Sync from llama.cpp should be done separately via PR process
+# prior to running this script.
+#
+# Usage:
+#   ./scripts/release.sh [major|minor|patch] [--dry-run]
+#
+# Example usage:
+# $ ./scripts/release.sh minor --dry-run
+#
+# This will show what the actions that would be taken to increment the minor
+# version of the project.
+#
+# This script:
+# 1. Updates version and removes -dev suffix
+# 2. Commits the version bump
+# 3. Creates a git tag
+# 4. Prepares for next development cycle
+#
+
+set -e
+
+if [ ! -f "CMakeLists.txt" ] || [ ! -d "scripts" ]; then
+    echo "Error: Must be run from ggml root directory"
+    exit 1
+fi
+
+# Parse command line arguments
+VERSION_TYPE=""
+DRY_RUN=false
+
+for arg in "$@"; do
+    case $arg in
+        --dry-run)
+            DRY_RUN=true
+            shift
+            ;;
+        major|minor|patch)
+            VERSION_TYPE="$arg"
+            shift
+            ;;
+        *)
+            echo "Error: Unknown argument '$arg'"
+            echo "Usage: $0 [major|minor|patch] [--dry-run]"
+            exit 1
+            ;;
+    esac
+done
+
+# Default to patch if no version type specified
+VERSION_TYPE="${VERSION_TYPE:-patch}"
+
+if [[ ! "$VERSION_TYPE" =~ ^(major|minor|patch)$ ]]; then
+    echo "Error: Version type must be 'major', 'minor', or 'patch'"
+    echo "Usage: $0 [major|minor|patch] [--dry-run]"
+    exit 1
+fi
+
+if [ "$DRY_RUN" = true ]; then
+    echo "[dry-run] - No changes will be made"
+    echo ""
+else
+    echo "Starting automated release process..."
+fi
+
+# Check for uncommitted changes (skip in dry-run)
+if [ "$DRY_RUN" = false ] && ! git diff-index --quiet HEAD --; then
+    echo "Error: You have uncommitted changes. Please commit or stash them first."
+    exit 1
+fi
+
+# Ensure we're on master branch
+CURRENT_BRANCH=$(git branch --show-current)
+if [ "$CURRENT_BRANCH" != "master" ]; then
+    if [ "$DRY_RUN" = true ]; then
+        echo "[dry run] Warning: Not on master branch (currently on: $CURRENT_BRANCH). Continuing with dry-run..."
+        echo ""
+    else
+        echo "Error: Must be on master branch to create release. Currently on: $CURRENT_BRANCH"
+        exit 1
+    fi
+fi
+
+# Check if we have the latest from master (skip in dry-run)
+if [ "$DRY_RUN" = false ]; then
+    echo "Checking if local master is up-to-date with remote..."
+    git fetch origin master
+    LOCAL=$(git rev-parse HEAD)
+    REMOTE=$(git rev-parse origin/master)
+
+    if [ "$LOCAL" != "$REMOTE" ]; then
+        echo "Error: Your local master branch is not up-to-date with origin/master."
+        echo "Please run 'git pull origin master' first."
+        exit 1
+    fi
+    echo "✓ Local master is up-to-date with remote"
+    echo ""
+elif [ "$CURRENT_BRANCH" = "master" ]; then
+    echo "[dry run] Warning: Dry-run mode - not checking if master is up-to-date with remote"
+    echo ""
+fi
+
+# Extract current version from CMakeLists.txt
+echo "Step 1: Reading current version..."
+MAJOR=$(grep "set(GGML_VERSION_MAJOR" CMakeLists.txt | sed 's/.*MAJOR \([0-9]*\).*/\1/')
+MINOR=$(grep "set(GGML_VERSION_MINOR" CMakeLists.txt | sed 's/.*MINOR \([0-9]*\).*/\1/')
+PATCH=$(grep "set(GGML_VERSION_PATCH" CMakeLists.txt | sed 's/.*PATCH \([0-9]*\).*/\1/')
+
+echo "Current version: $MAJOR.$MINOR.$PATCH-dev"
+
+# Calculate new version
+case $VERSION_TYPE in
+    major)
+        NEW_MAJOR=$((MAJOR + 1))
+        NEW_MINOR=0
+        NEW_PATCH=0
+        ;;
+    minor)
+        NEW_MAJOR=$MAJOR
+        NEW_MINOR=$((MINOR + 1))
+        NEW_PATCH=0
+        ;;
+    patch)
+        NEW_MAJOR=$MAJOR
+        NEW_MINOR=$MINOR
+        NEW_PATCH=$((PATCH + 1))
+        ;;
+esac
+
+NEW_VERSION="$NEW_MAJOR.$NEW_MINOR.$NEW_PATCH"
+RC_BRANCH="ggml-rc-v$NEW_VERSION"
+echo "New release version: $NEW_VERSION"
+echo "Release candidate branch: $RC_BRANCH"
+echo ""
+
+# Create release candidate branch
+echo "Step 2: Creating release candidate branch..."
+if [ "$DRY_RUN" = true ]; then
+    echo "  [dry-run] Would create branch: $RC_BRANCH"
+else
+    git checkout -b "$RC_BRANCH"
+    echo "✓ Created and switched to branch: $RC_BRANCH"
+fi
+echo ""
+
+# Update CMakeLists.txt for release
+echo "Step 3: Updating version in CMakeLists.txt..."
+if [ "$DRY_RUN" = true ]; then
+    echo "  [dry-run] Would update GGML_VERSION_MAJOR to $NEW_MAJOR"
+    echo "  [dry-run] Would update GGML_VERSION_MINOR to $NEW_MINOR"
+    echo "  [dry-run] Would update GGML_VERSION_PATCH to $NEW_PATCH"
+    echo "  [dry-run] Would remove -dev suffix"
+else
+    sed -i "s/set(GGML_VERSION_MAJOR [0-9]*)/set(GGML_VERSION_MAJOR $NEW_MAJOR)/" CMakeLists.txt
+    sed -i "s/set(GGML_VERSION_MINOR [0-9]*)/set(GGML_VERSION_MINOR $NEW_MINOR)/" CMakeLists.txt
+    sed -i "s/set(GGML_VERSION_PATCH [0-9]*)/set(GGML_VERSION_PATCH $NEW_PATCH)/" CMakeLists.txt
+    sed -i 's/set(GGML_VERSION_DEV "-dev")/set(GGML_VERSION_DEV "")/' CMakeLists.txt
+fi
+echo ""
+
+# Commit version bump
+echo "Step 4: Committing version bump..."
+if [ "$DRY_RUN" = true ]; then
+    echo "  [dry-run] Would commit: 'ggml : bump version to $NEW_VERSION'"
+else
+    git add CMakeLists.txt
+    git commit -m "ggml : bump version to $NEW_VERSION"
+fi
+echo ""
+
+# Create git tag
+echo "Step 5: Creating signed git tag..."
+if [ "$DRY_RUN" = true ]; then
+    echo "  [dry-run] Would create signed tag: v$NEW_VERSION with message 'Release version $NEW_VERSION'"
+else
+    git tag -s "v$NEW_VERSION" -m "Release version $NEW_VERSION"
+    echo "✓ Created signed tag: v$NEW_VERSION"
+fi
+echo ""
+
+# Prepare for next development cycle
+echo "Step 6: Preparing for next development cycle..."
+case $VERSION_TYPE in
+    major|minor)
+        NEXT_DEV_MINOR=$((NEW_MINOR + 1))
+        NEXT_DEV_VERSION="$NEW_MAJOR.$NEXT_DEV_MINOR.0-dev"
+        if [ "$DRY_RUN" = true ]; then
+            echo "  [dry-run] Would update GGML_VERSION_MINOR to $NEXT_DEV_MINOR"
+        else
+            sed -i "s/set(GGML_VERSION_MINOR [0-9]*)/set(GGML_VERSION_MINOR $NEXT_DEV_MINOR)/" CMakeLists.txt
+        fi
+        ;;
+    patch)
+        NEXT_DEV_PATCH=$((NEW_PATCH + 1))
+        NEXT_DEV_VERSION="$NEW_MAJOR.$NEW_MINOR.$NEXT_DEV_PATCH-dev"
+        if [ "$DRY_RUN" = true ]; then
+            echo "  [dry-run] Would update GGML_VERSION_PATCH to $NEXT_DEV_PATCH"
+        else
+            sed -i "s/set(GGML_VERSION_PATCH [0-9]*)/set(GGML_VERSION_PATCH $NEXT_DEV_PATCH)/" CMakeLists.txt
+        fi
+        ;;
+esac
+
+if [ "$DRY_RUN" = true ]; then
+    echo "  [dry-run] Would add -dev suffix back"
+else
+    sed -i 's/set(GGML_VERSION_DEV "")/set(GGML_VERSION_DEV "-dev")/' CMakeLists.txt
+fi
+echo ""
+
+# Commit development version
+echo "Step 7: Committing development version..."
+if [ "$DRY_RUN" = true ]; then
+    echo "  [dry-run] Would commit: 'ggml : prepare for development of $NEXT_DEV_VERSION'"
+else
+    git add CMakeLists.txt
+    git commit -m "ggml : prepare for development of $NEXT_DEV_VERSION"
+fi
+
+echo ""
+if [ "$DRY_RUN" = true ]; then
+    echo "[dry-run] Summary (no changes were made):"
+    echo "  • Would have created branch: $RC_BRANCH"
+    echo "  • Would have created tag: v$NEW_VERSION"
+    echo "  • Would have set next development version: $NEXT_DEV_VERSION"
+else
+    echo "Release process completed!"
+    echo "Summary:"
+    echo "  • Created branch: $RC_BRANCH"
+    echo "  • Created tag: v$NEW_VERSION"
+    echo "  • Next development version: $NEXT_DEV_VERSION"
+fi
+if [ "$DRY_RUN" = false ]; then
+    echo "Next steps:"
+    echo "  • Review the commits and tag on branch $RC_BRANCH"
+    echo "  • Push branch to remote: git push origin $RC_BRANCH"
+    echo "  • Create a Pull Request from $RC_BRANCH to master"
+    echo "  • After PR is merged, push the tag: git push origin v$NEW_VERSION"
+    echo "  • The release will be completed once the tag is pushed"
+    echo ""
+fi