Skip to content
Bitcoin Roots

v30.3-roots.1 · Commit 66: [PATCH 66/68] fix(release): validate notices and reuse proven promotion CI

ci/change-classifier.py

Before: ci/change-classifier.py · After: ci/change-classifier.py

File metadata
index 29afcbeccf9ee15c3ff6fd7b1b84f312cbac1657..11caa47e2367156f0f87573342c61e92ebb86ed6 100755

Download original patch · Release notes

Diff rows 1–36 of 36. Line numbers refer to the original before/after files.

+ Added− RemovedUnmarked lines are context.

Scroll the code area horizontally to read long lines. Before is on the left; after is on the right. Unified view fits narrow screens more easily.

ci/change-classifier.py CHANGED
@@ -50,7 +50,7 @@ def classify_path(path, policy):
50
  return "unknown"
51
 
52
 
53
- def result_for(files, labels, truncated, error, policy):
54
  complete = (isinstance(files, list) and isinstance(labels, list) and
55
  all(isinstance(label, str) for label in labels) and
56
  not truncated and not error)
@@ -88,6 +88,11 @@ def result_for(files, labels, truncated, error, policy):
88
  selected[label.removeprefix("ci:")] = True
89
  if selected["nightly_full"]:
90
  selected.update({name: False for name in OPTIONAL_SELECTION if name != "nightly_full"})
 
 
 
 
 
91
  return {
92
  "version": policy["version"],
93
  "categories": [category for category in KNOWN_CATEGORIES if category in categories],
@@ -118,6 +123,8 @@ def main():
118
  parser.add_argument("--truncated", action="store_true", help="Fail open because the file list is incomplete")
119
  parser.add_argument("--error", action="store_true", help="Fail open because file retrieval failed")
120
  parser.add_argument("--github-output", help="Path to append GitHub Actions outputs")
 
 
121
  args = parser.parse_args()
122
  try:
123
  files = load_json(args.files_json, "--files-json")
@@ -128,7 +135,8 @@ def main():
128
  tuple(policy["labels"]) != KNOWN_LABELS or
129
  set(policy["defaults"]) != {"baseline", *KNOWN_CATEGORIES}):
130
  raise ValueError("policy has an unsupported schema")
131
- result = result_for(files, labels, args.truncated, args.error, policy)
 
132
  except (OSError, ValueError, KeyError, TypeError, json.JSONDecodeError):
133
  # The script itself must fail open if its API or policy interface changes.
134
  result = result_for(None, None, True, True, SAFE_POLICY)
 
50
  return "unknown"
51
 
52
 
53
+ def result_for(files, labels, truncated, error, policy, reuse_canonical_ci=False):
54
  complete = (isinstance(files, list) and isinstance(labels, list) and
55
  all(isinstance(label, str) for label in labels) and
56
  not truncated and not error)
 
88
  selected[label.removeprefix("ci:")] = True
89
  if selected["nightly_full"]:
90
  selected.update({name: False for name in OPTIONAL_SELECTION if name != "nightly_full"})
91
+ if reuse_canonical_ci and complete and "unknown" not in categories and not labels:
92
+ # The caller has verified exact canonical CI and promotion tree parity.
93
+ # Baseline lint/classifier and separate main documentation checks remain.
94
+ selected.update({name: False for name in BROAD_SELECTION})
95
+ broad = False
96
  return {
97
  "version": policy["version"],
98
  "categories": [category for category in KNOWN_CATEGORIES if category in categories],
 
123
  parser.add_argument("--truncated", action="store_true", help="Fail open because the file list is incomplete")
124
  parser.add_argument("--error", action="store_true", help="Fail open because file retrieval failed")
125
  parser.add_argument("--github-output", help="Path to append GitHub Actions outputs")
126
+ parser.add_argument("--reuse-canonical-ci", action="store_true",
127
+ help="Suppress duplicate compiled jobs after verified promotion proof")
128
  args = parser.parse_args()
129
  try:
130
  files = load_json(args.files_json, "--files-json")
 
135
  tuple(policy["labels"]) != KNOWN_LABELS or
136
  set(policy["defaults"]) != {"baseline", *KNOWN_CATEGORIES}):
137
  raise ValueError("policy has an unsupported schema")
138
+ result = result_for(files, labels, args.truncated, args.error, policy,
139
+ args.reuse_canonical_ci)
140
  except (OSError, ValueError, KeyError, TypeError, json.JSONDecodeError):
141
  # The script itself must fail open if its API or policy interface changes.
142
  result = result_for(None, None, True, True, SAFE_POLICY)