@resolveio/server-lib 22.3.154 → 22.3.156
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/util/ai-runner-manager-policy.d.ts +59 -0
- package/util/ai-runner-manager-policy.js +236 -0
- package/util/ai-runner-manager-policy.js.map +1 -1
- package/util/support-runner-v5.d.ts +13 -0
- package/util/support-runner-v5.js +75 -1
- package/util/support-runner-v5.js.map +1 -1
package/package.json
CHANGED
|
@@ -165,6 +165,61 @@ export interface ResolveIOAIManagerHotfixFirstReleasePolicy {
|
|
|
165
165
|
forbiddenActions: string[];
|
|
166
166
|
requiredEvidence: string[];
|
|
167
167
|
}
|
|
168
|
+
export type ResolveIOAIManagerHotfixEvidenceStatus = 'missing' | 'incomplete' | 'passed' | 'blocked';
|
|
169
|
+
export interface ResolveIOAIManagerHotfixEvidenceTarget {
|
|
170
|
+
surface?: string;
|
|
171
|
+
host?: string;
|
|
172
|
+
path?: string;
|
|
173
|
+
artifactPath?: string;
|
|
174
|
+
bucket?: string;
|
|
175
|
+
distributionId?: string;
|
|
176
|
+
processName?: string;
|
|
177
|
+
configKey?: string;
|
|
178
|
+
cacheKey?: string;
|
|
179
|
+
seedKey?: string;
|
|
180
|
+
}
|
|
181
|
+
export interface ResolveIOAIManagerHotfixEvidence {
|
|
182
|
+
channel: ResolveIOAIManagerHotfixChannel;
|
|
183
|
+
status?: ResolveIOAIManagerHotfixEvidenceStatus | string;
|
|
184
|
+
target: ResolveIOAIManagerHotfixEvidenceTarget;
|
|
185
|
+
compiledArtifactPath?: string;
|
|
186
|
+
builtDistPath?: string;
|
|
187
|
+
remoteChecksumBefore?: string;
|
|
188
|
+
remoteChecksumAfter?: string;
|
|
189
|
+
remoteChecksum?: string;
|
|
190
|
+
restartEvidence?: string;
|
|
191
|
+
healthCheckStatus?: string;
|
|
192
|
+
selfTestStatus?: string;
|
|
193
|
+
releaseGateStatus?: string;
|
|
194
|
+
s3UploadResult?: string;
|
|
195
|
+
cloudfrontInvalidationId?: string;
|
|
196
|
+
publicProof?: string;
|
|
197
|
+
configChangeEvidence?: string;
|
|
198
|
+
seedDataEvidence?: string;
|
|
199
|
+
cacheInvalidationEvidence?: string;
|
|
200
|
+
serviceRestartEvidence?: string;
|
|
201
|
+
releaseArtifactFingerprint?: string;
|
|
202
|
+
lastReleaseArtifactFingerprint?: string;
|
|
203
|
+
forceDeployReason?: string;
|
|
204
|
+
hotfixCannotResolveReason?: string;
|
|
205
|
+
fullDeployRequested?: boolean;
|
|
206
|
+
recordedAt?: Date | string;
|
|
207
|
+
}
|
|
208
|
+
export interface ResolveIOAIManagerHotfixEvidenceValidation {
|
|
209
|
+
valid: boolean;
|
|
210
|
+
status: ResolveIOAIManagerHotfixEvidenceStatus;
|
|
211
|
+
channel: ResolveIOAIManagerHotfixChannel | '';
|
|
212
|
+
blockers: string[];
|
|
213
|
+
warnings: string[];
|
|
214
|
+
fullDeployAllowed: boolean;
|
|
215
|
+
fullDeployBlocked: boolean;
|
|
216
|
+
hotfixSatisfied: boolean;
|
|
217
|
+
requiredEvidence: string[];
|
|
218
|
+
successEvidence: string[];
|
|
219
|
+
normalized?: ResolveIOAIManagerHotfixEvidence;
|
|
220
|
+
policy?: ResolveIOAIManagerHotfixFirstReleasePolicy;
|
|
221
|
+
nextAction: 'record_hotfix_evidence' | 'rerun_release_gate' | 'request_force_deploy_reason' | 'allow_one_full_deploy' | 'park_manual';
|
|
222
|
+
}
|
|
168
223
|
export interface ResolveIOAIManagerRecoveryActionPacket {
|
|
169
224
|
actionId: string;
|
|
170
225
|
checkpointId: string;
|
|
@@ -385,6 +440,10 @@ export interface ResolveIOAIManagerRecoveryReplayCase {
|
|
|
385
440
|
fullDeployAllowed?: boolean;
|
|
386
441
|
details?: Record<string, any>;
|
|
387
442
|
}
|
|
443
|
+
export declare function normalizeResolveIOAIManagerHotfixEvidence(value: any, policy?: ResolveIOAIManagerHotfixFirstReleasePolicy): ResolveIOAIManagerHotfixEvidence | undefined;
|
|
444
|
+
export declare function validateResolveIOAIManagerHotfixEvidence(value: any, options?: {
|
|
445
|
+
policy?: ResolveIOAIManagerHotfixFirstReleasePolicy;
|
|
446
|
+
}): ResolveIOAIManagerHotfixEvidenceValidation;
|
|
388
447
|
export declare function buildResolveIOAIManagerHotfixFirstReleasePolicy(input?: ResolveIOAIManagerHotfixFirstReleasePolicyInput): ResolveIOAIManagerHotfixFirstReleasePolicy;
|
|
389
448
|
export declare function isResolveIOAIManagerSafeAutoDispatch(input: ResolveIOAIManagerAutoDispatchPolicyInput | ResolveIOAIManagerRecoveryActionDispatchAction | string | undefined): boolean;
|
|
390
449
|
export declare function normalizeResolveIOAIManagerFailureClass(value: any): string;
|
|
@@ -47,6 +47,8 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
|
47
47
|
return to.concat(ar || Array.prototype.slice.call(from));
|
|
48
48
|
};
|
|
49
49
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
50
|
+
exports.normalizeResolveIOAIManagerHotfixEvidence = normalizeResolveIOAIManagerHotfixEvidence;
|
|
51
|
+
exports.validateResolveIOAIManagerHotfixEvidence = validateResolveIOAIManagerHotfixEvidence;
|
|
50
52
|
exports.buildResolveIOAIManagerHotfixFirstReleasePolicy = buildResolveIOAIManagerHotfixFirstReleasePolicy;
|
|
51
53
|
exports.isResolveIOAIManagerSafeAutoDispatch = isResolveIOAIManagerSafeAutoDispatch;
|
|
52
54
|
exports.normalizeResolveIOAIManagerFailureClass = normalizeResolveIOAIManagerFailureClass;
|
|
@@ -96,6 +98,240 @@ function cleanList(values, limit, max) {
|
|
|
96
98
|
}
|
|
97
99
|
return result;
|
|
98
100
|
}
|
|
101
|
+
var HOTFIX_CHANNELS = new Set([
|
|
102
|
+
'static_ui',
|
|
103
|
+
'backend_js',
|
|
104
|
+
'config',
|
|
105
|
+
'seed_data',
|
|
106
|
+
'cache_invalidation',
|
|
107
|
+
'service_restart',
|
|
108
|
+
'release_artifact',
|
|
109
|
+
'force_deploy_review',
|
|
110
|
+
'new_artifact_deploy',
|
|
111
|
+
'artifact_build'
|
|
112
|
+
]);
|
|
113
|
+
function cleanObject(value) {
|
|
114
|
+
return value && typeof value === 'object' && !Array.isArray(value) ? value : {};
|
|
115
|
+
}
|
|
116
|
+
function normalizeHotfixChannel(value) {
|
|
117
|
+
var normalized = cleanText(value, 120).toLowerCase().replace(/[\s-]+/g, '_');
|
|
118
|
+
return HOTFIX_CHANNELS.has(normalized) ? normalized : '';
|
|
119
|
+
}
|
|
120
|
+
function normalizeHotfixStatus(value) {
|
|
121
|
+
var normalized = cleanText(value, 120).toLowerCase().replace(/[\s-]+/g, '_');
|
|
122
|
+
if (/^(pass|passed|success|succeeded|complete|completed|accepted)$/.test(normalized)) {
|
|
123
|
+
return 'passed';
|
|
124
|
+
}
|
|
125
|
+
if (/^(block|blocked|failed|fail|error|denied)$/.test(normalized)) {
|
|
126
|
+
return 'blocked';
|
|
127
|
+
}
|
|
128
|
+
if (/^(missing|none)$/.test(normalized)) {
|
|
129
|
+
return 'missing';
|
|
130
|
+
}
|
|
131
|
+
return 'incomplete';
|
|
132
|
+
}
|
|
133
|
+
function hotfixStatusPassed(value) {
|
|
134
|
+
return normalizeHotfixStatus(value) === 'passed';
|
|
135
|
+
}
|
|
136
|
+
function normalizeHotfixEvidenceTarget(value) {
|
|
137
|
+
var source = cleanObject(value);
|
|
138
|
+
return {
|
|
139
|
+
surface: cleanText(source.surface, 160),
|
|
140
|
+
host: cleanText(source.host || source.hostname || source.domain, 240),
|
|
141
|
+
path: cleanText(source.path || source.remotePath || source.remote_path, 500),
|
|
142
|
+
artifactPath: cleanText(source.artifactPath || source.artifact_path || source.localPath || source.local_path, 500),
|
|
143
|
+
bucket: cleanText(source.bucket || source.s3Bucket || source.s3_bucket, 240),
|
|
144
|
+
distributionId: cleanText(source.distributionId || source.distribution_id || source.cloudfrontDistributionId || source.cloudfront_distribution_id, 240),
|
|
145
|
+
processName: cleanText(source.processName || source.process_name || source.service || source.serviceName, 160),
|
|
146
|
+
configKey: cleanText(source.configKey || source.config_key || source.key, 240),
|
|
147
|
+
cacheKey: cleanText(source.cacheKey || source.cache_key, 240),
|
|
148
|
+
seedKey: cleanText(source.seedKey || source.seed_key || source.fixture, 240)
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
function normalizeResolveIOAIManagerHotfixEvidence(value, policy) {
|
|
152
|
+
var _a;
|
|
153
|
+
var source = cleanObject(value);
|
|
154
|
+
if (!Object.keys(source).length) {
|
|
155
|
+
return undefined;
|
|
156
|
+
}
|
|
157
|
+
var channel = normalizeHotfixChannel(source.channel || source.hotfixChannel || source.hotfix_channel || ((_a = policy === null || policy === void 0 ? void 0 : policy.hotfixPlan) === null || _a === void 0 ? void 0 : _a.recommendedChannel));
|
|
158
|
+
if (!channel) {
|
|
159
|
+
return undefined;
|
|
160
|
+
}
|
|
161
|
+
var target = normalizeHotfixEvidenceTarget(source.target || source);
|
|
162
|
+
return {
|
|
163
|
+
channel: channel,
|
|
164
|
+
status: normalizeHotfixStatus(source.status),
|
|
165
|
+
target: target,
|
|
166
|
+
compiledArtifactPath: cleanText(source.compiledArtifactPath || source.compiled_artifact_path || target.artifactPath, 500),
|
|
167
|
+
builtDistPath: cleanText(source.builtDistPath || source.built_dist_path || target.artifactPath, 500),
|
|
168
|
+
remoteChecksumBefore: cleanText(source.remoteChecksumBefore || source.remote_checksum_before || source.checksumBefore || source.checksum_before, 160),
|
|
169
|
+
remoteChecksumAfter: cleanText(source.remoteChecksumAfter || source.remote_checksum_after || source.checksumAfter || source.checksum_after, 160),
|
|
170
|
+
remoteChecksum: cleanText(source.remoteChecksum || source.remote_checksum || source.checksum, 160),
|
|
171
|
+
restartEvidence: cleanText(source.restartEvidence || source.restart_evidence, 1000),
|
|
172
|
+
healthCheckStatus: cleanText(source.healthCheckStatus || source.health_check_status || source.health, 160),
|
|
173
|
+
selfTestStatus: cleanText(source.selfTestStatus || source.self_test_status || source.selfTest || source.self_test, 160),
|
|
174
|
+
releaseGateStatus: cleanText(source.releaseGateStatus || source.release_gate_status || source.releaseGate || source.release_gate, 160),
|
|
175
|
+
s3UploadResult: cleanText(source.s3UploadResult || source.s3_upload_result || source.uploadResult || source.upload_result, 1000),
|
|
176
|
+
cloudfrontInvalidationId: cleanText(source.cloudfrontInvalidationId || source.cloudfront_invalidation_id || source.invalidationId || source.invalidation_id, 240),
|
|
177
|
+
publicProof: cleanText(source.publicProof || source.public_proof || source.publicUrl || source.public_url, 1000),
|
|
178
|
+
configChangeEvidence: cleanText(source.configChangeEvidence || source.config_change_evidence, 1000),
|
|
179
|
+
seedDataEvidence: cleanText(source.seedDataEvidence || source.seed_data_evidence, 1000),
|
|
180
|
+
cacheInvalidationEvidence: cleanText(source.cacheInvalidationEvidence || source.cache_invalidation_evidence, 1000),
|
|
181
|
+
serviceRestartEvidence: cleanText(source.serviceRestartEvidence || source.service_restart_evidence, 1000),
|
|
182
|
+
releaseArtifactFingerprint: cleanText(source.releaseArtifactFingerprint || source.release_artifact_fingerprint || source.artifactFingerprint || source.artifact_fingerprint, 240),
|
|
183
|
+
lastReleaseArtifactFingerprint: cleanText(source.lastReleaseArtifactFingerprint || source.last_release_artifact_fingerprint || source.lastArtifactFingerprint || source.last_artifact_fingerprint, 240),
|
|
184
|
+
forceDeployReason: cleanText(source.forceDeployReason || source.force_deploy_reason, 1000),
|
|
185
|
+
hotfixCannotResolveReason: cleanText(source.hotfixCannotResolveReason || source.hotfix_cannot_resolve_reason, 1000),
|
|
186
|
+
fullDeployRequested: source.fullDeployRequested === true || source.full_deploy_requested === true,
|
|
187
|
+
recordedAt: source.recordedAt || source.recorded_at
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
function matchingHotfixPlanStep(policy, channel) {
|
|
191
|
+
var _a;
|
|
192
|
+
return (((_a = policy === null || policy === void 0 ? void 0 : policy.hotfixPlan) === null || _a === void 0 ? void 0 : _a.steps) || []).find(function (step) { return step.channel === channel; });
|
|
193
|
+
}
|
|
194
|
+
function pushMissing(blockers, condition, message) {
|
|
195
|
+
if (!condition) {
|
|
196
|
+
blockers.push(message);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
function validateResolveIOAIManagerHotfixEvidence(value, options) {
|
|
200
|
+
var _a, _b, _c, _d;
|
|
201
|
+
if (options === void 0) { options = {}; }
|
|
202
|
+
var normalized = normalizeResolveIOAIManagerHotfixEvidence(value, options.policy);
|
|
203
|
+
var policy = options.policy;
|
|
204
|
+
if (!normalized) {
|
|
205
|
+
return {
|
|
206
|
+
valid: false,
|
|
207
|
+
status: 'missing',
|
|
208
|
+
channel: '',
|
|
209
|
+
blockers: ['Hotfix evidence is missing or channel is unsupported.'],
|
|
210
|
+
warnings: [],
|
|
211
|
+
fullDeployAllowed: false,
|
|
212
|
+
fullDeployBlocked: true,
|
|
213
|
+
hotfixSatisfied: false,
|
|
214
|
+
requiredEvidence: ((_b = (_a = policy === null || policy === void 0 ? void 0 : policy.hotfixPlan) === null || _a === void 0 ? void 0 : _a.steps) === null || _b === void 0 ? void 0 : _b.flatMap(function (step) { return step.requiredEvidence; })) || [],
|
|
215
|
+
successEvidence: ((_d = (_c = policy === null || policy === void 0 ? void 0 : policy.hotfixPlan) === null || _c === void 0 ? void 0 : _c.steps) === null || _d === void 0 ? void 0 : _d.flatMap(function (step) { return step.successEvidence; })) || [],
|
|
216
|
+
policy: policy,
|
|
217
|
+
nextAction: 'record_hotfix_evidence'
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
var blockers = [];
|
|
221
|
+
var warnings = [];
|
|
222
|
+
var target = normalized.target || {};
|
|
223
|
+
var channel = normalized.channel;
|
|
224
|
+
var step = matchingHotfixPlanStep(policy, channel);
|
|
225
|
+
var requiredEvidence = (step === null || step === void 0 ? void 0 : step.requiredEvidence) || [];
|
|
226
|
+
var successEvidence = (step === null || step === void 0 ? void 0 : step.successEvidence) || [];
|
|
227
|
+
var policyAllowsFullDeploy = (policy === null || policy === void 0 ? void 0 : policy.fullDeployAllowed) === true;
|
|
228
|
+
var policyBlocksDuplicate = (policy === null || policy === void 0 ? void 0 : policy.duplicateDeployBlocked) === true || (policy === null || policy === void 0 ? void 0 : policy.duplicatePublishBlocked) === true;
|
|
229
|
+
if (normalized.fullDeployRequested && !policyAllowsFullDeploy && channel !== 'force_deploy_review' && channel !== 'new_artifact_deploy') {
|
|
230
|
+
blockers.push('Full deploy requested but hotfix-first policy does not allow a full deploy for this release state.');
|
|
231
|
+
}
|
|
232
|
+
if (normalized.fullDeployRequested && policyBlocksDuplicate && !normalized.forceDeployReason && channel !== 'force_deploy_review') {
|
|
233
|
+
blockers.push('Duplicate deploy/publish fingerprint requires force deploy/publish evidence before any full deploy.');
|
|
234
|
+
}
|
|
235
|
+
if (channel === 'backend_js') {
|
|
236
|
+
pushMissing(blockers, !!normalized.compiledArtifactPath, 'Backend JS hotfix requires compiledArtifactPath.');
|
|
237
|
+
pushMissing(blockers, !!target.host, 'Backend JS hotfix requires target.host.');
|
|
238
|
+
pushMissing(blockers, !!target.path, 'Backend JS hotfix requires target.path.');
|
|
239
|
+
pushMissing(blockers, !!(normalized.remoteChecksumAfter || normalized.remoteChecksum), 'Backend JS hotfix requires remote checksum after replacement.');
|
|
240
|
+
pushMissing(blockers, !!(normalized.restartEvidence || normalized.serviceRestartEvidence), 'Backend JS hotfix requires restart evidence.');
|
|
241
|
+
pushMissing(blockers, hotfixStatusPassed(normalized.healthCheckStatus), 'Backend JS hotfix requires passed healthCheckStatus.');
|
|
242
|
+
pushMissing(blockers, hotfixStatusPassed(normalized.selfTestStatus), 'Backend JS hotfix requires passed selfTestStatus.');
|
|
243
|
+
if (normalized.remoteChecksumBefore && normalized.remoteChecksumAfter && normalized.remoteChecksumBefore === normalized.remoteChecksumAfter) {
|
|
244
|
+
blockers.push('Backend JS hotfix checksum did not change; record force/no-op evidence or do not claim a hotfix.');
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
else if (channel === 'static_ui') {
|
|
248
|
+
pushMissing(blockers, !!normalized.builtDistPath, 'Static UI hotfix requires builtDistPath.');
|
|
249
|
+
pushMissing(blockers, !!target.bucket, 'Static UI hotfix requires target.bucket.');
|
|
250
|
+
pushMissing(blockers, !!target.distributionId, 'Static UI hotfix requires target.distributionId.');
|
|
251
|
+
pushMissing(blockers, !!normalized.s3UploadResult, 'Static UI hotfix requires s3UploadResult.');
|
|
252
|
+
pushMissing(blockers, !!normalized.cloudfrontInvalidationId, 'Static UI hotfix requires cloudfrontInvalidationId.');
|
|
253
|
+
pushMissing(blockers, !!normalized.publicProof, 'Static UI hotfix requires publicProof.');
|
|
254
|
+
}
|
|
255
|
+
else if (channel === 'config') {
|
|
256
|
+
pushMissing(blockers, !!target.configKey, 'Config hotfix requires target.configKey.');
|
|
257
|
+
pushMissing(blockers, !!normalized.configChangeEvidence, 'Config hotfix requires configChangeEvidence.');
|
|
258
|
+
pushMissing(blockers, hotfixStatusPassed(normalized.releaseGateStatus), 'Config hotfix requires passed releaseGateStatus.');
|
|
259
|
+
}
|
|
260
|
+
else if (channel === 'seed_data') {
|
|
261
|
+
pushMissing(blockers, !!target.seedKey, 'Seed-data hotfix requires target.seedKey.');
|
|
262
|
+
pushMissing(blockers, !!normalized.seedDataEvidence, 'Seed-data hotfix requires seedDataEvidence.');
|
|
263
|
+
pushMissing(blockers, hotfixStatusPassed(normalized.releaseGateStatus), 'Seed-data hotfix requires passed releaseGateStatus.');
|
|
264
|
+
}
|
|
265
|
+
else if (channel === 'cache_invalidation') {
|
|
266
|
+
pushMissing(blockers, !!target.cacheKey, 'Cache invalidation hotfix requires target.cacheKey.');
|
|
267
|
+
pushMissing(blockers, !!normalized.cacheInvalidationEvidence, 'Cache invalidation hotfix requires cacheInvalidationEvidence.');
|
|
268
|
+
pushMissing(blockers, hotfixStatusPassed(normalized.releaseGateStatus) || hotfixStatusPassed(normalized.healthCheckStatus), 'Cache invalidation hotfix requires passed releaseGateStatus or healthCheckStatus.');
|
|
269
|
+
}
|
|
270
|
+
else if (channel === 'service_restart') {
|
|
271
|
+
pushMissing(blockers, !!target.processName, 'Service restart hotfix requires target.processName.');
|
|
272
|
+
pushMissing(blockers, !!(normalized.serviceRestartEvidence || normalized.restartEvidence), 'Service restart hotfix requires restart evidence.');
|
|
273
|
+
pushMissing(blockers, hotfixStatusPassed(normalized.healthCheckStatus), 'Service restart hotfix requires passed healthCheckStatus.');
|
|
274
|
+
pushMissing(blockers, hotfixStatusPassed(normalized.selfTestStatus), 'Service restart hotfix requires passed selfTestStatus.');
|
|
275
|
+
}
|
|
276
|
+
else if (channel === 'release_artifact') {
|
|
277
|
+
pushMissing(blockers, !!normalized.releaseArtifactFingerprint, 'Release artifact hotfix requires releaseArtifactFingerprint.');
|
|
278
|
+
pushMissing(blockers, hotfixStatusPassed(normalized.releaseGateStatus), 'Release artifact hotfix requires passed releaseGateStatus.');
|
|
279
|
+
}
|
|
280
|
+
else if (channel === 'force_deploy_review') {
|
|
281
|
+
pushMissing(blockers, !!normalized.forceDeployReason, 'Force deploy review requires forceDeployReason.');
|
|
282
|
+
pushMissing(blockers, !!normalized.hotfixCannotResolveReason, 'Force deploy review requires hotfixCannotResolveReason.');
|
|
283
|
+
}
|
|
284
|
+
else if (channel === 'new_artifact_deploy') {
|
|
285
|
+
pushMissing(blockers, !!normalized.releaseArtifactFingerprint, 'New artifact deploy requires releaseArtifactFingerprint.');
|
|
286
|
+
pushMissing(blockers, !!normalized.lastReleaseArtifactFingerprint, 'New artifact deploy requires lastReleaseArtifactFingerprint.');
|
|
287
|
+
if (normalized.releaseArtifactFingerprint && normalized.lastReleaseArtifactFingerprint && normalized.releaseArtifactFingerprint === normalized.lastReleaseArtifactFingerprint) {
|
|
288
|
+
blockers.push('New artifact deploy requires a fingerprint different from the last deployed artifact.');
|
|
289
|
+
}
|
|
290
|
+
pushMissing(blockers, hotfixStatusPassed(normalized.releaseGateStatus), 'New artifact deploy requires passed releaseGateStatus.');
|
|
291
|
+
}
|
|
292
|
+
else if (channel === 'artifact_build') {
|
|
293
|
+
pushMissing(blockers, !!normalized.releaseArtifactFingerprint, 'Artifact build requires releaseArtifactFingerprint.');
|
|
294
|
+
if (normalized.fullDeployRequested) {
|
|
295
|
+
blockers.push('Artifact build evidence cannot request a full deploy in the same step.');
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
if (!step && policy) {
|
|
299
|
+
warnings.push("Hotfix channel ".concat(channel, " is not the recommended channel in the current release policy."));
|
|
300
|
+
}
|
|
301
|
+
var forceDeployReviewValid = channel === 'force_deploy_review' && blockers.length === 0;
|
|
302
|
+
var newArtifactDeployValid = channel === 'new_artifact_deploy' && blockers.length === 0;
|
|
303
|
+
var fullDeployAllowed = forceDeployReviewValid || newArtifactDeployValid || (policyAllowsFullDeploy && blockers.length === 0 && normalized.fullDeployRequested === true);
|
|
304
|
+
var hotfixSatisfied = blockers.length === 0 && !fullDeployAllowed;
|
|
305
|
+
var status = blockers.length
|
|
306
|
+
? (normalizeHotfixStatus(normalized.status) === 'blocked' ? 'blocked' : 'incomplete')
|
|
307
|
+
: 'passed';
|
|
308
|
+
var fullDeployBlocked = !fullDeployAllowed && (normalized.fullDeployRequested === true || (policy === null || policy === void 0 ? void 0 : policy.fullDeployAllowed) !== true);
|
|
309
|
+
var nextAction = blockers.some(function (blocker) { return /force deploy/i.test(blocker); })
|
|
310
|
+
? 'request_force_deploy_reason'
|
|
311
|
+
: fullDeployAllowed
|
|
312
|
+
? 'allow_one_full_deploy'
|
|
313
|
+
: hotfixSatisfied
|
|
314
|
+
? 'rerun_release_gate'
|
|
315
|
+
: blockers.length
|
|
316
|
+
? 'record_hotfix_evidence'
|
|
317
|
+
: 'park_manual';
|
|
318
|
+
normalized.status = status;
|
|
319
|
+
return {
|
|
320
|
+
valid: blockers.length === 0,
|
|
321
|
+
status: status,
|
|
322
|
+
channel: channel,
|
|
323
|
+
blockers: blockers,
|
|
324
|
+
warnings: warnings,
|
|
325
|
+
fullDeployAllowed: fullDeployAllowed,
|
|
326
|
+
fullDeployBlocked: fullDeployBlocked,
|
|
327
|
+
hotfixSatisfied: hotfixSatisfied,
|
|
328
|
+
requiredEvidence: requiredEvidence,
|
|
329
|
+
successEvidence: successEvidence,
|
|
330
|
+
normalized: normalized,
|
|
331
|
+
policy: policy,
|
|
332
|
+
nextAction: nextAction
|
|
333
|
+
};
|
|
334
|
+
}
|
|
99
335
|
function releaseStatusIsBlocked(value) {
|
|
100
336
|
return /fail|error|blocked|missing|empty|not ready|not_ready|denied|invalid|timeout|stale/i.test(value);
|
|
101
337
|
}
|