Enhance generator to update changelog only if generated code differs from existing (#684)
* Enhance generator to update changelog only if generated code differs from existing Signed-off-by: saimedhi <saimedhi@amazon.com> * Enhance generator to update changelog only if generated code differs from existing Signed-off-by: saimedhi <saimedhi@amazon.com> --------- Signed-off-by: saimedhi <saimedhi@amazon.com>
This commit is contained in:
committed by
GitHub
parent
4b69c09416
commit
d36a882eaf
@@ -13,6 +13,7 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
|
||||
- Added GHA release ([#614](https://github.com/opensearch-project/opensearch-py/pull/614))
|
||||
- Incorporated API generation into CI workflow and fixed 'generate' nox session ([#660](https://github.com/opensearch-project/opensearch-py/pull/660))
|
||||
- Added an automated api update bot for opensearch-py ([#664](https://github.com/opensearch-project/opensearch-py/pull/664))
|
||||
- Enhance generator to update changelog only if generated code differs from existing ([#684](https://github.com/opensearch-project/opensearch-py/pull/684))
|
||||
### Changed
|
||||
- Updated the `get_policy` API in the index_management plugin to allow the policy_id argument as optional ([#633](https://github.com/opensearch-project/opensearch-py/pull/633))
|
||||
- Updated the `point_in_time.md` guide with examples demonstrating the usage of the new APIs as alternatives to the deprecated ones. ([#661](https://github.com/opensearch-project/opensearch-py/pull/661))
|
||||
|
||||
+2
-1
@@ -146,4 +146,5 @@ def generate(session: Any) -> None:
|
||||
"""
|
||||
session.install("-rdev-requirements.txt")
|
||||
session.run("python", "utils/generate_api.py")
|
||||
session.notify("format")
|
||||
session.run("nox", "-s", "format", external=True)
|
||||
session.run("python", "utils/changelog_updater.py")
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# The OpenSearch Contributors require contributions made to
|
||||
# this file be licensed under the Apache-2.0 license or a
|
||||
# compatible open source license.
|
||||
#
|
||||
# Modifications Copyright OpenSearch Contributors. See
|
||||
# GitHub history for details.
|
||||
|
||||
import filecmp
|
||||
import os
|
||||
import shutil
|
||||
|
||||
import requests
|
||||
|
||||
|
||||
def main() -> None:
|
||||
"""
|
||||
Update CHANGELOG.md when API generator produces new code differing from existing.
|
||||
"""
|
||||
root_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
after_paths = [
|
||||
os.path.join(root_dir, f"opensearchpy/{folder}")
|
||||
for folder in ["client", "_async/client"]
|
||||
]
|
||||
|
||||
before_paths = [
|
||||
os.path.join(root_dir, f"before_generate/{folder}")
|
||||
for folder in ["client", "async_client"]
|
||||
]
|
||||
|
||||
# Compare only .py files and take their union for client and async_client directories
|
||||
before_files_client = set(
|
||||
file for file in os.listdir(before_paths[0]) if file.endswith(".py")
|
||||
)
|
||||
after_files_client = set(
|
||||
file for file in os.listdir(after_paths[0]) if file.endswith(".py")
|
||||
)
|
||||
|
||||
before_files_async_client = set(
|
||||
file for file in os.listdir(before_paths[1]) if file.endswith(".py")
|
||||
)
|
||||
after_files_async_client = set(
|
||||
file for file in os.listdir(after_paths[1]) if file.endswith(".py")
|
||||
)
|
||||
|
||||
all_files_union_client = before_files_client.union(after_files_client)
|
||||
all_files_union_async_client = before_files_async_client.union(
|
||||
after_files_async_client
|
||||
)
|
||||
|
||||
# Compare files and check for mismatches or errors for client and async_client directories
|
||||
mismatch_client, errors_client = filecmp.cmpfiles(
|
||||
before_paths[0], after_paths[0], all_files_union_client, shallow=True
|
||||
)[1:]
|
||||
mismatch_async_client, errors_async_client = filecmp.cmpfiles(
|
||||
before_paths[1], after_paths[1], all_files_union_async_client, shallow=True
|
||||
)[1:]
|
||||
|
||||
if mismatch_client or errors_client or mismatch_async_client or errors_async_client:
|
||||
print("Changes detected")
|
||||
response = requests.get(
|
||||
"https://api.github.com/repos/opensearch-project/opensearch-api-specification/commits"
|
||||
)
|
||||
if response.ok:
|
||||
commit_info = response.json()[0]
|
||||
commit_url = commit_info["html_url"]
|
||||
latest_commit_sha = commit_info.get("sha")
|
||||
else:
|
||||
raise Exception(
|
||||
f"Failed to fetch opensearch-api-specification commit information. Status code: {response.status_code}"
|
||||
)
|
||||
|
||||
with open("CHANGELOG.md", "r+", encoding="utf-8") as file:
|
||||
content = file.read()
|
||||
if commit_url not in content:
|
||||
if "### Updated APIs" in content:
|
||||
file_content = content.replace(
|
||||
"### Updated APIs",
|
||||
f"### Updated APIs\n- Updated opensearch-py APIs to reflect [opensearch-api-specification@{latest_commit_sha[:7]}]({commit_url})",
|
||||
1,
|
||||
)
|
||||
file.seek(0)
|
||||
file.write(file_content)
|
||||
file.truncate()
|
||||
else:
|
||||
raise Exception(
|
||||
"'Updated APIs' section is not present in CHANGELOG.md"
|
||||
)
|
||||
else:
|
||||
print("No changes detected")
|
||||
|
||||
# Clean up
|
||||
for path in before_paths:
|
||||
shutil.rmtree(path)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
+17
-28
@@ -33,6 +33,7 @@
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
from functools import lru_cache
|
||||
from itertools import chain, groupby
|
||||
from operator import itemgetter
|
||||
@@ -764,34 +765,22 @@ def dump_modules(modules: Any) -> None:
|
||||
unasync.unasync_files(filepaths, rules)
|
||||
blacken(CODE_ROOT / "opensearchpy")
|
||||
|
||||
# Updating the CHANGELOG.md
|
||||
response = requests.get(
|
||||
"https://api.github.com/repos/opensearch-project/opensearch-api-specification/commits"
|
||||
)
|
||||
if response.ok:
|
||||
commit_info = response.json()[0]
|
||||
commit_url = commit_info["html_url"]
|
||||
latest_commit_sha = commit_info.get("sha")
|
||||
else:
|
||||
raise Exception(
|
||||
f"Failed to fetch opensearch-api-specification commit information. Status code: {response.status_code}"
|
||||
)
|
||||
|
||||
with open("CHANGELOG.md", "r+", encoding="utf-8") as file:
|
||||
content = file.read()
|
||||
if commit_url not in content:
|
||||
if "### Updated APIs" in content:
|
||||
file_content = content.replace(
|
||||
"### Updated APIs",
|
||||
f"### Updated APIs\n- Updated opensearch-py APIs to reflect [opensearch-api-specification@{latest_commit_sha[:7]}]({commit_url})",
|
||||
1,
|
||||
)
|
||||
file.seek(0)
|
||||
file.write(file_content)
|
||||
file.truncate()
|
||||
else:
|
||||
raise Exception("'Updated APIs' section is not present in CHANGELOG.md")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Store directories for comparison pre-generation vs post-generation.
|
||||
root_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
before_paths = [
|
||||
os.path.join(root_dir, f"before_generate/{folder}")
|
||||
for folder in ["client", "async_client"]
|
||||
]
|
||||
|
||||
for path in before_paths:
|
||||
if os.path.exists(path):
|
||||
shutil.rmtree(path)
|
||||
|
||||
shutil.copytree(os.path.join(root_dir, "opensearchpy/client"), before_paths[0])
|
||||
shutil.copytree(
|
||||
os.path.join(root_dir, "opensearchpy/_async/client"), before_paths[1]
|
||||
)
|
||||
|
||||
dump_modules(read_modules())
|
||||
|
||||
Reference in New Issue
Block a user