Merge pull request #1523 from pikasTech/fix/1519-agentrun-scheduler-mismatch
fix: prioritize unfinished branch follower sources
This commit is contained in:
@@ -34,6 +34,7 @@ import { prioritizedTaskRunItems } from "./cicd-taskruns";
|
||||
import { runBranchFollowerTaskRunDrillDown } from "./cicd-taskrun-drilldown";
|
||||
import { runBranchFollowerJobDrillDown, runBranchFollowerRuntimeDrillDown } from "./cicd-job-runtime-drilldown";
|
||||
import { runBranchFollowerGate } from "./cicd-gates";
|
||||
import { buildCicdHelp } from "./cicd-help";
|
||||
import { attachReconcileTimeline, compactReconcileTimeline, finishReconcileStep, finishReconcileTimeline, startReconcileStep, startReconcileTimeline } from "./cicd-reconcile-timeline";
|
||||
import { orderFollowersForControllerCloseout, shouldYieldAfterAutomaticTrigger } from "./cicd-reconcile-scheduler";
|
||||
import type { AdapterSummary, BranchFollowerAction, BranchFollowerDebugStep, BranchFollowerGate, BranchFollowerPhase, BranchFollowerRegistry, ControllerSpec, FollowerSpec, FollowerState, K8sFollowerStateRead, K8sStateRead, NativeCloseoutWaitResult, NativeK8sJobResult, NativeStatusSpec, NativeWorkloadSpec, OutputMode, ParsedOptions, StageTiming, TriggerResult } from "./cicd-types";
|
||||
@@ -55,30 +56,7 @@ const SPEC_REF = "PJ2026-01060703";
|
||||
const SPEC_VERSION = "draft-2026-07-03-p0-branch-follower";
|
||||
|
||||
export function cicdHelp(): unknown {
|
||||
return {
|
||||
command: "cicd branch-follower plan|apply|status|run-once|debug-step|cleanup-state|events|logs|taskrun|job|runtime|gate",
|
||||
output: "text by default; use --json, --raw, or -o json|yaml for machine output",
|
||||
usage: [
|
||||
"bun scripts/cli.ts cicd branch-follower plan",
|
||||
"bun scripts/cli.ts cicd branch-follower apply --confirm --wait",
|
||||
"bun scripts/cli.ts cicd branch-follower status",
|
||||
"bun scripts/cli.ts cicd branch-follower status --live",
|
||||
"bun scripts/cli.ts cicd branch-follower run-once --all --dry-run",
|
||||
"bun scripts/cli.ts cicd branch-follower run-once --follower hwlab-jd01-v03 --confirm --wait",
|
||||
"bun scripts/cli.ts cicd branch-follower debug-step --follower web-probe-sentinel-master --step controller-source",
|
||||
"bun scripts/cli.ts cicd branch-follower debug-step --follower web-probe-sentinel-master --step state-read",
|
||||
"bun scripts/cli.ts cicd branch-follower debug-step --follower web-probe-sentinel-master --step state-write --confirm",
|
||||
"bun scripts/cli.ts cicd branch-follower cleanup-state --follower web-probe-sentinel-master --confirm",
|
||||
"bun scripts/cli.ts cicd branch-follower events --follower agentrun-jd01-v02",
|
||||
"bun scripts/cli.ts cicd branch-follower logs --follower web-probe-sentinel-master",
|
||||
"bun scripts/cli.ts cicd branch-follower taskrun --follower hwlab-jd01-v03 --taskrun runtime-ready --logs-tail 120 --json",
|
||||
"bun scripts/cli.ts cicd branch-follower job --follower agentrun-jd01-v02 --source-commit <sha> --job image-build --json",
|
||||
"bun scripts/cli.ts cicd branch-follower gate --follower agentrun-jd01-v02 --gate reuse-plan --source-commit <sha> --json",
|
||||
],
|
||||
config: DEFAULT_CONFIG_PATH,
|
||||
spec: `${SPEC_REF} ${SPEC_VERSION}`,
|
||||
description: "Deploy and inspect the YAML-first Kubernetes branch follower that follows HWLAB v0.3, AgentRun v0.2, and the selected web-probe sentinel master lane without using host worktrees as source authority.",
|
||||
};
|
||||
return buildCicdHelp(DEFAULT_CONFIG_PATH, `${SPEC_REF} ${SPEC_VERSION}`);
|
||||
}
|
||||
|
||||
export async function runCicdCommand(_config: UniDeskConfig | null, args: string[]): Promise<RenderedCliResult> {
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
// SPEC: PJ2026-01060703 CI/CD branch follower help text.
|
||||
// Responsibility: bounded CLI help payloads for the branch-follower entrypoint.
|
||||
|
||||
export function buildCicdHelp(configPath: string, spec: string): unknown {
|
||||
return {
|
||||
command: "cicd branch-follower plan|apply|status|run-once|debug-step|cleanup-state|events|logs|taskrun|job|runtime|gate",
|
||||
output: "text by default; use --json, --raw, or -o json|yaml for machine output",
|
||||
usage: [
|
||||
"bun scripts/cli.ts cicd branch-follower plan",
|
||||
"bun scripts/cli.ts cicd branch-follower apply --confirm --wait",
|
||||
"bun scripts/cli.ts cicd branch-follower status",
|
||||
"bun scripts/cli.ts cicd branch-follower status --live",
|
||||
"bun scripts/cli.ts cicd branch-follower run-once --all --dry-run",
|
||||
"bun scripts/cli.ts cicd branch-follower run-once --follower hwlab-jd01-v03 --confirm --wait",
|
||||
"bun scripts/cli.ts cicd branch-follower debug-step --follower web-probe-sentinel-master --step controller-source",
|
||||
"bun scripts/cli.ts cicd branch-follower debug-step --follower web-probe-sentinel-master --step state-read",
|
||||
"bun scripts/cli.ts cicd branch-follower debug-step --follower web-probe-sentinel-master --step state-write --confirm",
|
||||
"bun scripts/cli.ts cicd branch-follower cleanup-state --follower web-probe-sentinel-master --confirm",
|
||||
"bun scripts/cli.ts cicd branch-follower events --follower agentrun-jd01-v02",
|
||||
"bun scripts/cli.ts cicd branch-follower logs --follower web-probe-sentinel-master",
|
||||
"bun scripts/cli.ts cicd branch-follower taskrun --follower hwlab-jd01-v03 --taskrun runtime-ready --logs-tail 120 --json",
|
||||
"bun scripts/cli.ts cicd branch-follower job --follower agentrun-jd01-v02 --source-commit <sha> --job image-build --json",
|
||||
"bun scripts/cli.ts cicd branch-follower gate --follower agentrun-jd01-v02 --gate reuse-plan --source-commit <sha> --json",
|
||||
],
|
||||
config: configPath,
|
||||
spec,
|
||||
description: "Deploy and inspect the YAML-first Kubernetes branch follower that follows HWLAB v0.3, AgentRun v0.2, and the selected web-probe sentinel master lane without using host worktrees as source authority.",
|
||||
};
|
||||
}
|
||||
@@ -23,8 +23,30 @@ export function shouldYieldAfterAutomaticTrigger(options: ParsedOptions, state:
|
||||
function followerPriority(state: Record<string, unknown> | undefined): number {
|
||||
if (state === undefined) return 2;
|
||||
const phase = typeof state.phase === "string" ? state.phase : null;
|
||||
if (hasStoredSourceTargetMismatch(state)) return 0;
|
||||
if (hasUnfinishedObservedSource(state)) return 0;
|
||||
if (phase !== null && CLOSEOUT_PHASES.has(phase)) return 0;
|
||||
if (typeof state.inFlightJob === "string" && state.inFlightJob.trim() !== "") return 0;
|
||||
if (phase === "PendingTrigger" || phase === "Superseded") return 1;
|
||||
return 2;
|
||||
}
|
||||
|
||||
function hasStoredSourceTargetMismatch(state: Record<string, unknown>): boolean {
|
||||
const observedSha = nestedString(state, "source", "observedSha");
|
||||
const targetSha = nestedString(state, "target", "targetSha");
|
||||
return observedSha !== null && targetSha !== null && observedSha !== targetSha;
|
||||
}
|
||||
|
||||
function hasUnfinishedObservedSource(state: Record<string, unknown>): boolean {
|
||||
const observedSha = nestedString(state, "source", "observedSha");
|
||||
const lastSucceededSha = typeof state.lastSucceededSha === "string" ? state.lastSucceededSha : null;
|
||||
if (observedSha === null) return false;
|
||||
return lastSucceededSha === null || lastSucceededSha !== observedSha;
|
||||
}
|
||||
|
||||
function nestedString(source: Record<string, unknown>, parentKey: string, childKey: string): string | null {
|
||||
const parent = source[parentKey];
|
||||
if (parent === null || typeof parent !== "object" || Array.isArray(parent)) return null;
|
||||
const value = (parent as Record<string, unknown>)[childKey];
|
||||
return typeof value === "string" && value.trim() !== "" ? value : null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user