fix(ci): verify performance report after push timeout (#103237)

This commit is contained in:
Peter Steinberger
2026-07-10 02:50:36 +01:00
committed by GitHub
parent 2c622e19de
commit 25eaa53a8a
2 changed files with 76 additions and 45 deletions
+41 -31
View File
@@ -1045,6 +1045,22 @@ jobs:
push_report() {
GIT_TERMINAL_PROMPT=0 GIT_CONFIG_COUNT=2 GIT_CONFIG_KEY_0=core.hooksPath GIT_CONFIG_VALUE_0=/dev/null GIT_CONFIG_KEY_1=http.https://github.com/.extraheader GIT_CONFIG_VALUE_1="AUTHORIZATION: basic ${auth_header}" timeout 120s git -C "$reports_root" push origin HEAD:main
}
write_publish_success() {
{
echo "### Clawgrit report published"
echo
echo "- Published report: ${REPORT_URL}"
} >> "$GITHUB_STEP_SUMMARY"
}
write_publish_failure() {
{
echo "### Clawgrit report publish failed"
echo
echo "Kova artifacts were uploaded, but publishing the clawgrit report failed after $1 attempts."
echo "Check the ClawSweeper GitHub App installation and contents permission for openclaw/clawgrit-reports."
} >> "$GITHUB_STEP_SUMMARY"
echo "::${annotation}::Kova artifacts uploaded, but clawgrit report publish failed after $1 attempts."
}
if [[ "$(git_local config --local --get core.hooksPath)" != "/dev/null" || "$(git_local remote get-url origin)" != "https://github.com/openclaw/clawgrit-reports.git" ]]; then
echo "::${annotation}::Prepared reports checkout failed integrity validation."
@@ -1055,42 +1071,36 @@ jobs:
for attempt in 1 2 3 4 5; do
if push_report; then
{
echo "### Clawgrit report published"
echo
echo "- Published report: ${REPORT_URL}"
} >> "$GITHUB_STEP_SUMMARY"
write_publish_success
exit 0
fi
if [[ "$attempt" == "5" ]]; then
{
echo "### Clawgrit report publish failed"
echo
echo "Kova artifacts were uploaded, but publishing the clawgrit report failed after ${attempt} attempts."
echo "Check the ClawSweeper GitHub App installation and contents permission for openclaw/clawgrit-reports."
} >> "$GITHUB_STEP_SUMMARY"
echo "::${annotation}::Kova artifacts uploaded, but clawgrit report publish failed after ${attempt} attempts."
exit 1
fi
sleep $((attempt * 2))
if ! timeout 120s git -C "$reports_root" -c core.hooksPath=/dev/null fetch --depth=1 origin main; then
echo "::warning::Unable to refresh openclaw/clawgrit-reports after publish attempt ${attempt}; retrying."
continue
fi
if git_local cat-file -e "FETCH_HEAD:${DEST_REL}/report.json" 2>/dev/null; then
# A timed-out push may have succeeded. Preserve any newer latest pointer.
git_local checkout --detach FETCH_HEAD
continue
if [[ "$attempt" != "5" ]]; then
echo "::warning::Unable to refresh openclaw/clawgrit-reports after publish attempt ${attempt}; retrying."
continue
fi
else
if git_local cat-file -e "FETCH_HEAD:${DEST_REL}/report.json" 2>/dev/null; then
# A timed-out push may have succeeded; verify its unique report before failing.
write_publish_success
exit 0
fi
if [[ "$attempt" != "5" ]]; then
git_local checkout --detach FETCH_HEAD
# The run path is unique; only the shared latest pointer can conflict.
# Replaying with the current commit wins that pointer deterministically.
if ! git_local cherry-pick -X theirs "$report_commit"; then
git_local cherry-pick --abort || true
echo "::${annotation}::Unable to replay the clawgrit report after a concurrent publish."
exit 1
fi
report_commit="$(git_local rev-parse HEAD)"
continue
fi
fi
git_local checkout --detach FETCH_HEAD
# The run path is unique; only the shared latest pointer can conflict.
# Replaying with the current commit wins that pointer deterministically.
if ! git_local cherry-pick -X theirs "$report_commit"; then
git_local cherry-pick --abort || true
echo "::${annotation}::Unable to replay the clawgrit report after a concurrent publish."
exit 1
fi
report_commit="$(git_local rev-parse HEAD)"
write_publish_failure "$attempt"
exit 1
done
@@ -320,7 +320,7 @@ printf '%s\\n' \
}
});
it("advertises a clawgrit URL only after an actual successful push", () => {
it("advertises a clawgrit URL only after a direct or remotely verified push", () => {
const publish = findStep("Publish to clawgrit reports", "publish");
const root = mkdtempSync(join(realpathSync(tmpdir()), "openclaw-publish-shell-"));
const bin = join(root, "bin");
@@ -336,7 +336,8 @@ case "$*" in
*"config --local --get core.hooksPath"*) echo /dev/null ;;
*"remote get-url origin"*) echo https://github.com/openclaw/clawgrit-reports.git ;;
*" push origin HEAD:main"*) printf push > "$STUB_PUSH_MARKER"; exit "\${STUB_PUSH_STATUS:-0}" ;;
*" fetch --depth=1 origin main"*) exit 1 ;;
*" fetch --depth=1 origin main"*) exit "\${STUB_FETCH_STATUS:-1}" ;;
*"cat-file -e FETCH_HEAD:"*) exit "\${STUB_REMOTE_REPORT_STATUS:-1}" ;;
*) exit 0 ;;
esac
`,
@@ -347,15 +348,25 @@ esac
chmodSync(join(bin, "sleep"), 0o755);
chmodSync(join(bin, "timeout"), 0o755);
const execute = (pushStatus: string, appToken: string | null = "test-app-token") => {
const summary = join(
root,
`summary-${pushStatus}-${appToken === null ? "missing" : "token"}.md`,
);
const pushMarker = join(
root,
`push-${pushStatus}-${appToken === null ? "missing" : "token"}.marker`,
);
const execute = ({
pushStatus,
appToken = "test-app-token",
fetchSucceeds = false,
remoteReportPresent = false,
}: {
pushStatus: string;
appToken?: string | null;
fetchSucceeds?: boolean;
remoteReportPresent?: boolean;
}) => {
const scenario = [
pushStatus,
appToken === null ? "missing" : "token",
fetchSucceeds ? "fetch" : "no-fetch",
remoteReportPresent ? "remote" : "absent",
].join("-");
const summary = join(root, `summary-${scenario}.md`);
const pushMarker = join(root, `push-${scenario}.marker`);
const result = spawnSync("bash", ["-c", publish.run ?? ""], {
encoding: "utf8",
env: {
@@ -369,8 +380,10 @@ esac
REPORT_URL: reportUrl,
REPORTS_ROOT: reportsRoot,
RUNNER_TEMP: root,
STUB_FETCH_STATUS: fetchSucceeds ? "0" : "1",
STUB_PUSH_MARKER: pushMarker,
STUB_PUSH_STATUS: pushStatus,
STUB_REMOTE_REPORT_STATUS: remoteReportPresent ? "0" : "1",
},
});
return {
@@ -381,17 +394,25 @@ esac
};
try {
const success = execute("0");
const success = execute({ pushStatus: "0" });
expect(success.result.status).toBe(0);
expect(success.summary).toContain(`- Published report: ${reportUrl}`);
const failure = execute("1");
const ambiguousSuccess = execute({
pushStatus: "1",
fetchSucceeds: true,
remoteReportPresent: true,
});
expect(ambiguousSuccess.result.status).toBe(0);
expect(ambiguousSuccess.summary).toContain(`- Published report: ${reportUrl}`);
const failure = execute({ pushStatus: "1" });
expect(failure.result.status).toBe(1);
expect(failure.summary).toContain("Clawgrit report publish failed");
expect(failure.summary).toContain("ClawSweeper GitHub App installation");
expect(failure.summary).not.toContain("Published report:");
const missing = execute("0", null);
const missing = execute({ pushStatus: "0", appToken: null });
expect(missing.result.status).toBe(1);
expect(missing.result.stdout).toContain("ClawSweeper GitHub App token is unavailable");
expect(missing.summary).toContain("Clawgrit report publish unavailable");