fix(release): make beta performance advisory

This commit is contained in:
Peter Steinberger
2026-07-16 23:55:04 +01:00
parent 2cd236385b
commit 7662b4bb8c
2 changed files with 66 additions and 10 deletions
+35 -10
View File
@@ -496,10 +496,13 @@ jobs:
fail_fast_failed_jobs() {
local failed_jobs_json
failed_jobs_json="$(
if ! failed_jobs_json="$(
fetch_child_jobs |
jq -s '[.[] | select(.status == "completed" and .conclusion != "success" and .conclusion != "skipped")]'
)"
)"; then
echo "::warning::Could not list ${workflow} child jobs; continuing with authoritative workflow conclusion."
return 0
fi
if jq -e 'length > 0' <<< "$failed_jobs_json" >/dev/null; then
echo "::error::${workflow} has failed child jobs before the workflow completed; cancelling the remaining matrix."
jq '.[] | {name, conclusion, url: .html_url}' <<< "$failed_jobs_json"
@@ -686,10 +689,13 @@ jobs:
fail_fast_failed_jobs() {
local failed_jobs_json
failed_jobs_json="$(
if ! failed_jobs_json="$(
fetch_child_jobs |
jq -s '[.[] | select(.status == "completed" and .conclusion != "success" and .conclusion != "skipped")]'
)"
)"; then
echo "::warning::Could not list ${workflow} child jobs; continuing with authoritative workflow conclusion."
return 0
fi
if jq -e 'length > 0' <<< "$failed_jobs_json" >/dev/null; then
echo "::error::${workflow} has failed child jobs before the workflow completed; cancelling the remaining matrix."
jq '.[] | {name, conclusion, url: .html_url}' <<< "$failed_jobs_json"
@@ -923,10 +929,13 @@ jobs:
if [[ "$workflow" == "openclaw-release-checks.yml" && "$CHILD_WORKFLOW_REF" =~ ^tideclaw/alpha/[0-9]{4}-[0-9]{2}-[0-9]{2}-[0-9]{4}Z$ ]]; then
return 0
fi
failed_jobs_json="$(
if ! failed_jobs_json="$(
fetch_child_jobs |
jq -s '[.[] | select(.status == "completed" and .conclusion != "success" and .conclusion != "skipped")]'
)"
)"; then
echo "::warning::Could not list ${workflow} child jobs; continuing with authoritative workflow conclusion."
return 0
fi
if [[ "$workflow" == "openclaw-release-checks.yml" ]]; then
# These jobs are continue-on-error in the child workflow. Let its
# status-artifact verifier decide whether their evidence is usable.
@@ -1279,6 +1288,7 @@ jobs:
id: dispatch
env:
GH_TOKEN: ${{ github.token }}
RELEASE_PROFILE: ${{ inputs.release_profile }}
TARGET_SHA: ${{ needs.resolve_target.outputs.sha }}
CHILD_WORKFLOW_REF: ${{ github.ref_name }}
PARENT_WORKFLOW_SHA: ${{ github.sha }}
@@ -1326,7 +1336,11 @@ jobs:
echo "- Deep profile: \`false\`"
echo "- Live OpenAI candidate: \`false\`"
echo "- Report publication: disabled (artifacts only)"
echo "- Release impact: blocking"
if [[ "$RELEASE_PROFILE" == "beta" ]]; then
echo "- Release impact: advisory"
else
echo "- Release impact: blocking"
fi
} >> "$GITHUB_STEP_SUMMARY"
dispatch_id="full-release-validation-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}"
@@ -1423,6 +1437,10 @@ jobs:
echo "url=${url}" >> "$GITHUB_OUTPUT"
echo "conclusion=${conclusion}" >> "$GITHUB_OUTPUT"
if [[ "$conclusion" != "success" ]]; then
if [[ "$RELEASE_PROFILE" == "beta" ]]; then
echo "::warning::OpenClaw Performance ended with ${conclusion}; advisory for beta: ${url}"
exit 0
fi
echo "::error::OpenClaw Performance ended with ${conclusion}: ${url}"
gh_with_retry run view "$run_id" --json jobs --jq '.jobs[] | select(.conclusion != "success" and .conclusion != "skipped") | {name, conclusion, url}' || true
exit 1
@@ -1458,6 +1476,7 @@ jobs:
RELEASE_CHECKS_RESULT: ${{ needs.release_checks.result }}
NPM_TELEGRAM_RESULT: ${{ needs.npm_telegram.result }}
PERFORMANCE_RESULT: ${{ needs.performance.result }}
RELEASE_PROFILE: ${{ inputs.release_profile }}
DOCKER_RUNTIME_ASSETS_PREFLIGHT_RESULT: ${{ needs.docker_runtime_assets_preflight.result }}
EVIDENCE_REUSE: ${{ needs.evidence_reuse.outputs.reuse }}
EVIDENCE_ROOT_RUN_ID: ${{ needs.evidence_reuse.outputs.evidence_root_run_id }}
@@ -1565,6 +1584,10 @@ jobs:
fi
if [[ "$status" != "completed" || "$conclusion" != "success" ]]; then
if [[ "$advisory_ok" == "1" && "$label" == "product_performance" && "$status" == "completed" ]]; then
echo "::warning::${label} ended with ${conclusion}; advisory for beta: ${url}"
return 0
fi
if [[ "$advisory_ok" == "1" && "$label" == "release_checks" ]]; then
if release_checks_advisory_only "$run_json"; then
echo "::warning::${label} child run ended with ${status}/${conclusion}, but Verify release checks accepted Tideclaw alpha advisory lanes: ${url}"
@@ -1822,7 +1845,9 @@ jobs:
if [[ "$PERFORMANCE_RESULT" == "skipped" && -z "${PERFORMANCE_RUN_ID// }" ]]; then
check_child "product_performance" "" "$performance_required" || failed=1
else
check_child "product_performance" "$PERFORMANCE_RUN_ID" "$performance_required" || failed=1
performance_advisory=0
[[ "$RELEASE_PROFILE" == "beta" ]] && performance_advisory=1
check_child "product_performance" "$PERFORMANCE_RUN_ID" "$performance_required" "$performance_advisory" || failed=1
fi
summarize_child_timing "normal_ci" "$NORMAL_CI_RUN_ID"
@@ -2052,7 +2077,7 @@ jobs:
},
controls: {
stableSoakRequired: ($releaseProfile == "stable" or $releaseProfile == "full"),
performanceBlocking: true,
performanceBlocking: ($releaseProfile != "beta"),
performanceReportPublication: "artifact-only"
},
childRuns: {
@@ -2063,7 +2088,7 @@ jobs:
productPerformance: {
runId: $performanceRunId,
conclusion: $performanceConclusion,
blocking: true
blocking: ($releaseProfile != "beta")
}
}
}' > "${manifest_dir}/full-release-validation-manifest.json"
@@ -1245,6 +1245,37 @@ describe("package acceptance workflow", () => {
);
});
it("keeps performance evidence advisory for beta releases", () => {
const workflow = readFileSync(FULL_RELEASE_VALIDATION_WORKFLOW, "utf8");
const performanceStep = workflowStep(
workflowJob(FULL_RELEASE_VALIDATION_WORKFLOW, "performance"),
"Dispatch and monitor OpenClaw Performance",
);
const summaryStep = workflowStep(
workflowJob(FULL_RELEASE_VALIDATION_WORKFLOW, "summary"),
"Verify child workflow results",
);
expect(performanceStep.env?.RELEASE_PROFILE).toBe("${{ inputs.release_profile }}");
expectTextToIncludeAll(performanceStep.run, [
'if [[ "$RELEASE_PROFILE" == "beta" ]]',
"Release impact: advisory",
"advisory for beta",
]);
expect(summaryStep.env?.RELEASE_PROFILE).toBe("${{ inputs.release_profile }}");
expectTextToIncludeAll(summaryStep.run, [
'[[ "$RELEASE_PROFILE" == "beta" ]] && performance_advisory=1',
'check_child "product_performance" "$PERFORMANCE_RUN_ID" "$performance_required" "$performance_advisory"',
]);
expect(workflow).toContain('performanceBlocking: ($releaseProfile != "beta")');
expect(workflow).toContain('blocking: ($releaseProfile != "beta")');
});
it("keeps child-job fail-fast polling best-effort", () => {
const workflow = readFileSync(FULL_RELEASE_VALIDATION_WORKFLOW, "utf8");
expect(workflow.match(/continuing with authoritative workflow conclusion\./gu)).toHaveLength(3);
});
it("adopts exact full-release child runs without retrying ambiguous dispatch posts", () => {
const childDispatches = [
["normal_ci", "Dispatch and monitor CI"],