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. The two line-number columns refer to before and after.

ci/change-classifier.py CHANGED
@@ -50,7 +50,7 @@ def classify_path(path, policy):
50
50
  return "unknown"
51
51
 
52
52
 
53
- def result_for(files, labels, truncated, error, policy):
53
+ def result_for(files, labels, truncated, error, policy, reuse_canonical_ci=False):
54
54
  complete = (isinstance(files, list) and isinstance(labels, list) and
55
55
  all(isinstance(label, str) for label in labels) and
56
56
  not truncated and not error)
@@ -88,6 +88,11 @@ def result_for(files, labels, truncated, error, policy):
88
88
  selected[label.removeprefix("ci:")] = True
89
89
  if selected["nightly_full"]:
90
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
91
96
  return {
92
97
  "version": policy["version"],
93
98
  "categories": [category for category in KNOWN_CATEGORIES if category in categories],
@@ -118,6 +123,8 @@ def main():
118
123
  parser.add_argument("--truncated", action="store_true", help="Fail open because the file list is incomplete")
119
124
  parser.add_argument("--error", action="store_true", help="Fail open because file retrieval failed")
120
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")
121
128
  args = parser.parse_args()
122
129
  try:
123
130
  files = load_json(args.files_json, "--files-json")
@@ -128,7 +135,8 @@ def main():
128
135
  tuple(policy["labels"]) != KNOWN_LABELS or
129
136
  set(policy["defaults"]) != {"baseline", *KNOWN_CATEGORIES}):
130
137
  raise ValueError("policy has an unsupported schema")
131
- result = result_for(files, labels, args.truncated, args.error, policy)
138
+ result = result_for(files, labels, args.truncated, args.error, policy,
139
+ args.reuse_canonical_ci)
132
140
  except (OSError, ValueError, KeyError, TypeError, json.JSONDecodeError):
133
141
  # The script itself must fail open if its API or policy interface changes.
134
142
  result = result_for(None, None, True, True, SAFE_POLICY)