From c4f38fb2878406b949d1d1fe80f6df6f33924c10 Mon Sep 17 00:00:00 2001 From: emdneto <9735060+emdneto@users.noreply.github.com> Date: Wed, 11 Jun 2025 21:11:29 -0300 Subject: [PATCH 1/3] infra: add griffe to public-symbols check CI Signed-off-by: emdneto <9735060+emdneto@users.noreply.github.com> --- scripts/eachdist.py | 31 +++++++++++++++++++++++++++++++ scripts/griffe_check.sh | 28 ++++++++++++++++++++++++++++ tox.ini | 7 ++++++- 3 files changed, 65 insertions(+), 1 deletion(-) create mode 100755 scripts/griffe_check.sh diff --git a/scripts/eachdist.py b/scripts/eachdist.py index b01d0733657..24f9a8c02cb 100755 --- a/scripts/eachdist.py +++ b/scripts/eachdist.py @@ -272,6 +272,21 @@ def setup_instparser(instparser): ), ) + listparser = subparsers.add_parser( + "list", + help="List all packages with their relative paths", + ) + listparser.set_defaults(func=list_args) + listparser.add_argument( + "--mode", + "-m", + default="DEFAULT", + help=cleandoc( + """Section of config file to use for target selection configuration. + See description of exec for available options.""" + ), + ) + return parser.parse_args(args) @@ -741,6 +756,22 @@ def version_args(args): print(cfg[args.mode]["version"]) +def list_args(args): + rootpath = find_projectroot() + targets = find_targets(args.mode, rootpath) + + if not targets: + sys.exit(f"Error: No targets selected (root: {rootpath})") + + excluded_dirs = ["docs", "scripts"] + + for target in targets: + rel_path = target.relative_to(rootpath) + if any(excluded in str(rel_path) for excluded in excluded_dirs): + continue + print(str(rel_path)) + + def main(): args = parse_args() args.func(args) diff --git a/scripts/griffe_check.sh b/scripts/griffe_check.sh new file mode 100755 index 00000000000..ce287f6bbbe --- /dev/null +++ b/scripts/griffe_check.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +OVERALL_EXIT_CODE=0 +BRANCH_TO_COMPARE="main" +GRIFFE_CMD="griffe check -v -a $BRANCH_TO_COMPARE " + +run_griffe_check() { + local package_spec="$1" + local package_name + local search_path="" + + if [[ "$package_spec" == *"/"* ]]; then + search_path=$(echo "$package_spec" | cut -d'/' -f1) + package_name=$(echo "$package_spec" | cut -d'/' -f2) + $GRIFFE_CMD -s "$search_path" "$package_name" + else + package_name="$package_spec" + $GRIFFE_CMD "$package_name" + fi +} + +while read -r package; do + if ! run_griffe_check "$package"; then + OVERALL_EXIT_CODE=1 + fi +done < <(python "$(dirname "$0")/eachdist.py" list) + +exit $OVERALL_EXIT_CODE diff --git a/tox.ini b/tox.ini index 81451578b59..c88b954440b 100644 --- a/tox.ini +++ b/tox.ini @@ -309,11 +309,16 @@ commands_post = docker-compose down -v [testenv:public-symbols-check] -basepython: python3 recreate = True +allowlist_externals = + {toxinidir}/scripts/griffe_check.sh deps = GitPython==3.1.40 + griffe==1.7.3 + toml commands = + ; griffe check before to fail fast if there are any issues + {toxinidir}/scripts/griffe_check.sh python {toxinidir}/scripts/public_symbols_checker.py [testenv:generate-workflows] From 6b4dc7f984788585201bb014dab9cdfbaf5f763a Mon Sep 17 00:00:00 2001 From: emdneto <9735060+emdneto@users.noreply.github.com> Date: Mon, 23 Jun 2025 20:47:29 -0300 Subject: [PATCH 2/3] use griffe python api --- scripts/eachdist.py | 31 -------------------- scripts/griffe_check.py | 65 +++++++++++++++++++++++++++++++++++++++++ scripts/griffe_check.sh | 28 ------------------ tox.ini | 2 +- 4 files changed, 66 insertions(+), 60 deletions(-) create mode 100644 scripts/griffe_check.py delete mode 100755 scripts/griffe_check.sh diff --git a/scripts/eachdist.py b/scripts/eachdist.py index 24f9a8c02cb..b01d0733657 100755 --- a/scripts/eachdist.py +++ b/scripts/eachdist.py @@ -272,21 +272,6 @@ def setup_instparser(instparser): ), ) - listparser = subparsers.add_parser( - "list", - help="List all packages with their relative paths", - ) - listparser.set_defaults(func=list_args) - listparser.add_argument( - "--mode", - "-m", - default="DEFAULT", - help=cleandoc( - """Section of config file to use for target selection configuration. - See description of exec for available options.""" - ), - ) - return parser.parse_args(args) @@ -756,22 +741,6 @@ def version_args(args): print(cfg[args.mode]["version"]) -def list_args(args): - rootpath = find_projectroot() - targets = find_targets(args.mode, rootpath) - - if not targets: - sys.exit(f"Error: No targets selected (root: {rootpath})") - - excluded_dirs = ["docs", "scripts"] - - for target in targets: - rel_path = target.relative_to(rootpath) - if any(excluded in str(rel_path) for excluded in excluded_dirs): - continue - print(str(rel_path)) - - def main(): args = parse_args() args.func(args) diff --git a/scripts/griffe_check.py b/scripts/griffe_check.py new file mode 100644 index 00000000000..475dfba8372 --- /dev/null +++ b/scripts/griffe_check.py @@ -0,0 +1,65 @@ +import argparse +import sys + +import griffe +from eachdist import find_projectroot, find_targets + + +def get_modules() -> list[str]: + rootpath = find_projectroot() + targets = find_targets("DEFAULT", rootpath) + + dirs_to_exclude = [ + "docs", + "scripts", + "opentelemetry-docker-tests", + "examples", + "_template", + ] + + packages = [] + for target in targets: + rel_path = target.relative_to(rootpath) + if not any(excluded in str(rel_path) for excluded in dirs_to_exclude): + packages.append(str(rel_path / "src")) + return packages + + +def main(): + parser = argparse.ArgumentParser( + description="Check for breaking changes using griffe", + formatter_class=argparse.ArgumentDefaultsHelpFormatter, + ) + + parser.add_argument( + "--module", + default="opentelemetry", + help="Name of the module to check for breaking changes (e.g., opentelemetry, opentelemetry.sdk, opentelemetry.sdk.resources)", + ) + parser.add_argument( + "--against", + default="main", + help="Git ref to compare against (e.g., branch, tag, or commit)", + ) + args = parser.parse_args() + + modules = get_modules() + base = griffe.load(args.module, search_paths=modules) + against = griffe.load_git( + args.module, ref=args.against, search_paths=modules + ) + + breakages = list(griffe.find_breaking_changes(against, base)) + + if breakages: + for b in breakages: + # We can use `b.explain()` to get a detailed explanation of the breaking change + # and we can iterate over breakages to perform more complex logic + # like skipping per object.path or breakage type + print(b.explain()) + return 1 + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/scripts/griffe_check.sh b/scripts/griffe_check.sh deleted file mode 100755 index ce287f6bbbe..00000000000 --- a/scripts/griffe_check.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/bash - -OVERALL_EXIT_CODE=0 -BRANCH_TO_COMPARE="main" -GRIFFE_CMD="griffe check -v -a $BRANCH_TO_COMPARE " - -run_griffe_check() { - local package_spec="$1" - local package_name - local search_path="" - - if [[ "$package_spec" == *"/"* ]]; then - search_path=$(echo "$package_spec" | cut -d'/' -f1) - package_name=$(echo "$package_spec" | cut -d'/' -f2) - $GRIFFE_CMD -s "$search_path" "$package_name" - else - package_name="$package_spec" - $GRIFFE_CMD "$package_name" - fi -} - -while read -r package; do - if ! run_griffe_check "$package"; then - OVERALL_EXIT_CODE=1 - fi -done < <(python "$(dirname "$0")/eachdist.py" list) - -exit $OVERALL_EXIT_CODE diff --git a/tox.ini b/tox.ini index c88b954440b..9058de77a93 100644 --- a/tox.ini +++ b/tox.ini @@ -318,7 +318,7 @@ deps = toml commands = ; griffe check before to fail fast if there are any issues - {toxinidir}/scripts/griffe_check.sh + python {toxinidir}/scripts/griffe_check.py python {toxinidir}/scripts/public_symbols_checker.py [testenv:generate-workflows] From 75f799f6e8559837f976d9c5d100fa8bb888202b Mon Sep 17 00:00:00 2001 From: emdneto <9735060+emdneto@users.noreply.github.com> Date: Mon, 23 Jun 2025 20:51:20 -0300 Subject: [PATCH 3/3] cleanup --- tox.ini | 2 -- 1 file changed, 2 deletions(-) diff --git a/tox.ini b/tox.ini index 9058de77a93..da5b62beca6 100644 --- a/tox.ini +++ b/tox.ini @@ -310,8 +310,6 @@ commands_post = [testenv:public-symbols-check] recreate = True -allowlist_externals = - {toxinidir}/scripts/griffe_check.sh deps = GitPython==3.1.40 griffe==1.7.3