diff --git a/.github/scripts/update_version_in_docs.py b/.github/scripts/update_version_in_docs.py
new file mode 100755
index 0000000..51841e1
--- /dev/null
+++ b/.github/scripts/update_version_in_docs.py
@@ -0,0 +1,153 @@
+#!/usr/bin/env python3
+
+import os
+import re
+import shutil
+import subprocess
+import sys
+
+
+def get_release_version():
+ """
+ Get the release version from RELEASE_VERSION environment variable or Maven.
+ Returns the version string without -SNAPSHOT suffix.
+ """
+ release_version = os.environ.get("RELEASE_VERSION")
+
+ if release_version:
+ return release_version
+
+ # Check if Maven is available
+ if not shutil.which("mvn"):
+ print("Error: Maven executable not found in PATH.", file=sys.stderr)
+ sys.exit(1)
+
+ try:
+ # Get Maven version
+ result = subprocess.run(
+ [
+ "mvn",
+ "-q",
+ "--non-recursive",
+ "help:evaluate",
+ "-Dexpression=project.version",
+ "-DforceStdout",
+ ],
+ capture_output=True,
+ text=True,
+ check=True,
+ )
+
+ mvn_version = result.stdout.strip().split("\n")[-1]
+ release_version = mvn_version.replace("-SNAPSHOT", "")
+
+ if not release_version:
+ print("Error: derived release version is empty.", file=sys.stderr)
+ sys.exit(1)
+
+ return release_version
+
+ except subprocess.CalledProcessError:
+ print("Error: unable to determine project version from Maven.", file=sys.stderr)
+ sys.exit(1)
+
+
+def update_readme_versions(readme_path, release_version):
+ """
+ Update version references in README.md file.
+ Returns True if the file was modified, False otherwise.
+ """
+ try:
+ with open(readme_path, "r", encoding="utf-8") as f:
+ content = f.read()
+ except FileNotFoundError:
+ print(f'Error: README file not found at "{readme_path}".', file=sys.stderr)
+ sys.exit(1)
+
+ original_content = content
+
+ # Pattern 1: Maven dependency version
+ # Matches: X.Y.Z
+ maven_pattern = r"(infobip-openapi-mcp-spring-boot-starter\s*)[^<]+()"
+ content = re.sub(maven_pattern, rf"\g<1>{release_version}\g<2>", content)
+
+ # Pattern 2: Gradle dependency version
+ # Matches: implementation("com.infobip.openapi.mcp:infobip-openapi-mcp-spring-boot-starter:X.Y.Z")
+ gradle_pattern = r'(implementation\("com\.infobip\.openapi\.mcp:infobip-openapi-mcp-spring-boot-starter:)[^"]+("\))'
+ content = re.sub(gradle_pattern, rf"\g<1>{release_version}\g<2>", content)
+
+ # Check if any changes were made
+ if content == original_content:
+ print(f'No version references found or updated in "{readme_path}".')
+ return False
+
+ # Write the updated content back to the file
+ with open(readme_path, "w", encoding="utf-8") as f:
+ f.write(content)
+
+ print(f'Successfully updated version references to "{release_version}" in README.md')
+ return True
+
+
+def commit_files_if_changed(file_paths, release_version):
+ """
+ Commit the files if they have changes.
+ """
+ try:
+ # Check if there are any changes in the provided files
+ result = subprocess.run(
+ ["git", "diff", "--quiet", "--"] + file_paths, capture_output=True
+ )
+
+ if result.returncode == 0:
+ # No changes
+ print(f'No changes detected in any files to commit.')
+ else:
+ # Changes detected, commit them
+ subprocess.run(["git", "add"] + file_paths, check=True)
+ subprocess.run(
+ [
+ "git",
+ "commit",
+ "-m",
+ f"Update version references to {release_version}",
+ ],
+ check=True,
+ )
+ print(f'Committed version updates for {release_version}')
+ except subprocess.CalledProcessError as e:
+ print(f"Error: failed to commit changes: {e}", file=sys.stderr)
+ sys.exit(1)
+
+
+def main():
+ # Get paths
+ readme_path = sys.argv[1] if len(sys.argv) > 1 else "./README.md"
+
+ # Check if README exists
+ if not os.path.isfile(readme_path):
+ print(f'Error: README file not found at "{readme_path}".', file=sys.stderr)
+ sys.exit(1)
+
+ # Get release version
+ release_version = get_release_version()
+ print(f'Updating version references to {release_version}')
+
+ # Track all files that need to be committed
+ files_to_commit = []
+
+ # Update the README
+ print(f'\nUpdating README.md...')
+ if update_readme_versions(readme_path, release_version):
+ files_to_commit.append(readme_path)
+
+ # Commit all changes together if there are any
+ if files_to_commit:
+ print(f'\nCommitting {len(files_to_commit)} file(s)...')
+ commit_files_if_changed(files_to_commit, release_version)
+ else:
+ print('\nNo files were modified.')
+
+
+if __name__ == "__main__":
+ main()
\ No newline at end of file
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index e4b8ee3..f344c32 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -35,6 +35,10 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
RELEASE_VERSION: ${{ github.event.inputs.release_version }}
+ - name: Update version in docs
+ run: ./.github/scripts/update_version_in_docs.py
+ env:
+ RELEASE_VERSION: ${{ github.event.inputs.release_version }}
- name: Prepare maven release
run: ./.github/scripts/prepare_maven_release.sh
env:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ad71060..6b7f75d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
+- A new step in the release workflow that automatically updates references to framework version in `README.md`
- `./examples/infobip-sms-mock-mcp` project that demonstrates the recently introduced mock tool mode.
### Changed