From 3bed96bb4de7272a6e1a299279492576f620cfe3 Mon Sep 17 00:00:00 2001 From: Vitor Bandeira Date: Sat, 26 Sep 2026 17:32:12 -0300 Subject: [PATCH 1/2] fix(util): exit non-zero when uploadMetadata publish fails A failed Pub/Sub publish printed a warning, and the script exited 0. When the publish credential was rejected with a 401, CI builds passed, but the QoR dashboard received no results. The dashboard baseline then stayed on an old build. Later builds were compared against that old build. They failed on metric changes from many merges, not from their own commit. Exit 1 when the pipeline report or a v1 fallback message fails to publish. CI then shows the upload failure in the build that has it. Signed-off-by: Vitor Bandeira --- flow/util/uploadMetadata.py | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/flow/util/uploadMetadata.py b/flow/util/uploadMetadata.py index 6918ccf2b4..616d00e952 100755 --- a/flow/util/uploadMetadata.py +++ b/flow/util/uploadMetadata.py @@ -3,6 +3,7 @@ import json import argparse import os +import sys # --- PUBSUB --- from google.cloud import pubsub_v1 @@ -248,7 +249,7 @@ def publish_v1_per_design(publisher, topic_path, design_records, args, provenanc Emits one v1-format message per design (no payload_schema_version, metrics flattened at the root), matching the legacy schema the ingestion service - still supports. + still supports. Returns the number of designs that failed to publish. Provenance is mirrored onto every message: all of them resolve to the same build, and the backend upserts components by path, so N copies converge on @@ -261,6 +262,7 @@ def publish_v1_per_design(publisher, topic_path, design_records, args, provenanc key presence rather than by version. """ futures = [] + failed = 0 for d in design_records: payload = { "build_id": args.buildID, @@ -284,8 +286,9 @@ def publish_v1_per_design(publisher, topic_path, design_records, args, provenanc ) futures.append((d, future)) except Exception as e: + failed += 1 print( - f"[WARN] Pub/Sub v1 fallback publish failed for " + f"[ERROR] Pub/Sub v1 fallback publish failed for " f"{d['platform']} {d['design']} {d['variant']}: {e}" ) @@ -297,10 +300,12 @@ def publish_v1_per_design(publisher, topic_path, design_records, args, provenanc f"{d['platform']} {d['design']} {d['variant']}." ) except Exception as e: + failed += 1 print( - f"[WARN] Pub/Sub v1 fallback publish failed for " + f"[ERROR] Pub/Sub v1 fallback publish failed for " f"{d['platform']} {d['design']} {d['variant']}: {e}" ) + return failed # --- END PUBSUB --- @@ -353,6 +358,9 @@ def publish_v1_per_design(publisher, topic_path, design_records, args, provenanc # --- END PUBSUB --- # --- PUBSUB --- +# A failed publish exits non-zero. A warning alone let CI builds pass while the +# QoR dashboard stopped receiving results, which froze the baseline that later +# builds are compared against. if publisher and design_records: provenance = load_provenance(args.provenanceFile) payload = build_pipeline_payload(design_records, args, provenance) @@ -364,7 +372,12 @@ def publish_v1_per_design(publisher, topic_path, design_records, args, provenanc f"{MAX_PUBSUB_BYTES // 1024} KB cap. Falling back to v1 per-design publish " f"({len(design_records)} messages)." ) - publish_v1_per_design(publisher, topic_path, design_records, args, provenance) + failed = publish_v1_per_design( + publisher, topic_path, design_records, args, provenance + ) + if failed: + print(f"[ERROR] {failed} of {len(design_records)} designs were not published.") + sys.exit(1) else: try: publish_pipeline_report( @@ -376,7 +389,8 @@ def publish_v1_per_design(publisher, topic_path, design_records, args, provenanc provenance, ) except Exception as e: - print(f"[WARN] Pub/Sub publish failed for pipeline report: {e}") + print(f"[ERROR] Pub/Sub publish failed for pipeline report: {e}") + sys.exit(1) elif publisher and not design_records: print("[WARN] Pub/Sub publisher initialized but no design records were collected.") # --- END PUBSUB --- From ee0968ceaa5be773cb49f9438171e7b78aed9109 Mon Sep 17 00:00:00 2001 From: Vitor Bandeira Date: Mon, 28 Sep 2026 01:13:00 -0300 Subject: [PATCH 2/2] style(util): wrap long print line for black Signed-off-by: Vitor Bandeira --- flow/util/uploadMetadata.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/flow/util/uploadMetadata.py b/flow/util/uploadMetadata.py index 616d00e952..b7a49c27f3 100755 --- a/flow/util/uploadMetadata.py +++ b/flow/util/uploadMetadata.py @@ -376,7 +376,9 @@ def publish_v1_per_design(publisher, topic_path, design_records, args, provenanc publisher, topic_path, design_records, args, provenance ) if failed: - print(f"[ERROR] {failed} of {len(design_records)} designs were not published.") + print( + f"[ERROR] {failed} of {len(design_records)} designs were not published." + ) sys.exit(1) else: try: