|
76 | 76 | "vars.RELEASE_RECOVERY_SHA == inputs.release-sha" |
77 | 77 | ) |
78 | 78 | SELECT_RELEASE_CONDITION = ( |
79 | | - "always() && github.run_attempt == 1 && " |
| 79 | + "always() && !cancelled() && github.run_attempt == 1 && " |
80 | 80 | "( ( github.event_name == 'push' && needs.release-please.result == 'success' && " |
81 | 81 | "needs.release-please.outputs.release-created == 'true' && " |
82 | 82 | "needs.release-please.outputs.release-verified == 'true' ) || " |
83 | 83 | "( github.event_name == 'workflow_dispatch' && " |
84 | 84 | "needs.verify-recovery.result == 'success' ) )" |
85 | 85 | ) |
| 86 | +BUILD_JOB_CONDITION = ( |
| 87 | + "always() && !cancelled() && github.run_attempt == 1 && " |
| 88 | + "needs.select-release.result == 'success'" |
| 89 | +) |
| 90 | +RELEASE_LIVE_JOB_CONDITION = ( |
| 91 | + "always() && !cancelled() && github.run_attempt == 1 && needs.build.result == 'success'" |
| 92 | +) |
| 93 | +PUBLISH_JOB_CONDITION = ( |
| 94 | + "always() && !cancelled() && github.run_attempt == 1 && " |
| 95 | + "needs.build.result == 'success' && " |
| 96 | + "needs.release-live-smoke.result == 'success'" |
| 97 | +) |
| 98 | +REGISTRY_JOB_CONDITION = ( |
| 99 | + "always() && !cancelled() && github.run_attempt == 1 && " |
| 100 | + "needs.build.result == 'success' && needs.publish.result == 'success'" |
| 101 | +) |
86 | 102 | SELECT_RELEASE_COMMAND = """\ |
87 | 103 | case "$EVENT_NAME" in |
88 | 104 | push) |
@@ -1066,7 +1082,10 @@ def check_publish_workflow(text: str, live_smoke_text: str) -> None: |
1066 | 1082 | "steps.release.outputs.release_created == 'true'", |
1067 | 1083 | RECOVERY_JOB_CONDITION, |
1068 | 1084 | SELECT_RELEASE_CONDITION, |
1069 | | - *(["github.run_attempt == 1"] * 4), |
| 1085 | + BUILD_JOB_CONDITION, |
| 1086 | + RELEASE_LIVE_JOB_CONDITION, |
| 1087 | + PUBLISH_JOB_CONDITION, |
| 1088 | + REGISTRY_JOB_CONDITION, |
1070 | 1089 | ] |
1071 | 1090 | if sorted(conditions) != sorted(expected_conditions): |
1072 | 1091 | raise CheckError( |
@@ -1224,15 +1243,25 @@ def check_publish_workflow(text: str, live_smoke_text: str) -> None: |
1224 | 1243 | "steps", |
1225 | 1244 | }, |
1226 | 1245 | } |
| 1246 | + expected_release_conditions = { |
| 1247 | + "build": BUILD_JOB_CONDITION, |
| 1248 | + "release-live-smoke": RELEASE_LIVE_JOB_CONDITION, |
| 1249 | + "publish": PUBLISH_JOB_CONDITION, |
| 1250 | + "verify-registry": REGISTRY_JOB_CONDITION, |
| 1251 | + } |
1227 | 1252 | for name, job in ( |
1228 | 1253 | ("build", build), |
1229 | 1254 | ("release-live-smoke", release_live), |
1230 | 1255 | ("publish", publish), |
1231 | 1256 | ("verify-registry", registry), |
1232 | 1257 | ): |
1233 | 1258 | _require_exact_keys(job, expected_release_job_keys[name], f"release {name} job") |
1234 | | - if job["if"] != "github.run_attempt == 1": |
1235 | | - raise CheckError(f"release {name} job must run only on the first workflow attempt") |
| 1259 | + condition = " ".join(_scalar(job["if"], f"release {name} condition").split()) |
| 1260 | + if condition != expected_release_conditions[name]: |
| 1261 | + raise CheckError( |
| 1262 | + f"release {name} job must evaluate skipped ancestry, reject cancellation " |
| 1263 | + "and reruns, and require every direct dependency to succeed" |
| 1264 | + ) |
1236 | 1265 | _require_step_working_directories( |
1237 | 1266 | job, |
1238 | 1267 | ({"Recheck immutable artifact digests": "release-bundle"} if name == "publish" else {}), |
|
0 commit comments