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