From 4c13874ca83c00934d24be99b92dcc7183055d71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C5=A1a=20=C5=A0arenac?= Date: Fri, 6 Mar 2026 20:41:37 +0100 Subject: [PATCH 1/3] fix(logging): quiet routine pip module logs Healthy upgrade runs call pip for bookkeeping, and emitting those probes at INFO made normal activity look suspicious. Move the message to DEBUG so operator logs stay focused on real run outcomes. --- upgrade/scripts/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/upgrade/scripts/utils.py b/upgrade/scripts/utils.py index f8a69b1..bb099b9 100644 --- a/upgrade/scripts/utils.py +++ b/upgrade/scripts/utils.py @@ -142,7 +142,7 @@ def run_python_module(module_name, *args, **kwargs): # check for arguments stored in an environment variable UPDATE_MODULE_NAME var_name = f"UPDATE_{module_name.upper()}" args = tuple(os.environ.get(var_name, "").split()) - logging.info("running %s python module", module_name) + logging.debug("running %s python module", module_name) py_executable = kwargs.pop("py_executable", sys.executable) try: return run(*((py_executable, "-m", module_name) + args), **kwargs) From 41348bbba4aa0fca0005231bba2f88b0571ac002 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C5=A1a=20=C5=A0arenac?= Date: Fri, 6 Mar 2026 20:41:37 +0100 Subject: [PATCH 2/3] fix(summary): reserve upgrade_failed for real failures Operators rely on the summary line to tell whether an upgrade actually failed. Stop treating ordinary command output as a failure signal so unchanged runs no longer read like broken upgrades. --- upgrade/scripts/upgrade_python_package.py | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/upgrade/scripts/upgrade_python_package.py b/upgrade/scripts/upgrade_python_package.py index b8dcb66..5590515 100644 --- a/upgrade/scripts/upgrade_python_package.py +++ b/upgrade/scripts/upgrade_python_package.py @@ -54,6 +54,7 @@ def upgrade_and_run( package_name = package_install_cmd.split("[", 1)[0] was_updated = False response_err = "" + result = "unchanged" if version is not None: logging.debug( "Trying to install version %s of package %s", version, package_name @@ -66,6 +67,7 @@ def upgrade_and_run( slack_webhook_url, constraints_path, ) + result = "upgraded" if was_updated else "upgrade_failed" else: logging.debug('Trying to upgrade "%s" package.', package_name) was_updated, response_err = attempt_upgrade( @@ -76,6 +78,7 @@ def upgrade_and_run( constraints_path, *args, ) + result = "upgraded" if was_updated else "unchanged" if not skip_post_install and (was_updated or force): module_name = package_name.replace("-", "_") try_running_module( @@ -84,7 +87,7 @@ def upgrade_and_run( cloudsmith_url=cloudsmith_url, slack_webhook_url=slack_webhook_url, ) - return was_updated, response_err + return result, response_err def get_constraints_file_path(package_name, site_packages_dir=None): @@ -349,7 +352,7 @@ def upgrade_from_local_wheel( ) except Exception as e: response_err = str(e) - return False, response_err + return "upgrade_failed", response_err if not skip_post_install: module_name = package_name.replace("-", "_").split("==")[0] try_running_module(module_name, *args) @@ -359,7 +362,8 @@ def upgrade_from_local_wheel( success = installed_version is not None and spec.contains(installed_version) else: success = installed_version is not None - return success, resp + result = "upgraded" if success else "upgrade_failed" + return result, resp def attempt_to_install_version( @@ -700,6 +704,7 @@ def upgrade_python_package( success = False run_succeeded = False response_output = "" + operation_result = "unchanged" start_time = time.monotonic() package_name, _ = split_package_name_and_extra(package) current_version = None @@ -722,7 +727,7 @@ def upgrade_python_package( wheels_path = wheels_path or "/vagrant/wheels" slack_webhook_url = slack_webhook_url or os.environ.get("SLACK_WEBHOOK_URL") if update_from_local_wheels: - success, response_output = upgrade_from_local_wheel( + operation_result, response_output = upgrade_from_local_wheel( package, skip_post_install, wheels_path=wheels_path, @@ -732,10 +737,11 @@ def upgrade_python_package( constraints_path=constraints_path, *vars, ) + success = operation_result == "upgraded" elif should_run_initial_post_install: run_initial_post_install(package, *vars) else: - success, response_output = upgrade_and_run( + operation_result, response_output = upgrade_and_run( package, force, skip_post_install, @@ -746,6 +752,7 @@ def upgrade_python_package( constraints_path, *vars, ) + success = operation_result == "upgraded" run_succeeded = True except Exception as e: logging.exception("Upgrade run failed package=%s", package) @@ -760,12 +767,8 @@ def upgrade_python_package( if not run_succeeded: result = "errored" - elif success: - result = "upgraded" - elif response_output: - result = "upgrade_failed" else: - result = "unchanged" + result = operation_result log_run_summary( script="upgrade_python_package", From aa4b82a5f46eafeef4d02ed0dff2edea9512f96f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C5=A1a=20=C5=A0arenac?= Date: Fri, 6 Mar 2026 20:46:28 +0100 Subject: [PATCH 3/3] docs(changelog): prepare release notes for logging fixes The next release should explain why operator logs look different and why upgrade summaries can be trusted again. Capture the branch changes in Unreleased so release prep does not depend on reconstructing intent from commits later. --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 87a1e5a..d87f55c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,8 +12,12 @@ and this project adheres to a _modified_ form of _[Semantic Versioning][semver]_ ### Changed +- Reduce routine `pip` module logging noise so operator-facing logs stay focused on run summaries. + ### Fixed +- Keep upgrade run summaries accurate by reserving `upgrade_failed` for actual failed upgrade paths instead of unchanged runs with command output. + ### Removed ## [0.9.2]