Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 37 additions & 4 deletions .github/workflows/sweep.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2292,6 +2292,8 @@ jobs:
cursor_path="results/comment-sync-cursors/${target_slug}.json"
apply_cursor_path="results/apply-cursors/${target_slug}.json"
next_cursor=""
apply_ready_count=""
cursor_advance_count=""
if [ "$sync_open_pr_batch" = "true" ]; then
sync_comments_only="true"
apply_kind="pull_request"
Expand Down Expand Up @@ -2333,6 +2335,9 @@ jobs:
health_processed_limit="$4"
health_cursor_path="${5:-}"
health_cursor_required="${6:-false}"
health_candidate_count="${7:-}"
health_scheduled_interval_minutes="${8:-}"
health_cursor_advance_count="${9:-}"
health_args=(
--target-repo "$TARGET_REPO"
--report "$report_path"
Expand All @@ -2346,6 +2351,15 @@ jobs:
if [ "$health_cursor_required" = "true" ]; then
health_args+=(--cursor-required true)
fi
if [ -n "$health_candidate_count" ]; then
health_args+=(--candidate-count "$health_candidate_count")
fi
if [ -n "$health_scheduled_interval_minutes" ]; then
health_args+=(--scheduled-interval-minutes "$health_scheduled_interval_minutes")
fi
if [ -n "$health_cursor_advance_count" ]; then
health_args+=(--cursor-advance-count "$health_cursor_advance_count")
fi
pnpm run --silent workflow -- summarize-apply-report "${health_args[@]}" > "$output_path"
}
reconcile_args=(--target-repo "$TARGET_REPO" --skip-closed-at)
Expand Down Expand Up @@ -2406,10 +2420,17 @@ jobs:
if [ -n "$item_numbers" ]; then
auto_selected_apply_batch=true
proposed_count="$(pnpm run --silent workflow -- count-csv --items "$item_numbers")"
apply_ready_count="$(pnpm run --silent workflow -- proposed-item-count \
--target-repo "$TARGET_REPO" \
--apply-kind "$apply_kind" \
--apply-close-reasons "$apply_close_reasons" \
--stale-min-age-days "$stale_min_age_days" \
--min-age-days "$min_age_days" \
--min-age-minutes "$min_age_minutes")"
if [ "$proposed_count" -lt "$limit" ]; then
limit="$proposed_count"
fi
echo "Auto-selected $proposed_count proposed close candidate(s) from apply cursor window: $item_numbers"
echo "Auto-selected $proposed_count proposed close candidate(s) from apply cursor window: $item_numbers; apply-ready count: ${apply_ready_count:-unknown}"
fi
fi
item_numbers_arg=()
Expand Down Expand Up @@ -2491,7 +2512,7 @@ jobs:
comment_sync_health_cursor_required="true"
comment_sync_health_processed_limit="$sync_batch_size"
fi
write_apply_health ".artifacts/apply-reports/apply-report-$checkpoint.json" ".artifacts/apply-health-$checkpoint.json" "comment_sync" "$comment_sync_health_processed_limit" "$comment_sync_health_cursor_path" "$comment_sync_health_cursor_required"
write_apply_health ".artifacts/apply-reports/apply-report-$checkpoint.json" ".artifacts/apply-health-$checkpoint.json" "comment_sync" "$comment_sync_health_processed_limit" "$comment_sync_health_cursor_path" "$comment_sync_health_cursor_required" "" "" ""
pnpm run status -- \
--target-repo "$TARGET_REPO" \
--state "Apply comments synced" \
Expand Down Expand Up @@ -2541,14 +2562,17 @@ jobs:
--report ".artifacts/apply-reports/apply-report-$checkpoint.json" \
--target-repo "$TARGET_REPO" \
--item-numbers "$item_numbers"
cursor_advance_count="$(pnpm run --silent workflow -- apply-cursor-advance-count \
--report ".artifacts/apply-reports/apply-report-$checkpoint.json" \
--item-numbers "$item_numbers")"
apply_publish_paths+=(results/apply-cursors)
fi
publish_changes "chore: apply sweep decisions checkpoint $checkpoint" "${apply_publish_paths[@]}"
close_health_cursor_path=""
if [ "$auto_selected_apply_batch" = "true" ]; then
close_health_cursor_path="$apply_cursor_path"
fi
write_apply_health ".artifacts/apply-reports/apply-report-$checkpoint.json" ".artifacts/apply-health-$checkpoint.json" "close" "$close_processed_limit" "$close_health_cursor_path" "$auto_selected_apply_batch"
write_apply_health ".artifacts/apply-reports/apply-report-$checkpoint.json" ".artifacts/apply-health-$checkpoint.json" "close" "$close_processed_limit" "$close_health_cursor_path" "$auto_selected_apply_batch" "$apply_ready_count" "15" "$cursor_advance_count"
pnpm run status -- \
--target-repo "$TARGET_REPO" \
--state "Apply in progress" \
Expand Down Expand Up @@ -2583,20 +2607,29 @@ jobs:
final_health_processed_limit="$close_processed_limit"
final_health_cursor_path=""
final_health_cursor_required="$auto_selected_apply_batch"
final_health_candidate_count=""
final_health_scheduled_interval_minutes=""
final_health_cursor_advance_count=""
if [ "$auto_selected_apply_batch" = "true" ]; then
final_health_cursor_path="$apply_cursor_path"
final_health_candidate_count="$apply_ready_count"
final_health_scheduled_interval_minutes="15"
final_health_cursor_advance_count="$cursor_advance_count"
fi
if [ "$sync_comments_only" = "true" ]; then
final_health_mode="comment_sync"
final_health_processed_limit="$comment_sync_processed_limit"
final_health_cursor_required="false"
final_health_candidate_count=""
final_health_scheduled_interval_minutes=""
final_health_cursor_advance_count=""
if [ "$sync_open_pr_batch" = "true" ]; then
final_health_cursor_path="$cursor_path"
final_health_cursor_required="true"
final_health_processed_limit="$sync_batch_size"
fi
fi
write_apply_health "apply-report.json" ".artifacts/apply-health-final.json" "$final_health_mode" "$final_health_processed_limit" "$final_health_cursor_path" "$final_health_cursor_required"
write_apply_health "apply-report.json" ".artifacts/apply-health-final.json" "$final_health_mode" "$final_health_processed_limit" "$final_health_cursor_path" "$final_health_cursor_required" "$final_health_candidate_count" "$final_health_scheduled_interval_minutes" "$final_health_cursor_advance_count"
pnpm run status -- \
--target-repo "$TARGET_REPO" \
--state "Apply finished" \
Expand Down
44 changes: 43 additions & 1 deletion dashboard/worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3584,6 +3584,7 @@ async function readApplyHealthMarker(env, targetRepo) {
lanes: applyHealthLanes(health.lanes),
next_actions: nextActions,
next_action_buckets: numericRecord(health.next_action_buckets),
cycle: applyHealthCycle(health.cycle),
attention_reasons: Array.isArray(health.attention_reasons)
? health.attention_reasons
.map((reason) => String(reason))
Expand Down Expand Up @@ -3620,6 +3621,7 @@ async function readApplyHealthMarker(env, targetRepo) {
lanes: emptyApplyHealthLanes(),
next_actions: [],
next_action_buckets: {},
cycle: emptyApplyHealthCycle(),
attention_reasons: [],
cursor: null,
};
Expand All @@ -3638,6 +3640,7 @@ function emptyApplyHealthStatus(targetRepos) {
lanes: emptyApplyHealthLanes(),
next_actions: [],
next_action_buckets: {},
cycle: emptyApplyHealthCycle(),
attention_reasons: [],
cursor: null,
})),
Expand Down Expand Up @@ -3699,6 +3702,31 @@ function applyHealthNextActions(value) {
.filter(Boolean)
.slice(0, 12);
}

function applyHealthCycle(value) {
const source = objectValue(value);
return {
basis: nullableString(source.basis),
apply_ready_count: optionalNumber(source.apply_ready_count),
window_size: optionalNumber(source.window_size),
estimated_full_cycle_windows: optionalNumber(source.estimated_full_cycle_windows),
estimated_full_cycle_minutes: optionalNumber(source.estimated_full_cycle_minutes),
scheduled_interval_minutes: optionalNumber(source.scheduled_interval_minutes),
label: nullableString(source.label),
};
}

function emptyApplyHealthCycle() {
return {
basis: null,
apply_ready_count: null,
window_size: null,
estimated_full_cycle_windows: null,
estimated_full_cycle_minutes: null,
scheduled_interval_minutes: null,
label: null,
};
}
function latestIso(values) {
const timestamps = values
.map((value) => Date.parse(value || ""))
Expand Down Expand Up @@ -4763,6 +4791,11 @@ function numberOrNull(value) {
return Number.isFinite(number) ? number : null;
}

function optionalNumber(value) {
if (value === null || value === undefined || value === "") return null;
return numberOrNull(value);
}

function numberFrom(value, fallback) {
const number = Number(value);
return Number.isFinite(number) ? number : fallback;
Expand Down Expand Up @@ -6890,14 +6923,23 @@ function renderApplyHealth(data) {
const syncProcessed = Number.isFinite(item.lanes?.comment_sync?.processed) ? fmt.format(item.lanes.comment_sync.processed) : processed;
const closureSynced = Number.isFinite(item.lanes?.closure?.comment_synced) ? fmt.format(item.lanes.closure.comment_synced) : "0";
const syncLaneSynced = Number.isFinite(item.lanes?.comment_sync?.comment_synced) ? fmt.format(item.lanes.comment_sync.comment_synced) : "0";
const cycle = applyHealthCyclePill(item.cycle);
return '<div class="apply-health-alert" role="status" title="' + esc(topInfo.summary + " Next: " + topInfo.action) + '">' +
'<div class="apply-health-heading"><strong>Pruning sweep ' + esc(applyHealthStatusLabel(item.status)) + " - " + esc(item.target_repo || "target repo") + '</strong><span class="pill" title="' + esc("Latest " + applyHealthModeLabel(item.mode) + " status from the sweep-status marker.") + '">' + esc(applyHealthModeLabel(item.mode)) + '</span></div>' +
'<p>' + esc(applyHealthOperatorSummary(item, topInfo)) + '</p>' +
'<p class="apply-health-next"><strong>Next check:</strong> ' + esc(topInfo.action) + '</p>' +
applyHealthActionHtml(action) +
'<div class="apply-health-meta"><span class="pill" title="Records checked in this pruning window.">' + esc(processed) + ' processed</span><span class="pill" title="' + esc("Closure lane: " + closureProcessed + " records processed; " + closed + " closed.") + '">' + esc(closed) + ' closed</span><span class="pill" title="' + esc("Durable review comments refreshed across lanes: " + synced + ". Closure lane refreshed " + closureSynced + "; comment-sync lane refreshed " + syncLaneSynced + " from " + syncProcessed + " records.") + '">' + esc(synced) + ' comments synced</span>' + cursorPill + reasons + buckets + linkClass(item.run_url, "workflow run", "pill run-link") + '</div></div>';
'<div class="apply-health-meta"><span class="pill" title="Records checked in this pruning window.">' + esc(processed) + ' processed</span><span class="pill" title="' + esc("Closure lane: " + closureProcessed + " records processed; " + closed + " closed.") + '">' + esc(closed) + ' closed</span><span class="pill" title="' + esc("Durable review comments refreshed across lanes: " + synced + ". Closure lane refreshed " + closureSynced + "; comment-sync lane refreshed " + syncLaneSynced + " from " + syncProcessed + " records.") + '">' + esc(synced) + ' comments synced</span>' + cycle + cursorPill + reasons + buckets + linkClass(item.run_url, "workflow run", "pill run-link") + '</div></div>';
}).join("");
}
function applyHealthCyclePill(cycle) {
if (!cycle || cycle.basis !== "scheduled_close_cursor") return "";
const windows = Number(cycle.estimated_full_cycle_windows);
const label = Number.isFinite(windows)
? "revisit ~" + fmt.format(windows) + " window" + (windows === 1 ? "" : "s")
: "revisit estimate";
return '<span class="pill" title="' + esc(cycle.label || "Estimated time to revisit the current apply-ready close queue.") + '">' + esc(label) + '</span>';
}
function applyHealthNeedsAttention(status) {
return ["attention", "blocked", "degraded", "failed", "needs_attention", "warning"].includes(String(status || "").toLowerCase());
}
Expand Down
4 changes: 4 additions & 0 deletions docs/live-dashboard.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,10 @@ is absent or a cache event lands in another Cloudflare colo.
- skip next-action buckets in apply health JSON so stale reviews, missing close
proof, protected labels, stable skips, invalid reports, and open closing PRs
are discoverable without reading individual item records
- scheduled close-cycle telemetry in apply-health JSON, including current
apply-ready candidate count and an estimated number of cursor windows to
revisit the close queue; scheduled cadence time is explanatory only because
successful windows can dispatch immediate continuations

The Worker fetches job details only for the bounded active-run set, limits that
GitHub fanout to 12 concurrent requests, and caches each run's jobs for 60
Expand Down
Loading