mirror of
https://github.com/openclaw/openclaw.git
synced 2026-10-03 17:53:39 +00:00
* feat(release): accept exact-job recorded flakes in release validation A release lead can classify one failed Normal CI job of a Full Release Validation run as a flake through the trusted classification workflow. The receipt binds the exact job id and attempt, CI child run, FRV parent run and attempt, and Release SHA, and carries a tracking issue or PR plus a reason. Release Decision, the manifest, the publisher's live re-derivation, the step summary, and the GitHub release notes tail treat it as a visible advisory. Required classes and every other child stay blocking. * docs(release): fold recorded flakes into the shared release boundaries * fix(release): scope flake receipt discovery to the CI child run * fix(release): require main lineage for flake receipt producers * test(release): copy the flake classification module into tooling fixtures * fix(release): keep advisory-only release notes verifiable
191 lines
6.7 KiB
TypeScript
191 lines
6.7 KiB
TypeScript
export const MAX_RELEASE_ARTIFACT_BYTES: number;
|
|
export const WINDOWS_NODE_CI_ADVISORY: {
|
|
readonly id: "windows-node-ci";
|
|
readonly child: "normalCi";
|
|
readonly jobNamePattern: RegExp;
|
|
readonly aggregateJob: "checks-windows";
|
|
};
|
|
interface ReleaseAdvisoryJobBase {
|
|
child: "normalCi";
|
|
job: string;
|
|
conclusion: string;
|
|
runId: string;
|
|
url: string;
|
|
}
|
|
export type ReleaseAdvisoryJob = ReleaseAdvisoryJobBase &
|
|
(
|
|
| { class: "windows-node-ci" }
|
|
| {
|
|
class: "recorded-flake";
|
|
jobId: string;
|
|
trackingUrl: string;
|
|
reason: string;
|
|
receiptRunId: string;
|
|
}
|
|
);
|
|
export function releaseChildClassificationEvidence(child: ReleaseRecord): ReleaseRecord;
|
|
export function releaseAdvisoryJobs(children: ReleaseRecord[]): ReleaseAdvisoryJob[];
|
|
export function validateReleaseManifestAdvisoryJobs(manifest: unknown): ReleaseAdvisoryJob[];
|
|
export const SPLIT_CHANGELOG_EVIDENCE_REUSE_POLICY: "split-changelog-release-v1";
|
|
export function isSplitChangelogEvidenceDelta(paths: unknown, version: unknown): boolean;
|
|
export function classifyReleaseChangelogEvidenceComparison(
|
|
comparison: unknown,
|
|
identity: { baseSha: string; version?: unknown },
|
|
): { changedPaths: string[]; policy: string };
|
|
export function serializeReleaseArtifact(payload: unknown): string;
|
|
export function buildReleaseValidationManifest(input: {
|
|
plan: ReleaseRecord;
|
|
drain?: ReleaseRecord;
|
|
context: ReleaseRecord;
|
|
}): ReleaseRecord;
|
|
export function assertReleasePublicationKnownBudget(
|
|
plan: ReleaseRecord,
|
|
context: ReleaseRecord,
|
|
): void;
|
|
export function normalizeReleaseCoveragePolicy(
|
|
input: ReleaseRecord,
|
|
): "npm-beta-v1" | "npm-stable-v1" | undefined;
|
|
export function validateReleaseCoveragePolicyBinding(
|
|
plan: ReleaseRecord | undefined,
|
|
validationInputs?: ReleaseRecord,
|
|
): void;
|
|
export function normalizeReleaseTelegramWaiver(input: ReleaseRecord): string;
|
|
export function releaseWaivedIntegrationChannels(input: ReleaseRecord): string[];
|
|
export function validateReleaseTelegramWaiverBinding(
|
|
plan: ReleaseRecord | undefined,
|
|
validationInputs?: ReleaseRecord,
|
|
): void;
|
|
|
|
export interface ReleaseRecord {
|
|
[key: string]: unknown;
|
|
}
|
|
export interface ReleaseChild extends ReleaseRecord {
|
|
key: string;
|
|
runAttempt: number | null;
|
|
runId: string;
|
|
}
|
|
export interface ReleaseExecutionPlan extends ReleaseRecord {
|
|
sha256: string;
|
|
sourceAdmissionContract?: "1";
|
|
sourceAdmission?: import("./full-release-publication-contract.mjs").PublicationSourceFact | null;
|
|
publicationAdmissionContract?: "1";
|
|
publicationAdmission?:
|
|
| import("./full-release-publication-contract.mjs").PublicationAdmission
|
|
| null;
|
|
children: ReleaseChild[];
|
|
evidenceReuse: ReleaseRecord;
|
|
gates: ReleaseRecord[];
|
|
}
|
|
export interface ReleaseStateArtifact extends ReleaseRecord {
|
|
blockers: ReleaseRecord[];
|
|
children: Record<string, ReleaseRecord>;
|
|
errors: ReleaseRecord[];
|
|
parentRunAttempt: number;
|
|
sourceParentRunAttempt: number;
|
|
state: string;
|
|
}
|
|
export interface ReleaseChildSpec {
|
|
dispatchName: string;
|
|
displayName: string;
|
|
key: string;
|
|
parentJobName: string;
|
|
rerunGroups: string[];
|
|
suffix: string;
|
|
workflow: string;
|
|
}
|
|
export type ReleaseGhTransportErrorClass = "ambiguous" | "hard" | "transient";
|
|
export function classifyReleaseGhTransportError(error: unknown): ReleaseGhTransportErrorClass;
|
|
export function isReleaseGhArtifactMissingError(error: unknown): boolean;
|
|
export function releaseChildSpec(key: string): ReleaseChildSpec;
|
|
export function releaseChildSpecs(): ReleaseChildSpec[];
|
|
export function planReleaseChildRerun(input: {
|
|
childKey: string;
|
|
jobs: ReleaseRecord[];
|
|
}):
|
|
| { failed: string[]; mode: "failed-jobs" }
|
|
| { failed: string[]; mode: "producer"; producer: string };
|
|
export function validateReleaseChildRunProvenance(
|
|
run: ReleaseRecord,
|
|
expected?: ReleaseRecord,
|
|
): {
|
|
dispatchActor: string;
|
|
effectiveRunAttempt: number;
|
|
repository: string;
|
|
triggeringActor: string;
|
|
};
|
|
export function validateReleaseChildDispatchBinding(input: ReleaseRecord): void;
|
|
export function buildReleaseExecutionPlan(input: ReleaseRecord): {
|
|
children: ReleaseChild[];
|
|
gates: ReleaseRecord[];
|
|
};
|
|
export function buildReleaseExecutionPlanArtifact(input: ReleaseRecord): ReleaseExecutionPlan;
|
|
export function validateReleaseExecutionPlanArtifact(
|
|
payload: unknown,
|
|
expected?: Record<string, unknown>,
|
|
): ReleaseExecutionPlan;
|
|
export function releaseExecutionPlanSha256(plan: ReleaseRecord): string;
|
|
export function releaseCompositeJobsSha256(value: ReleaseRecord): string;
|
|
export function compareReleaseJobsByName(left: { name: string }, right: { name: string }): number;
|
|
export function composeReleaseAttemptJobs(
|
|
attempts: Array<{ jobs: ReleaseRecord[]; runAttempt: number }>,
|
|
expected: { effectiveRunAttempt: number; plannedRunAttempt: number },
|
|
): {
|
|
effectiveRunAttempt: number;
|
|
jobs: ReleaseRecord[];
|
|
plannedRunAttempt: number;
|
|
sha256: string;
|
|
};
|
|
export function composeReleaseChildAttemptEvidence(input: {
|
|
attempts: Array<{ jobs: ReleaseRecord[]; runAttempt: number }>;
|
|
expected: ReleaseRecord;
|
|
run: ReleaseRecord;
|
|
}): ReleaseRecord;
|
|
|
|
export function terminalPolicyPass(child: ReleaseRecord): boolean;
|
|
|
|
export function classifyReleaseSnapshot(input: ReleaseRecord): ReleaseStateArtifact;
|
|
export function releasePlanGateFailures(gates: ReleaseRecord[]): ReleaseRecord[];
|
|
export function buildReleaseStateArtifact(input: ReleaseRecord): ReleaseStateArtifact;
|
|
export function validateReleaseStateArtifact(
|
|
payload: unknown,
|
|
expected?: Record<string, unknown>,
|
|
expectedMode?: string,
|
|
): ReleaseStateArtifact;
|
|
export function validateRetiredReleaseRetryFields(value: ReleaseRecord): void;
|
|
export function verifyReleaseStateArtifacts(
|
|
executionPlanPayload: unknown,
|
|
decisionPayload: unknown,
|
|
drainPayload: unknown,
|
|
expected?: Record<string, unknown>,
|
|
): {
|
|
decision: ReleaseStateArtifact;
|
|
drain: ReleaseStateArtifact;
|
|
executionPlan: ReleaseExecutionPlan;
|
|
sourceAttempts: {
|
|
decision: number;
|
|
drain: number;
|
|
executionPlan: number;
|
|
};
|
|
};
|
|
export function selectReleaseStateArtifacts(
|
|
executionPlanPayload: unknown,
|
|
decisionCandidates: Array<{ name: string; payload: unknown }>,
|
|
drainCandidates: Array<{ name: string; payload: unknown }>,
|
|
expected?: Record<string, unknown>,
|
|
): {
|
|
decision: ReleaseStateArtifact;
|
|
drain: ReleaseStateArtifact;
|
|
executionPlan: ReleaseExecutionPlan;
|
|
sourceAttempts: {
|
|
decision: number;
|
|
drain: number;
|
|
executionPlan: number;
|
|
};
|
|
};
|
|
export function formatReleaseStateOutcome(payload: ReleaseRecord): string;
|
|
export function releaseStateChildEvidence(child: ReleaseRecord): ReleaseRecord;
|
|
export function affectedActiveRunIds(
|
|
children: ReleaseRecord[],
|
|
blockers: ReleaseRecord[],
|
|
cancelledRunIds?: Set<string>,
|
|
): string[];
|