@uipath/solution-tool 1.204.0-preview.255 → 1.205.0-preview.256
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/README.md +3 -3
- package/dist/THIRD-PARTY-NOTICES.md +2 -2
- package/dist/archive-extract-x35t9ktj.js +120 -0
- package/dist/cleanup-command-service-n4e7vxnw.js +149 -0
- package/dist/deploy-delete-service-cag0q8yx.js +25 -0
- package/dist/deploy-run-service-f0h8wb9w.js +25 -0
- package/dist/{deploy-status-service-6svq7c6w.js → deploy-status-service-yh6xn6e0.js} +41 -33
- package/dist/deploy.js +23 -17
- package/dist/{deployment-search-v2qtz23x.js → deployment-search-mnywd9nc.js} +16 -10
- package/dist/{embedded-file-reader-rf2g1kfj.js → embedded-file-reader-z4becc02.js} +2 -2
- package/dist/{feed-resolver-xz3akamf.js → feed-resolver-fve33dxq.js} +10 -9
- package/dist/feed-scope-failure-jmg4t1r1.js +19 -0
- package/dist/{feed-session-sxga31vn.js → feed-session-7xqphdrg.js} +3 -3
- package/dist/governance-options-4vxz7ekn.js +32 -0
- package/dist/index-g8c8nf1c.js +667 -0
- package/dist/index-prm27bvm.js +138 -0
- package/dist/index.js +27 -29
- package/dist/init.js +11 -10
- package/dist/{list-tjetkspc.js → list-50mepbed.js} +10 -8
- package/dist/models/pack-command-types.d.ts +15 -0
- package/dist/node-7jm7ksqa.js +86 -0
- package/dist/pack-command-service-dewf5vsq.js +35 -0
- package/dist/pack-project-xwd1rbaa.js +97 -0
- package/dist/pack.js +24 -14
- package/dist/package-id-1wr3cy9c.js +13 -0
- package/dist/packager-tool-09swr9cp.js +171 -0
- package/dist/{packager-tool-a9jx8gf4.js → packager-tool-2vmsh5pt.js} +196 -1519
- package/dist/{packager-tool-px1j9kre.js → packager-tool-3bwnkjdq.js} +2 -2
- package/dist/{packager-tool-gb35b4qs.js → packager-tool-43ahv5mn.js} +192 -96
- package/dist/{packager-tool-9ha2z8h5.js → packager-tool-47by487p.js} +6 -4
- package/dist/packager-tool-47wzvqw0.js +86 -0
- package/dist/{packager-tool-zns6n8zp.js → packager-tool-5ddtwzva.js} +1 -1
- package/dist/packager-tool-5edvzz80.js +543 -0
- package/dist/{packager-tool-jq9zw82w.js → packager-tool-5n6jsn41.js} +104 -14
- package/dist/packager-tool-60af1hw2.js +26 -0
- package/dist/{packager-tool-f5gq77m5.js → packager-tool-61pwb567.js} +2 -2
- package/dist/{packager-tool-yrz4mwfn.js → packager-tool-6kz1pv9f.js} +1373 -486
- package/dist/packager-tool-6ybywxxn.js +1809 -0
- package/dist/packager-tool-8ptbmmmp.js +2132 -0
- package/dist/{packager-tool-7gr2nphb.js → packager-tool-97rcgwvv.js} +224 -6
- package/dist/{packager-tool-83m6ns0r.js → packager-tool-9t26kde1.js} +3556 -1646
- package/dist/packager-tool-act5r386.js +239 -0
- package/dist/packager-tool-amhyxzz6.js +125 -0
- package/dist/packager-tool-b03rva43.js +188 -0
- package/dist/{packager-tool-e2rtr49j.js → packager-tool-b2nhscfk.js} +15 -31
- package/dist/{packager-tool-tv9c1e80.js → packager-tool-d6rrfd46.js} +149 -53
- package/dist/packager-tool-frr2xmkr.js +445 -0
- package/dist/{packager-tool-v8bkkqdb.js → packager-tool-gmwva4yv.js} +5 -5
- package/dist/packager-tool-gs3f3tf7.js +103 -0
- package/dist/packager-tool-jg692f13.js +517 -0
- package/dist/packager-tool-jmpb786m.js +109 -0
- package/dist/{packager-tool-5sex4a1h.js → packager-tool-kds8ytzw.js} +74 -23
- package/dist/packager-tool-kkfb5kgn.js +182 -0
- package/dist/packager-tool-kvcxg0zv.js +1510 -0
- package/dist/packager-tool-n3jfjn5r.js +42 -0
- package/dist/{packager-tool-fjsn5h8s.js → packager-tool-n5d5dx5j.js} +2196 -3455
- package/dist/{packager-tool-yfpcvdpm.js → packager-tool-nsya65z1.js} +357 -1370
- package/dist/{packager-tool-fv7xyzg2.js → packager-tool-pbmqk39a.js} +126 -128
- package/dist/{packager-tool-bqre28m1.js → packager-tool-qw47eyw7.js} +1 -1
- package/dist/{packager-tool-9qgmwy21.js → packager-tool-rc3hwn4b.js} +25 -4
- package/dist/packager-tool-resolver-994z3jkj.js +23 -0
- package/dist/{packager-tool-tgw5x6vx.js → packager-tool-rvt68c1t.js} +17 -8
- package/dist/{packager-tool-gab9y5ct.js → packager-tool-t8gh825q.js} +37 -13
- package/dist/{packager-tool-kswwd3hp.js → packager-tool-tx834spe.js} +2376 -4077
- package/dist/{packager-tool-zf3929se.js → packager-tool-v1f5e8t9.js} +11 -1
- package/dist/{packager-tool-ssq2kzqm.js → packager-tool-w77d72a7.js} +13 -11
- package/dist/{packager-tool-1rzssy0x.js → packager-tool-wy4fx250.js} +19 -18
- package/dist/packager-tool-wz34ma3s.js +1333 -0
- package/dist/packager-tool-zq16e1xv.js +68 -0
- package/dist/packager-tool.js +2 -2
- package/dist/prepare-solution-resources-m1djfj62.js +29 -0
- package/dist/project-command-utils-t6pmpvq3.js +90 -0
- package/dist/project-contributions-79ndycrx.js +32 -0
- package/dist/publish.js +13 -12
- package/dist/resource-mutations-c3krjqze.js +36 -0
- package/dist/resource-version-lookup-0e3e2j58.js +99 -0
- package/dist/resource.js +10 -9
- package/dist/restore-command-service-5v0b9363.js +155 -0
- package/dist/run-service-tg6b67wp.js +428 -0
- package/dist/services/deploy-activate-service.d.ts +10 -5
- package/dist/services/deploy-delete-service.d.ts +8 -4
- package/dist/services/deploy-run-service.d.ts +34 -1
- package/dist/services/deploy-uninstall-service.d.ts +21 -3
- package/dist/services/deploy-upgrade-service.d.ts +35 -1
- package/dist/services/deployment-feed-locator.d.ts +15 -4
- package/dist/services/deployment-search-client.d.ts +5 -53
- package/dist/services/deployment-search.d.ts +58 -3
- package/dist/services/deployment-state.d.ts +84 -24
- package/dist/services/deployment-validation.d.ts +5 -0
- package/dist/services/emit-runtime-dependencies.d.ts +2 -1
- package/dist/services/feed-resolver.d.ts +6 -4
- package/dist/services/feed-selection.d.ts +47 -0
- package/dist/services/http-status.d.ts +2 -7
- package/dist/services/pack-command-service.d.ts +9 -0
- package/dist/services/pack-project-selection.d.ts +51 -0
- package/dist/services/pack-project.d.ts +26 -0
- package/dist/services/pack-service.d.ts +7 -3
- package/dist/services/package-search-client.d.ts +7 -0
- package/dist/services/packager-tool-resolver.d.ts +7 -1
- package/dist/services/packages-list-service.d.ts +1 -1
- package/dist/services/permanent-deletion-consent.d.ts +110 -0
- package/dist/services/pipeline-deploy-poll.d.ts +7 -0
- package/dist/services/prepare-solution-resources.d.ts +12 -2
- package/dist/services/project-contributions.d.ts +5 -4
- package/dist/services/search-failure.d.ts +9 -13
- package/dist/services/solution-packager-helpers.d.ts +5 -2
- package/dist/services/solution-path.d.ts +1 -1
- package/dist/services/uninstall-consent.d.ts +82 -0
- package/dist/ship-telemetry-myes7ak5.js +21 -0
- package/dist/solution-auth-aead70sw.js +11 -0
- package/dist/templates/AGENTS.md +125 -12
- package/dist/tool.js +27 -29
- package/dist/utils/deployment-errors.d.ts +9 -1
- package/package.json +2 -2
- package/dist/deploy-delete-service-w3e8x1kq.js +0 -22
- package/dist/feed-scope-failure-0j5byccb.js +0 -18
- package/dist/packager-tool-f2e9rzxk.js +0 -104
- package/dist/packager-tool-resolver-6zwhec62.js +0 -20
- package/dist/packager-tool-zdfn32bc.js +0 -4465
- package/dist/prepare-solution-resources-jpb5as2s.js +0 -25
- package/dist/project-contributions-6wpff2hm.js +0 -30
- package/dist/services/legacy-deployment-search-v3.d.ts +0 -23
|
@@ -1,81 +1,85 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ACKNOWLEDGE_PERMANENT_DELETION_FLAG,
|
|
3
|
+
NO_SERVER_REASON,
|
|
4
|
+
acknowledgedButNotRunHint,
|
|
5
|
+
activateDeployment,
|
|
6
|
+
describeDeploymentFailureAsync,
|
|
7
|
+
describeValidationFailureAsync,
|
|
8
|
+
formatPermanentDeletionResources,
|
|
9
|
+
isPermanentDeletionRefusal,
|
|
10
|
+
pollPipelineDeploymentAsync,
|
|
11
|
+
remainingTimeoutMs,
|
|
12
|
+
resolveFolderInfo,
|
|
13
|
+
resolveParentFolder,
|
|
14
|
+
settlePermanentDeletionRefusalAsync,
|
|
15
|
+
stillRequiresConfirmation
|
|
16
|
+
} from "./packager-tool-frr2xmkr.js";
|
|
1
17
|
import {
|
|
2
18
|
appendDeploymentStateInstructions,
|
|
3
19
|
deploymentNextSteps,
|
|
4
|
-
explainRefusal,
|
|
5
20
|
needsPendingResources,
|
|
6
|
-
|
|
7
|
-
|
|
21
|
+
pendingResourceApis,
|
|
22
|
+
readPendingResourcesAsync,
|
|
23
|
+
reportedActivationStatus
|
|
24
|
+
} from "./packager-tool-5n6jsn41.js";
|
|
8
25
|
import {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
26
|
+
DRAFT_VERSION_MISMATCH_CODE,
|
|
27
|
+
explainPipelineStatusAfterInstall,
|
|
28
|
+
formatDeploymentFailureDetails,
|
|
29
|
+
hasServerErrorCode,
|
|
30
|
+
installLandedDespiteStatus,
|
|
31
|
+
leavesPendingDraft
|
|
32
|
+
} from "./packager-tool-act5r386.js";
|
|
15
33
|
import {
|
|
16
34
|
DeploymentSearchNeedsUserSessionError,
|
|
17
35
|
MAX_LISTED_DEPLOYMENTS,
|
|
18
36
|
blocksRedeploy,
|
|
19
|
-
deploymentToTerminalPipelineResult,
|
|
20
37
|
findDeploymentBestEffort,
|
|
21
|
-
findDeploymentByName,
|
|
22
38
|
findDeploymentsByName,
|
|
23
39
|
findDeploymentsByPackageName,
|
|
24
40
|
formatExistingDeployments,
|
|
25
41
|
interpretFailedDeployPoll,
|
|
26
42
|
isAuthRefusal,
|
|
27
|
-
isCompletedUninstall,
|
|
28
|
-
isPipelineDeploymentNotFoundError,
|
|
29
|
-
mapOperationStatusToPipelineStatus,
|
|
30
43
|
newestDeploymentRow,
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
} from "./packager-tool-
|
|
34
|
-
import {
|
|
35
|
-
Configuration as Configuration2,
|
|
36
|
-
DeploymentOperation,
|
|
37
|
-
DeploymentStatus,
|
|
38
|
-
PipelinesApi
|
|
39
|
-
} from "./packager-tool-7gr2nphb.js";
|
|
44
|
+
readDeploymentByKeyAsync,
|
|
45
|
+
resolveInstalledFolder
|
|
46
|
+
} from "./packager-tool-d6rrfd46.js";
|
|
40
47
|
import {
|
|
41
|
-
describeFeedResolutionFailureAsync,
|
|
42
48
|
feedScopeInitOverride,
|
|
43
49
|
feedSelectorFlag,
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
resolvePersonalWorkspace
|
|
47
|
-
} from "./packager-tool-tgw5x6vx.js";
|
|
50
|
+
resolveFeedScope
|
|
51
|
+
} from "./packager-tool-rvt68c1t.js";
|
|
48
52
|
import {
|
|
49
53
|
Configuration,
|
|
54
|
+
PipelinesApi
|
|
55
|
+
} from "./packager-tool-97rcgwvv.js";
|
|
56
|
+
import {
|
|
57
|
+
Configuration as Configuration2,
|
|
50
58
|
DeploymentsApi,
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
WorkflowAction
|
|
54
|
-
} from "./packager-tool-83m6ns0r.js";
|
|
59
|
+
SolutionDeploymentAction
|
|
60
|
+
} from "./packager-tool-9t26kde1.js";
|
|
55
61
|
import {
|
|
56
62
|
classifyFeedSession,
|
|
57
|
-
feedReadRefusalForApplication,
|
|
58
63
|
feedSessionRefusal
|
|
59
|
-
} from "./packager-tool-
|
|
64
|
+
} from "./packager-tool-qw47eyw7.js";
|
|
60
65
|
import {
|
|
61
66
|
getSolutionAuthContext
|
|
62
|
-
} from "./packager-tool-
|
|
67
|
+
} from "./packager-tool-61pwb567.js";
|
|
63
68
|
import {
|
|
64
69
|
resolveFolder
|
|
65
|
-
} from "./packager-tool-
|
|
70
|
+
} from "./packager-tool-8ptbmmmp.js";
|
|
66
71
|
import {
|
|
67
|
-
DEFAULT_PAGE_SIZE,
|
|
68
72
|
PollOutcome,
|
|
69
|
-
catchError,
|
|
70
|
-
extractErrorDetails,
|
|
71
73
|
logger,
|
|
72
|
-
mapPollFailure
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
74
|
+
mapPollFailure
|
|
75
|
+
} from "./packager-tool-tx834spe.js";
|
|
76
|
+
import {
|
|
77
|
+
catchError,
|
|
78
|
+
extractErrorDetails
|
|
79
|
+
} from "./packager-tool-6ybywxxn.js";
|
|
76
80
|
import {
|
|
77
81
|
getFileSystem
|
|
78
|
-
} from "./packager-tool-
|
|
82
|
+
} from "./packager-tool-v1f5e8t9.js";
|
|
79
83
|
import {
|
|
80
84
|
__commonJS,
|
|
81
85
|
__require
|
|
@@ -7022,550 +7026,6 @@ var require_public_api = __commonJS(function(exports) {
|
|
|
7022
7026
|
exports.stringify = stringify;
|
|
7023
7027
|
});
|
|
7024
7028
|
|
|
7025
|
-
// src/utils/deployment-errors.ts
|
|
7026
|
-
function coerceWorkflowErrorMessages(raw) {
|
|
7027
|
-
if (Array.isArray(raw)) {
|
|
7028
|
-
return raw.map(coerceWorkflowErrorMessage).filter((error) => error !== undefined);
|
|
7029
|
-
}
|
|
7030
|
-
const coerced = coerceWorkflowErrorMessage(raw);
|
|
7031
|
-
if (coerced) {
|
|
7032
|
-
return [coerced];
|
|
7033
|
-
}
|
|
7034
|
-
return [];
|
|
7035
|
-
}
|
|
7036
|
-
function coerceWorkflowErrorMessage(raw) {
|
|
7037
|
-
if (raw === null || raw === undefined) {
|
|
7038
|
-
return;
|
|
7039
|
-
}
|
|
7040
|
-
if (typeof raw === "string") {
|
|
7041
|
-
const trimmed = raw.trim();
|
|
7042
|
-
return trimmed ? { errorMessage: trimmed } : undefined;
|
|
7043
|
-
}
|
|
7044
|
-
if (!isRecord(raw)) {
|
|
7045
|
-
return { errorMessage: String(raw) };
|
|
7046
|
-
}
|
|
7047
|
-
if (typeof raw.errorMessage === "string" && raw.errorMessage.trim()) {
|
|
7048
|
-
return {
|
|
7049
|
-
errorMessage: raw.errorMessage.trim(),
|
|
7050
|
-
serviceMessage: typeof raw.serviceMessage === "string" ? raw.serviceMessage : undefined,
|
|
7051
|
-
exceptionTrace: typeof raw.exceptionTrace === "string" ? raw.exceptionTrace : undefined,
|
|
7052
|
-
serviceName: typeof raw.serviceName === "string" ? raw.serviceName : undefined
|
|
7053
|
-
};
|
|
7054
|
-
}
|
|
7055
|
-
return { errorMessage: stringifyUnexpectedWorkflowError(raw) };
|
|
7056
|
-
}
|
|
7057
|
-
function isRecord(value) {
|
|
7058
|
-
return typeof value === "object" && value !== null;
|
|
7059
|
-
}
|
|
7060
|
-
function stringifyUnexpectedWorkflowError(value) {
|
|
7061
|
-
try {
|
|
7062
|
-
return JSON.stringify(value);
|
|
7063
|
-
} catch (error) {
|
|
7064
|
-
return String(error);
|
|
7065
|
-
}
|
|
7066
|
-
}
|
|
7067
|
-
function formatSummaryValidationError(e) {
|
|
7068
|
-
return e.errorType ? `[${e.errorType}] ${e.errorText}` : e.errorText;
|
|
7069
|
-
}
|
|
7070
|
-
function formatSummaryScheduleError(e) {
|
|
7071
|
-
return e.errorCode ? `[${e.errorCode}] ${e.errorText}` : e.errorText;
|
|
7072
|
-
}
|
|
7073
|
-
function formatSummaryWorkflowError(e) {
|
|
7074
|
-
const parts = [e.errorMessage];
|
|
7075
|
-
const details = [];
|
|
7076
|
-
if (e.serviceName) {
|
|
7077
|
-
details.push(`service: ${e.serviceName}`);
|
|
7078
|
-
}
|
|
7079
|
-
if (e.serviceMessage) {
|
|
7080
|
-
details.push(`reason: ${e.serviceMessage}`);
|
|
7081
|
-
}
|
|
7082
|
-
if (details.length > 0) {
|
|
7083
|
-
parts.push(`(${details.join(", ")})`);
|
|
7084
|
-
}
|
|
7085
|
-
return parts.join(" ");
|
|
7086
|
-
}
|
|
7087
|
-
function nonEmpty(arr) {
|
|
7088
|
-
return arr && arr.length > 0 ? arr : undefined;
|
|
7089
|
-
}
|
|
7090
|
-
function extractDeploymentErrors(result) {
|
|
7091
|
-
const validationErrors = nonEmpty(result.validationResult?.validationErrors?.map(formatSummaryValidationError));
|
|
7092
|
-
const conflictSources = [
|
|
7093
|
-
...result.validationResult?.conflictErrors ?? [],
|
|
7094
|
-
...result.conflictFixingErrors ?? []
|
|
7095
|
-
];
|
|
7096
|
-
const conflictErrors = nonEmpty(conflictSources.map(formatSummaryValidationError));
|
|
7097
|
-
const scheduleErrors = nonEmpty(result.deploymentScheduleErrors?.map(formatSummaryScheduleError));
|
|
7098
|
-
const deploymentErrors = nonEmpty(coerceWorkflowErrorMessages(result.deploymentResult?.errorMessage).map(formatSummaryWorkflowError));
|
|
7099
|
-
if (!validationErrors && !conflictErrors && !scheduleErrors && !deploymentErrors) {
|
|
7100
|
-
return;
|
|
7101
|
-
}
|
|
7102
|
-
return {
|
|
7103
|
-
ValidationErrors: validationErrors,
|
|
7104
|
-
ConflictErrors: conflictErrors,
|
|
7105
|
-
ScheduleErrors: scheduleErrors,
|
|
7106
|
-
DeploymentErrors: deploymentErrors
|
|
7107
|
-
};
|
|
7108
|
-
}
|
|
7109
|
-
function formatDeploymentErrorsAsText(summary) {
|
|
7110
|
-
const lines = [];
|
|
7111
|
-
if (summary.ValidationErrors) {
|
|
7112
|
-
lines.push(`Validation: ${summary.ValidationErrors.join("; ")}`);
|
|
7113
|
-
}
|
|
7114
|
-
if (summary.ConflictErrors) {
|
|
7115
|
-
lines.push(`Conflicts: ${summary.ConflictErrors.join("; ")}`);
|
|
7116
|
-
}
|
|
7117
|
-
if (summary.ScheduleErrors) {
|
|
7118
|
-
lines.push(`Schedule: ${summary.ScheduleErrors.join("; ")}`);
|
|
7119
|
-
}
|
|
7120
|
-
if (summary.DeploymentErrors) {
|
|
7121
|
-
lines.push(`Deployment: ${summary.DeploymentErrors.join("; ")}`);
|
|
7122
|
-
}
|
|
7123
|
-
return lines.join(`
|
|
7124
|
-
`);
|
|
7125
|
-
}
|
|
7126
|
-
function formatErrorCode(errorCode) {
|
|
7127
|
-
return errorCode ? `[${errorCode}] ` : "";
|
|
7128
|
-
}
|
|
7129
|
-
function formatDetailedValidationError(error) {
|
|
7130
|
-
const resource = [error.kind, error.name].filter(Boolean).join(" ");
|
|
7131
|
-
const prefix = resource ? `${resource}: ` : "";
|
|
7132
|
-
return `${formatErrorCode(error.errorCode)}${prefix}${error.errorText}`;
|
|
7133
|
-
}
|
|
7134
|
-
function formatDetailedConflictError(error) {
|
|
7135
|
-
const actions = error.conflictFixingActions?.length ? ` (fix: ${error.conflictFixingActions.join(", ")})` : "";
|
|
7136
|
-
return `${formatDetailedValidationError(error)}${actions}`;
|
|
7137
|
-
}
|
|
7138
|
-
function formatDetailedScheduleError(error) {
|
|
7139
|
-
return `${formatErrorCode(error.errorCode)}${error.errorText}`;
|
|
7140
|
-
}
|
|
7141
|
-
function formatDetailedWorkflowError(error) {
|
|
7142
|
-
const parts = [
|
|
7143
|
-
error.serviceName && error.errorMessage ? `${error.serviceName}: ${error.errorMessage}` : error.errorMessage ?? error.serviceName,
|
|
7144
|
-
error.serviceMessage,
|
|
7145
|
-
error.exceptionTrace
|
|
7146
|
-
].filter(Boolean);
|
|
7147
|
-
return parts.join(" | ");
|
|
7148
|
-
}
|
|
7149
|
-
function formatResourceInstallError(error) {
|
|
7150
|
-
const context = [error.kind, error.type, error.name].filter(Boolean).join(" ");
|
|
7151
|
-
return context ? `${context}: ${error.text}` : error.text;
|
|
7152
|
-
}
|
|
7153
|
-
function formatServiceError(service) {
|
|
7154
|
-
const servicePrefix = service.serviceName ? `${service.serviceName} (${service.status})` : service.status;
|
|
7155
|
-
const errors = [];
|
|
7156
|
-
if (service.errorMessage) {
|
|
7157
|
-
errors.push(`${servicePrefix}: ${service.errorMessage}`);
|
|
7158
|
-
}
|
|
7159
|
-
if (service.serviceErrorMessages?.length) {
|
|
7160
|
-
errors.push(...service.serviceErrorMessages.map((error) => `${servicePrefix}: ${formatResourceInstallError(error)}`));
|
|
7161
|
-
}
|
|
7162
|
-
return errors;
|
|
7163
|
-
}
|
|
7164
|
-
function formatDeploymentIdentifiers(pipelineDeploymentId, status) {
|
|
7165
|
-
const identifiers = [
|
|
7166
|
-
`pipelineDeploymentId=${pipelineDeploymentId}`,
|
|
7167
|
-
status.deploymentKey ? `deploymentKey=${status.deploymentKey}` : "",
|
|
7168
|
-
status.configurationKey ? `configurationKey=${status.configurationKey}` : "",
|
|
7169
|
-
status.instanceId ? `instanceId=${status.instanceId}` : ""
|
|
7170
|
-
].filter(Boolean);
|
|
7171
|
-
return `Operation: ${identifiers.join(", ")}`;
|
|
7172
|
-
}
|
|
7173
|
-
function formatDeploymentFailureDetails(pipelineDeploymentId, status) {
|
|
7174
|
-
return [
|
|
7175
|
-
...formatPipelineErrors(status),
|
|
7176
|
-
formatDeploymentIdentifiers(pipelineDeploymentId, status)
|
|
7177
|
-
].join(`
|
|
7178
|
-
`);
|
|
7179
|
-
}
|
|
7180
|
-
function formatPipelineErrors(status) {
|
|
7181
|
-
const errorParts = [];
|
|
7182
|
-
const validationErrors = status.validationResult?.validationErrors;
|
|
7183
|
-
if (validationErrors?.length) {
|
|
7184
|
-
errorParts.push(`Validation: ${validationErrors.map(formatDetailedValidationError).join("; ")}`);
|
|
7185
|
-
}
|
|
7186
|
-
const conflictErrors = status.validationResult?.conflictErrors;
|
|
7187
|
-
if (conflictErrors?.length) {
|
|
7188
|
-
errorParts.push(`Conflicts: ${conflictErrors.map(formatDetailedConflictError).join("; ")}`);
|
|
7189
|
-
}
|
|
7190
|
-
if (status.conflictFixingErrors?.length) {
|
|
7191
|
-
errorParts.push(`Conflict fixing: ${status.conflictFixingErrors.map(formatDetailedValidationError).join("; ")}`);
|
|
7192
|
-
}
|
|
7193
|
-
if (status.deploymentScheduleErrors?.length) {
|
|
7194
|
-
errorParts.push(`Schedule: ${status.deploymentScheduleErrors.map(formatDetailedScheduleError).join("; ")}`);
|
|
7195
|
-
}
|
|
7196
|
-
const workflowErrors = coerceWorkflowErrorMessages(status.deploymentResult?.errorMessage);
|
|
7197
|
-
if (workflowErrors.length) {
|
|
7198
|
-
errorParts.push(`Deployment: ${workflowErrors.map(formatDetailedWorkflowError).join("; ")}`);
|
|
7199
|
-
}
|
|
7200
|
-
const serviceErrors = status.deploymentResult?.services?.flatMap(formatServiceError);
|
|
7201
|
-
if (serviceErrors?.length) {
|
|
7202
|
-
errorParts.push(`Services: ${serviceErrors.join("; ")}`);
|
|
7203
|
-
}
|
|
7204
|
-
return errorParts;
|
|
7205
|
-
}
|
|
7206
|
-
function hasServerErrorCode(details, code) {
|
|
7207
|
-
return new RegExp(`"errorCode"\\s*:\\s*"${code}"`).test(details);
|
|
7208
|
-
}
|
|
7209
|
-
function isBareResponse(details) {
|
|
7210
|
-
return !/^\s*[{[]/.test(details);
|
|
7211
|
-
}
|
|
7212
|
-
var DRAFT_VERSION_MISMATCH_CODE = "DraftDeploymentHasDifferentPackageVersion";
|
|
7213
|
-
function leavesPendingDraft(status) {
|
|
7214
|
-
return status === "ValidationFailed" || status === "ConflictFixingError" || status === "DeploymentScheduleError";
|
|
7215
|
-
}
|
|
7216
|
-
function installLandedDespiteStatus(status) {
|
|
7217
|
-
const record = status.deploymentResult?.status;
|
|
7218
|
-
return status.status !== "DeploymentSucceeded" && (record === "SuccessfulInstall" || record === "SuccessfulActivate");
|
|
7219
|
-
}
|
|
7220
|
-
function explainPipelineStatusAfterInstall(status) {
|
|
7221
|
-
const lines = formatPipelineErrors(status);
|
|
7222
|
-
const errors = lines.length > 0 ? ` ${lines.join(" ")}` : "";
|
|
7223
|
-
return `The deploy pipeline ended at ${status.status} although the install landed (the deployment record reports ${status.deploymentResult?.status}): the errors it attached come from the activation validation the pipeline runs after the install, not from the install.${errors}`;
|
|
7224
|
-
}
|
|
7225
|
-
|
|
7226
|
-
// src/services/activation.ts
|
|
7227
|
-
var TERMINAL_STATUSES = new Set([
|
|
7228
|
-
"SuccessfulActivate",
|
|
7229
|
-
"FailedActivate"
|
|
7230
|
-
]);
|
|
7231
|
-
async function activateDeployment(auth, deploymentName, options) {
|
|
7232
|
-
const api = new PipelinesApi(new Configuration2({
|
|
7233
|
-
basePath: auth.basePath,
|
|
7234
|
-
accessToken: auth.accessToken
|
|
7235
|
-
}));
|
|
7236
|
-
const [stepsError, steps] = await catchError(api.pipelinesGetPreActivateSteps({ deploymentName }, options.scope));
|
|
7237
|
-
if (stepsError) {
|
|
7238
|
-
const { message, details, errorCode, retry, context } = await extractErrorDetails(stepsError);
|
|
7239
|
-
const deployment = await findDeploymentBestEffort(auth, deploymentName, options.scope);
|
|
7240
|
-
return {
|
|
7241
|
-
kind: "RequestFailed",
|
|
7242
|
-
phase: "preActivateSteps",
|
|
7243
|
-
message,
|
|
7244
|
-
details,
|
|
7245
|
-
errorCode,
|
|
7246
|
-
retry,
|
|
7247
|
-
httpStatus: context?.httpStatus,
|
|
7248
|
-
deployment
|
|
7249
|
-
};
|
|
7250
|
-
}
|
|
7251
|
-
if (steps.steps.length > 0) {
|
|
7252
|
-
logger.info(`Pre-activate steps for ${deploymentName}:`);
|
|
7253
|
-
for (const step of steps.steps) {
|
|
7254
|
-
logger.info(` [${step.serviceName}] ${step.step}: ${step.description}`);
|
|
7255
|
-
}
|
|
7256
|
-
}
|
|
7257
|
-
const [activateError, activateResult] = await catchError(api.pipelinesActivate({ deploymentName }, options.scope));
|
|
7258
|
-
if (activateError) {
|
|
7259
|
-
const { message, details, errorCode, retry, context } = await extractErrorDetails(activateError);
|
|
7260
|
-
const deployment = await findDeploymentBestEffort(auth, deploymentName, options.scope);
|
|
7261
|
-
return {
|
|
7262
|
-
kind: "RequestFailed",
|
|
7263
|
-
phase: "activate",
|
|
7264
|
-
message,
|
|
7265
|
-
details,
|
|
7266
|
-
errorCode,
|
|
7267
|
-
retry,
|
|
7268
|
-
httpStatus: context?.httpStatus,
|
|
7269
|
-
deployment
|
|
7270
|
-
};
|
|
7271
|
-
}
|
|
7272
|
-
const instanceId = activateResult.instanceId;
|
|
7273
|
-
if (!instanceId) {
|
|
7274
|
-
return { kind: "NoInstance" };
|
|
7275
|
-
}
|
|
7276
|
-
const pollResult = await pollUntil({
|
|
7277
|
-
fn: () => api.pipelinesGetDeploymentInstanceStatus({ instanceId }, options.scope),
|
|
7278
|
-
until: (result) => TERMINAL_STATUSES.has(result.status),
|
|
7279
|
-
getStatus: (result) => result.status,
|
|
7280
|
-
label: `activate ${deploymentName}`,
|
|
7281
|
-
logPrefix: "activate",
|
|
7282
|
-
timeoutMs: options.timeoutSeconds * 1000,
|
|
7283
|
-
intervalMs: options.pollIntervalMs,
|
|
7284
|
-
signal: options.signal ?? processContext.pollSignal
|
|
7285
|
-
});
|
|
7286
|
-
if (pollResult.outcome !== PollOutcome.Completed || !pollResult.data) {
|
|
7287
|
-
return { kind: "PollFailed", poll: pollResult };
|
|
7288
|
-
}
|
|
7289
|
-
const finalStatus = pollResult.data;
|
|
7290
|
-
if (finalStatus.status !== "SuccessfulActivate") {
|
|
7291
|
-
const errorMessage = coerceWorkflowErrorMessages(finalStatus.errorMessage).map((e) => e.errorMessage).join(", ") || "Unknown error";
|
|
7292
|
-
return {
|
|
7293
|
-
kind: "ActivationFailed",
|
|
7294
|
-
status: finalStatus.status,
|
|
7295
|
-
instanceId,
|
|
7296
|
-
errorMessage
|
|
7297
|
-
};
|
|
7298
|
-
}
|
|
7299
|
-
return {
|
|
7300
|
-
kind: "Success",
|
|
7301
|
-
status: finalStatus.status,
|
|
7302
|
-
instanceId
|
|
7303
|
-
};
|
|
7304
|
-
}
|
|
7305
|
-
|
|
7306
|
-
// src/services/deploy-activate-service.ts
|
|
7307
|
-
var fail = (reason, message, instructions, exitCode = 1) => ({
|
|
7308
|
-
ok: false,
|
|
7309
|
-
reason,
|
|
7310
|
-
message,
|
|
7311
|
-
instructions,
|
|
7312
|
-
exitCode
|
|
7313
|
-
});
|
|
7314
|
-
var AUTH_INSTRUCTIONS = "Run 'uip login' to refresh credentials, then retry activation. If the deployment is in a different tenant, switch with 'uip login tenant set <tenant>'.";
|
|
7315
|
-
async function incompleteSweepRefusalAsync(deploymentName, skipped, result) {
|
|
7316
|
-
const details = `Details: ${result.details}`;
|
|
7317
|
-
if (!isNameOrFeedRefusal(result.errorCode, result.httpStatus)) {
|
|
7318
|
-
return {
|
|
7319
|
-
...fail("request_failed", result.message, `The activation request failed. ${retryAdvice(result.errorCode, result.retry, "Orchestrator")} ${details}`),
|
|
7320
|
-
errorCode: result.errorCode,
|
|
7321
|
-
retry: result.retry
|
|
7322
|
-
};
|
|
7323
|
-
}
|
|
7324
|
-
const report = await reportIncompleteSweepAsync(deploymentName, skipped);
|
|
7325
|
-
return {
|
|
7326
|
-
...fail("request_failed", report.message, `${INCOMPLETE_SWEEP_ADVICE} Without its feed the activation went to the tenant feed, which refused it. ${report.nextStep} ${details} (feed search: ${report.details})`),
|
|
7327
|
-
errorCode: report.errorCode,
|
|
7328
|
-
retry: report.retry
|
|
7329
|
-
};
|
|
7330
|
-
}
|
|
7331
|
-
async function activateDeploymentAsync(deploymentName, options = {}) {
|
|
7332
|
-
const [authError, auth] = await catchError(getSolutionAuthContext({
|
|
7333
|
-
tenant: options.tenant,
|
|
7334
|
-
loginValidity: options.loginValidity,
|
|
7335
|
-
envFilePath: options.envFilePath
|
|
7336
|
-
}));
|
|
7337
|
-
if (authError) {
|
|
7338
|
-
return fail("auth_failed", authError.message, AUTH_INSTRUCTIONS);
|
|
7339
|
-
}
|
|
7340
|
-
const sweep = await findDeploymentAcrossFeeds(auth, deploymentName, {
|
|
7341
|
-
tenant: options.tenant,
|
|
7342
|
-
loginValidity: options.loginValidity,
|
|
7343
|
-
envFilePath: options.envFilePath
|
|
7344
|
-
});
|
|
7345
|
-
const location = sweep.location;
|
|
7346
|
-
const result = await activateDeployment(auth, deploymentName, {
|
|
7347
|
-
timeoutSeconds: options.timeout ?? 360,
|
|
7348
|
-
pollIntervalMs: options.pollInterval ?? 5000,
|
|
7349
|
-
signal: options.signal,
|
|
7350
|
-
scope: location?.scope
|
|
7351
|
-
});
|
|
7352
|
-
if (result.kind === "RequestFailed") {
|
|
7353
|
-
const details = `Details: ${result.details}`;
|
|
7354
|
-
const known = result.deployment ?? location?.deployment;
|
|
7355
|
-
if (!known && !sweep.complete) {
|
|
7356
|
-
return incompleteSweepRefusalAsync(deploymentName, sweep.skipped, result);
|
|
7357
|
-
}
|
|
7358
|
-
const pendingResources = known && needsPendingResources(known) ? await readPendingResourcesAsync(new DeploymentsApi(new Configuration({
|
|
7359
|
-
basePath: auth.basePath,
|
|
7360
|
-
accessToken: auth.accessToken
|
|
7361
|
-
})), known.key, location?.scope) : undefined;
|
|
7362
|
-
const feedSelector = feedSelectorFlag(location?.feed);
|
|
7363
|
-
const explanation = known ? explainRefusal(known, pendingResources, feedSelector) : undefined;
|
|
7364
|
-
const instructions = explanation ? [...explanation, details].join(`
|
|
7365
|
-
`) : known ? `Deployment '${known.name}' exists (Operation: ${known.operation}, OperationStatus: ${known.operationStatus}, ActivationStatus: ${known.activationStatus}) but the service refused to activate it. Check it with: uip solution deploy status ${known.key}${feedSelector}. ${details}` : result.phase === "preActivateSteps" ? `Check deployment name. Deploy first with: uip solution deploy run. ${details}` : `Check deployment name matches an existing deployment. ${details}`;
|
|
7366
|
-
return fail("request_failed", result.message, instructions);
|
|
7367
|
-
}
|
|
7368
|
-
if (result.kind === "NoInstance") {
|
|
7369
|
-
return {
|
|
7370
|
-
ok: true,
|
|
7371
|
-
status: "Activation completed (no instance to poll)",
|
|
7372
|
-
deploymentName
|
|
7373
|
-
};
|
|
7374
|
-
}
|
|
7375
|
-
if (result.kind === "PollFailed") {
|
|
7376
|
-
const { reason, message, exitCode } = mapPollFailure(result.poll, "Activation");
|
|
7377
|
-
return fail(reason, message, "Activation may still be in progress.", exitCode);
|
|
7378
|
-
}
|
|
7379
|
-
if (result.kind === "ActivationFailed") {
|
|
7380
|
-
return fail("activation_failed", `Activation failed with status: ${result.status}`, result.errorMessage);
|
|
7381
|
-
}
|
|
7382
|
-
return {
|
|
7383
|
-
ok: true,
|
|
7384
|
-
status: result.status,
|
|
7385
|
-
deploymentName,
|
|
7386
|
-
instanceId: result.instanceId
|
|
7387
|
-
};
|
|
7388
|
-
}
|
|
7389
|
-
|
|
7390
|
-
// src/services/folder-helper.ts
|
|
7391
|
-
async function resolveParentFolder(options) {
|
|
7392
|
-
if (!options.folderPath && !options.folderKey && !options.personalWorkspace) {
|
|
7393
|
-
return;
|
|
7394
|
-
}
|
|
7395
|
-
if (options.personalWorkspace) {
|
|
7396
|
-
const [pwError, pw] = await catchError(resolvePersonalWorkspace({
|
|
7397
|
-
tenant: options.tenant,
|
|
7398
|
-
loginValidity: options.loginValidity,
|
|
7399
|
-
envFilePath: options.envFilePath
|
|
7400
|
-
}));
|
|
7401
|
-
if (pwError) {
|
|
7402
|
-
throw new Error(`Failed to resolve Personal Workspace: ${pwError.message}`);
|
|
7403
|
-
}
|
|
7404
|
-
return pw.name;
|
|
7405
|
-
}
|
|
7406
|
-
if (options.folderPath) {
|
|
7407
|
-
return options.folderPath;
|
|
7408
|
-
}
|
|
7409
|
-
const [resolveError, resolved] = await catchError(resolveFolder({ folderKey: options.folderKey }, {
|
|
7410
|
-
tenant: options.tenant,
|
|
7411
|
-
loginValidity: options.loginValidity,
|
|
7412
|
-
envFilePath: options.envFilePath
|
|
7413
|
-
}));
|
|
7414
|
-
if (resolveError) {
|
|
7415
|
-
throw new Error(`Failed to resolve folder key '${options.folderKey}': ${resolveError.message}`);
|
|
7416
|
-
}
|
|
7417
|
-
if (!resolved) {
|
|
7418
|
-
throw new Error(`Folder not found for key '${options.folderKey}'.`);
|
|
7419
|
-
}
|
|
7420
|
-
return resolved.path;
|
|
7421
|
-
}
|
|
7422
|
-
async function resolveFolderInfo(options) {
|
|
7423
|
-
if (!options.folderPath && !options.folderKey) {
|
|
7424
|
-
return;
|
|
7425
|
-
}
|
|
7426
|
-
const [resolveError, resolved] = await catchError(resolveFolder({ folderPath: options.folderPath, folderKey: options.folderKey }, {
|
|
7427
|
-
tenant: options.tenant,
|
|
7428
|
-
loginValidity: options.loginValidity,
|
|
7429
|
-
envFilePath: options.envFilePath
|
|
7430
|
-
}));
|
|
7431
|
-
if (resolveError) {
|
|
7432
|
-
throw new Error(`Failed to resolve folder '${options.folderPath ?? options.folderKey}': ${resolveError.message}`);
|
|
7433
|
-
}
|
|
7434
|
-
if (!resolved) {
|
|
7435
|
-
throw new Error(`Folder not found: '${options.folderPath ?? options.folderKey}'.`);
|
|
7436
|
-
}
|
|
7437
|
-
return { key: resolved.key, path: resolved.path };
|
|
7438
|
-
}
|
|
7439
|
-
|
|
7440
|
-
// src/services/search-failure.ts
|
|
7441
|
-
async function describeSearchFailureAsync(error, what, session, { userSessionsOnly }) {
|
|
7442
|
-
const details = await extractErrorDetails(error);
|
|
7443
|
-
if (userSessionsOnly && details.context?.httpStatus === 401 && classifyFeedSession(session) === "application") {
|
|
7444
|
-
return {
|
|
7445
|
-
message: `Failed to list ${what}: Solution Search accepts user sessions only, and this session is an external app.`,
|
|
7446
|
-
instructions: `Run it with a user session ('uip login'). A client-credentials login cannot list solution ${what}.`,
|
|
7447
|
-
errorCode: "permission_denied",
|
|
7448
|
-
retry: "RetryWillNotFix",
|
|
7449
|
-
context: details.context
|
|
7450
|
-
};
|
|
7451
|
-
}
|
|
7452
|
-
return {
|
|
7453
|
-
message: `Failed to list ${what}: ${details.message}`,
|
|
7454
|
-
instructions: searchFailureInstructions(details.errorCode, details.retry),
|
|
7455
|
-
errorCode: details.errorCode,
|
|
7456
|
-
retry: details.retry,
|
|
7457
|
-
context: details.context
|
|
7458
|
-
};
|
|
7459
|
-
}
|
|
7460
|
-
function searchFailureInstructions(errorCode, retry) {
|
|
7461
|
-
if (errorCode === "authentication_required") {
|
|
7462
|
-
return "Run 'uip login' to refresh the session, then run the command again.";
|
|
7463
|
-
}
|
|
7464
|
-
if (errorCode === "permission_denied") {
|
|
7465
|
-
return "Use an account that can read Automation Solutions in this tenant.";
|
|
7466
|
-
}
|
|
7467
|
-
if (retry === "RetryLater") {
|
|
7468
|
-
return "Wait a moment, then run the command again.";
|
|
7469
|
-
}
|
|
7470
|
-
return "Check the options and the session ('uip login status --detailed'), then run the command again.";
|
|
7471
|
-
}
|
|
7472
|
-
|
|
7473
|
-
// src/services/deploy-list-service.ts
|
|
7474
|
-
var fail2 = (reason, message, instructions, extras = {}) => ({
|
|
7475
|
-
ok: false,
|
|
7476
|
-
reason,
|
|
7477
|
-
message,
|
|
7478
|
-
instructions,
|
|
7479
|
-
exitCode: 1,
|
|
7480
|
-
...extras
|
|
7481
|
-
});
|
|
7482
|
-
var refuseFeedRead = (refusal) => fail2("feed_requires_user_session", refusal.message, refusal.instructions, {
|
|
7483
|
-
errorCode: "permission_denied",
|
|
7484
|
-
retry: "RetryWillNotFix"
|
|
7485
|
-
});
|
|
7486
|
-
async function listDeploymentsAsync(options = {}) {
|
|
7487
|
-
const limit = options.limit ?? DEFAULT_PAGE_SIZE;
|
|
7488
|
-
const offset = options.offset ?? 0;
|
|
7489
|
-
const [authError, auth] = await catchError(getSolutionAuthContext({
|
|
7490
|
-
tenant: options.tenant,
|
|
7491
|
-
loginValidity: options.loginValidity,
|
|
7492
|
-
envFilePath: options.envFilePath
|
|
7493
|
-
}));
|
|
7494
|
-
if (authError) {
|
|
7495
|
-
return fail2("auth_failed", authError.message, authError.message);
|
|
7496
|
-
}
|
|
7497
|
-
if (options.personalWorkspace) {
|
|
7498
|
-
const refusal = feedReadRefusalForApplication(auth, "Listing the Personal Workspace's deployments");
|
|
7499
|
-
if (refusal) {
|
|
7500
|
-
return refuseFeedRead(refusal);
|
|
7501
|
-
}
|
|
7502
|
-
}
|
|
7503
|
-
const [folderError, folderPathFilter] = await catchError(resolveParentFolder({
|
|
7504
|
-
folderPath: options.folderPath,
|
|
7505
|
-
folderKey: options.folderKey,
|
|
7506
|
-
tenant: options.tenant,
|
|
7507
|
-
loginValidity: options.loginValidity,
|
|
7508
|
-
envFilePath: options.envFilePath
|
|
7509
|
-
}));
|
|
7510
|
-
if (folderError) {
|
|
7511
|
-
return fail2("folder_resolution_failed", folderError.message, "Provide a valid --folder-path or --folder-key to filter by folder.");
|
|
7512
|
-
}
|
|
7513
|
-
const [scopeError, scope] = await catchError(resolveFeedScope({
|
|
7514
|
-
personalWorkspace: options.personalWorkspace,
|
|
7515
|
-
feed: options.feed,
|
|
7516
|
-
tenant: options.tenant,
|
|
7517
|
-
loginValidity: options.loginValidity,
|
|
7518
|
-
envFilePath: options.envFilePath
|
|
7519
|
-
}));
|
|
7520
|
-
if (scopeError) {
|
|
7521
|
-
const { message, instructions, ...extras } = await describeFeedResolutionFailureAsync(scopeError, options, auth);
|
|
7522
|
-
return fail2("feed_resolution_failed", message, instructions, extras);
|
|
7523
|
-
}
|
|
7524
|
-
if (scope.kind !== "tenant") {
|
|
7525
|
-
const refusal = feedReadRefusalForApplication(auth, `Listing the deployments of the feed '${scope.name ?? scope.folderKey}'`);
|
|
7526
|
-
if (refusal) {
|
|
7527
|
-
return refuseFeedRead(refusal);
|
|
7528
|
-
}
|
|
7529
|
-
}
|
|
7530
|
-
const [listError, result] = await catchError(searchDeploymentsPage(auth, {
|
|
7531
|
-
take: limit,
|
|
7532
|
-
skip: offset,
|
|
7533
|
-
orderByColumn: options.sortBy ?? "startTime",
|
|
7534
|
-
orderByDirection: options.sortOrder ?? "Descending",
|
|
7535
|
-
operationStatuses: options.operationStatuses ?? [],
|
|
7536
|
-
activationStatuses: options.activationStatuses ?? [],
|
|
7537
|
-
...folderPathFilter ? { targetFolderName: folderPathFilter } : {}
|
|
7538
|
-
}, feedScopeInitOverride(scope)));
|
|
7539
|
-
if (listError instanceof DeploymentSearchNeedsUserSessionError) {
|
|
7540
|
-
return fail2("list_request_failed", `Failed to list deployments: ${listError.message}`, "Run it with a user session ('uip login'). A client-credentials login cannot list deployments on this server.", { errorCode: "permission_denied", retry: "RetryWillNotFix" });
|
|
7541
|
-
}
|
|
7542
|
-
if (listError) {
|
|
7543
|
-
const { message, instructions, ...extras } = await describeSearchFailureAsync(listError, "deployments", auth, {
|
|
7544
|
-
userSessionsOnly: false
|
|
7545
|
-
});
|
|
7546
|
-
return fail2("list_request_failed", message, instructions, extras);
|
|
7547
|
-
}
|
|
7548
|
-
const values = result.values ?? [];
|
|
7549
|
-
const deployments = values.map((d) => ({
|
|
7550
|
-
key: d.key,
|
|
7551
|
-
installDeploymentKey: d.installDeploymentKey,
|
|
7552
|
-
name: d.name,
|
|
7553
|
-
packageName: d.packageName,
|
|
7554
|
-
packageVersion: d.packageVersion,
|
|
7555
|
-
currentPackageVersion: d.currentPackageVersion,
|
|
7556
|
-
targetPackageVersion: d.targetPackageVersion,
|
|
7557
|
-
newPackageVersionAvailable: d.newPackageVersionAvailable,
|
|
7558
|
-
operation: d.operation,
|
|
7559
|
-
operationStatus: d.operationStatus,
|
|
7560
|
-
activationStatus: d.activationStatus,
|
|
7561
|
-
folderPath: d.folderPath,
|
|
7562
|
-
installedRootFolderKey: d.installedRootFolderKey,
|
|
7563
|
-
deploymentCreationTime: d.deploymentCreationTime,
|
|
7564
|
-
actions: d.actions ?? []
|
|
7565
|
-
}));
|
|
7566
|
-
return { ok: true, deployments, limit, offset, total: result.count };
|
|
7567
|
-
}
|
|
7568
|
-
|
|
7569
7029
|
// ../../node_modules/yaml/dist/index.js
|
|
7570
7030
|
var composer = require_composer();
|
|
7571
7031
|
var Document = require_Document();
|
|
@@ -7612,132 +7072,6 @@ var $stringify = publicApi.stringify;
|
|
|
7612
7072
|
var $visit = visit.visit;
|
|
7613
7073
|
var $visitAsync = visit.visitAsync;
|
|
7614
7074
|
|
|
7615
|
-
// src/services/deployment-validation.ts
|
|
7616
|
-
var NO_SERVER_REASON = "the server reported no reason.";
|
|
7617
|
-
var LOOKUP_TIMEOUT_MS = 15000;
|
|
7618
|
-
function boundedScope(scope, signal) {
|
|
7619
|
-
const deadline = AbortSignal.timeout(LOOKUP_TIMEOUT_MS);
|
|
7620
|
-
const abort = signal ? AbortSignal.any([signal, deadline]) : deadline;
|
|
7621
|
-
return async (requestContext) => ({
|
|
7622
|
-
...await scope?.(requestContext),
|
|
7623
|
-
signal: abort
|
|
7624
|
-
});
|
|
7625
|
-
}
|
|
7626
|
-
async function describeValidationFailureAsync(deploymentsApi, deploymentKey, deploymentAction, scope, signal) {
|
|
7627
|
-
const [error, validation] = await catchError(deploymentsApi.deploymentsGetValidationResult({ deploymentKey, deploymentAction }, boundedScope(scope, signal)));
|
|
7628
|
-
if (error || !validation) {
|
|
7629
|
-
return NO_SERVER_REASON;
|
|
7630
|
-
}
|
|
7631
|
-
const messages = [
|
|
7632
|
-
...validation.validationErrors.map((item) => item.text || item.resource),
|
|
7633
|
-
...validation.resourceValidationErrors.flatMap((resource) => resource.errors.map((item) => item.text || item.resource))
|
|
7634
|
-
].filter(Boolean);
|
|
7635
|
-
return messages.length > 0 ? messages.join("; ") : NO_SERVER_REASON;
|
|
7636
|
-
}
|
|
7637
|
-
async function describeDeploymentFailureAsync(auth, deployment, deploymentAction, scope, signal) {
|
|
7638
|
-
const deploymentsApi = new DeploymentsApi(new Configuration({
|
|
7639
|
-
basePath: auth.basePath,
|
|
7640
|
-
accessToken: auth.accessToken
|
|
7641
|
-
}));
|
|
7642
|
-
const keys = [deployment.key, deployment.installDeploymentKey].filter((key, index, all) => Boolean(key) && all.indexOf(key) === index);
|
|
7643
|
-
for (const key of keys) {
|
|
7644
|
-
const reason = await describeValidationFailureAsync(deploymentsApi, key, deploymentAction, scope, signal);
|
|
7645
|
-
if (reason !== NO_SERVER_REASON) {
|
|
7646
|
-
return reason;
|
|
7647
|
-
}
|
|
7648
|
-
}
|
|
7649
|
-
return NO_SERVER_REASON;
|
|
7650
|
-
}
|
|
7651
|
-
|
|
7652
|
-
// src/services/pipeline-deploy-poll.ts
|
|
7653
|
-
var PIPELINE_TERMINAL_STATUSES = new Set([
|
|
7654
|
-
"DeploymentSucceeded",
|
|
7655
|
-
"DeploymentFailed",
|
|
7656
|
-
"ValidationFailed",
|
|
7657
|
-
"ConflictFixingError",
|
|
7658
|
-
"DeploymentScheduleError"
|
|
7659
|
-
]);
|
|
7660
|
-
var NO_ERRORS = {
|
|
7661
|
-
validationResult: { validationErrors: [], conflictErrors: [] },
|
|
7662
|
-
conflictFixingErrors: [],
|
|
7663
|
-
deploymentScheduleErrors: []
|
|
7664
|
-
};
|
|
7665
|
-
function stillInFlight(deploymentKey) {
|
|
7666
|
-
return {
|
|
7667
|
-
status: "DeploymentInProgress",
|
|
7668
|
-
deploymentKey: deploymentKey ?? "",
|
|
7669
|
-
configurationKey: "",
|
|
7670
|
-
...NO_ERRORS
|
|
7671
|
-
};
|
|
7672
|
-
}
|
|
7673
|
-
async function readOutcomeByKeyAsync(api, deploymentKey) {
|
|
7674
|
-
const [error, info] = await catchError(() => api.pipelinesGetDeploymentByKey({ key: deploymentKey }));
|
|
7675
|
-
if (error || !info) {
|
|
7676
|
-
return;
|
|
7677
|
-
}
|
|
7678
|
-
if (info.deploymentKey !== deploymentKey) {
|
|
7679
|
-
return;
|
|
7680
|
-
}
|
|
7681
|
-
if (info.operation === "Uninstall" || info.operationStatus === "Draft") {
|
|
7682
|
-
return stillInFlight(deploymentKey);
|
|
7683
|
-
}
|
|
7684
|
-
const status = mapOperationStatusToPipelineStatus(info.operationStatus);
|
|
7685
|
-
if (!status) {
|
|
7686
|
-
return stillInFlight(deploymentKey);
|
|
7687
|
-
}
|
|
7688
|
-
return {
|
|
7689
|
-
status,
|
|
7690
|
-
deploymentKey: info.deploymentKey,
|
|
7691
|
-
configurationKey: "",
|
|
7692
|
-
...NO_ERRORS,
|
|
7693
|
-
synthesizedOperation: info.operation
|
|
7694
|
-
};
|
|
7695
|
-
}
|
|
7696
|
-
async function pollPipelineDeploymentAsync(api, auth, options) {
|
|
7697
|
-
let observedDeploymentKey;
|
|
7698
|
-
return pollUntil({
|
|
7699
|
-
fn: async () => {
|
|
7700
|
-
try {
|
|
7701
|
-
const status = await api.pipelinesGetPipelineDeploymentStatus({ pipelineDeploymentId: options.pipelineDeploymentId }, options.scope);
|
|
7702
|
-
if (status.deploymentKey) {
|
|
7703
|
-
observedDeploymentKey = status.deploymentKey;
|
|
7704
|
-
}
|
|
7705
|
-
return status;
|
|
7706
|
-
} catch (err) {
|
|
7707
|
-
if (!await isPipelineDeploymentNotFoundError(err)) {
|
|
7708
|
-
throw err;
|
|
7709
|
-
}
|
|
7710
|
-
if (!observedDeploymentKey) {
|
|
7711
|
-
return stillInFlight(undefined);
|
|
7712
|
-
}
|
|
7713
|
-
const byKey = await readOutcomeByKeyAsync(api, observedDeploymentKey);
|
|
7714
|
-
if (byKey) {
|
|
7715
|
-
return byKey;
|
|
7716
|
-
}
|
|
7717
|
-
const deployment = await findDeploymentBestEffort(auth, options.deploymentName, options.scope, { deploymentKey: observedDeploymentKey });
|
|
7718
|
-
if (!deployment || deployment.operationStatus === "Draft") {
|
|
7719
|
-
return stillInFlight(observedDeploymentKey);
|
|
7720
|
-
}
|
|
7721
|
-
const synthesized = deploymentToTerminalPipelineResult(deployment);
|
|
7722
|
-
if (!synthesized) {
|
|
7723
|
-
return stillInFlight(observedDeploymentKey);
|
|
7724
|
-
}
|
|
7725
|
-
return {
|
|
7726
|
-
...synthesized,
|
|
7727
|
-
synthesizedOperation: deployment.operation
|
|
7728
|
-
};
|
|
7729
|
-
}
|
|
7730
|
-
},
|
|
7731
|
-
until: (result) => PIPELINE_TERMINAL_STATUSES.has(result.status),
|
|
7732
|
-
getStatus: (result) => result.status,
|
|
7733
|
-
label: `deployment ${options.pipelineDeploymentId}`,
|
|
7734
|
-
logPrefix: options.logPrefix,
|
|
7735
|
-
timeoutMs: options.timeoutMs,
|
|
7736
|
-
intervalMs: options.intervalMs,
|
|
7737
|
-
signal: options.signal
|
|
7738
|
-
});
|
|
7739
|
-
}
|
|
7740
|
-
|
|
7741
7075
|
// src/services/deploy-run-service.ts
|
|
7742
7076
|
var PROCESS_RESOURCE_MAPPING_ERROR = /(?:AgentProcessResource|FlowProcessResource)\s*->\s*ReleaseDto/;
|
|
7743
7077
|
var PROCESS_KEY_MAPPING_ERROR = /Destination Member:\s*ProcessKey|Invalid argument 'Key'/;
|
|
@@ -7766,7 +7100,7 @@ function parseConfiguration(content) {
|
|
|
7766
7100
|
}
|
|
7767
7101
|
return yamlConfiguration;
|
|
7768
7102
|
}
|
|
7769
|
-
var
|
|
7103
|
+
var fail = (reason, message, instructions, extras = {}) => ({
|
|
7770
7104
|
ok: false,
|
|
7771
7105
|
reason,
|
|
7772
7106
|
message,
|
|
@@ -7774,8 +7108,34 @@ var fail3 = (reason, message, instructions, extras = {}) => ({
|
|
|
7774
7108
|
exitCode: extras.exitCode ?? 1,
|
|
7775
7109
|
pipelineDeploymentId: extras.pipelineDeploymentId,
|
|
7776
7110
|
errorCode: extras.errorCode,
|
|
7777
|
-
retry: extras.retry
|
|
7111
|
+
retry: extras.retry,
|
|
7112
|
+
...extras.deploymentKey !== undefined && {
|
|
7113
|
+
deploymentKey: extras.deploymentKey
|
|
7114
|
+
},
|
|
7115
|
+
...extras.permanentDeletionResources !== undefined && {
|
|
7116
|
+
permanentDeletionResources: extras.permanentDeletionResources
|
|
7117
|
+
},
|
|
7118
|
+
...extras.permanentlyDeletedResources !== undefined && {
|
|
7119
|
+
permanentlyDeletedResources: extras.permanentlyDeletedResources
|
|
7120
|
+
}
|
|
7778
7121
|
});
|
|
7122
|
+
var failPermanentDeletion = (refusal, pipelineDeploymentId, deploymentKey) => fail(refusal.reason, refusal.message, refusal.instructions, {
|
|
7123
|
+
...refusal.classification,
|
|
7124
|
+
pipelineDeploymentId,
|
|
7125
|
+
deploymentKey,
|
|
7126
|
+
permanentDeletionResources: refusal.resources
|
|
7127
|
+
});
|
|
7128
|
+
async function readInstalledFolderAsync(auth, deploymentName, deploymentKey, scope) {
|
|
7129
|
+
if (deploymentKey) {
|
|
7130
|
+
const [, info] = await catchError(readDeploymentByKeyAsync(auth, deploymentKey, { scope }));
|
|
7131
|
+
if (info?.deploymentKey === deploymentKey && info.installedRootFolderKey) {
|
|
7132
|
+
return { installedRootFolderKey: info.installedRootFolderKey };
|
|
7133
|
+
}
|
|
7134
|
+
}
|
|
7135
|
+
return findDeploymentBestEffort(auth, deploymentName, scope, {
|
|
7136
|
+
deploymentKey
|
|
7137
|
+
});
|
|
7138
|
+
}
|
|
7779
7139
|
function makeFolderKeyResolver(options) {
|
|
7780
7140
|
return async (folderKey) => {
|
|
7781
7141
|
const folder = await resolveFolder({ folderKey }, {
|
|
@@ -7793,7 +7153,7 @@ async function deployRunAsync(options) {
|
|
|
7793
7153
|
envFilePath: options.envFilePath
|
|
7794
7154
|
}));
|
|
7795
7155
|
if (authError) {
|
|
7796
|
-
return
|
|
7156
|
+
return fail("auth_failed", authError.message, authError.message);
|
|
7797
7157
|
}
|
|
7798
7158
|
let feedScope = { kind: "tenant" };
|
|
7799
7159
|
if (options.personalWorkspace || options.feed !== undefined) {
|
|
@@ -7811,7 +7171,7 @@ async function deployRunAsync(options) {
|
|
|
7811
7171
|
envFilePath: options.envFilePath
|
|
7812
7172
|
}));
|
|
7813
7173
|
if (scopeError) {
|
|
7814
|
-
return
|
|
7174
|
+
return fail(options.feed !== undefined ? "feed_resolution_failed" : "personal_workspace_deploy_failed", scopeError.message, "List the feeds you can deploy from with: uip solution feeds list.");
|
|
7815
7175
|
}
|
|
7816
7176
|
feedScope = scope2;
|
|
7817
7177
|
if (feedScope.kind !== "tenant") {
|
|
@@ -7829,7 +7189,7 @@ async function deployRunAsync(options) {
|
|
|
7829
7189
|
if (feedScope.kind !== "tenant") {
|
|
7830
7190
|
const [locationError, location] = await catchError(resolveFeedDeployLocation(feedScope, options));
|
|
7831
7191
|
if (locationError) {
|
|
7832
|
-
return
|
|
7192
|
+
return fail("location_outside_feed", locationError.message, "Pass a --parent-folder-path / --parent-folder-key inside the feed folder, or omit it to deploy into the feed folder itself.");
|
|
7833
7193
|
}
|
|
7834
7194
|
parentFolderPath = location.folderFQN || undefined;
|
|
7835
7195
|
} else {
|
|
@@ -7842,7 +7202,7 @@ async function deployRunAsync(options) {
|
|
|
7842
7202
|
envFilePath: options.envFilePath
|
|
7843
7203
|
}));
|
|
7844
7204
|
if (folderError) {
|
|
7845
|
-
return
|
|
7205
|
+
return fail("folder_resolution_failed", folderError.message, "Provide a valid --parent-folder-path, --parent-folder-key, or --personal-workspace.");
|
|
7846
7206
|
}
|
|
7847
7207
|
parentFolderPath = resolved;
|
|
7848
7208
|
}
|
|
@@ -7853,7 +7213,7 @@ async function deployRunAsync(options) {
|
|
|
7853
7213
|
packageName: options.packageName,
|
|
7854
7214
|
packageVersion: options.packageVersion
|
|
7855
7215
|
};
|
|
7856
|
-
const configuration = new
|
|
7216
|
+
const configuration = new Configuration({
|
|
7857
7217
|
basePath: auth.basePath,
|
|
7858
7218
|
accessToken: auth.accessToken
|
|
7859
7219
|
});
|
|
@@ -7864,45 +7224,87 @@ async function deployRunAsync(options) {
|
|
|
7864
7224
|
const configPath = fs.path.resolve(options.configFile);
|
|
7865
7225
|
const [readError, configContent] = await catchError(fs.readFile(configPath, "utf-8"));
|
|
7866
7226
|
if (readError) {
|
|
7867
|
-
return
|
|
7227
|
+
return fail("config_file_read_failed", `Failed to read config file: ${configPath}`, readError.message);
|
|
7868
7228
|
}
|
|
7869
7229
|
if (configContent === null) {
|
|
7870
|
-
return
|
|
7230
|
+
return fail("config_file_not_found", `Failed to read config file: ${configPath}`, `File not found at ${configPath}. Check the --config-file path; generate a default config with: uip solution deploy config get <name> -d config.json.`);
|
|
7871
7231
|
}
|
|
7872
7232
|
const [parseError, parsed] = catchError(() => parseConfiguration(configContent));
|
|
7873
7233
|
if (parseError) {
|
|
7874
|
-
return
|
|
7234
|
+
return fail("config_file_parse_failed", `Invalid JSON or YAML in config file: ${configPath}`, parseError.message);
|
|
7875
7235
|
}
|
|
7876
7236
|
configBody = parsed;
|
|
7877
7237
|
}
|
|
7878
|
-
const
|
|
7879
|
-
|
|
7880
|
-
|
|
7881
|
-
|
|
7882
|
-
|
|
7883
|
-
|
|
7884
|
-
|
|
7885
|
-
|
|
7886
|
-
|
|
7887
|
-
|
|
7888
|
-
|
|
7889
|
-
|
|
7890
|
-
|
|
7891
|
-
|
|
7892
|
-
|
|
7893
|
-
|
|
7894
|
-
|
|
7895
|
-
|
|
7896
|
-
|
|
7897
|
-
|
|
7898
|
-
|
|
7899
|
-
|
|
7900
|
-
|
|
7901
|
-
|
|
7902
|
-
|
|
7903
|
-
|
|
7904
|
-
|
|
7905
|
-
|
|
7238
|
+
const timeoutMs = (options.timeout ?? 360) * 1000;
|
|
7239
|
+
let deadline;
|
|
7240
|
+
const installAndPollAsync = async () => {
|
|
7241
|
+
const [installError, installResult] = await catchError(api.pipelinesInstall({
|
|
7242
|
+
deploymentName: options.deploymentName,
|
|
7243
|
+
packageName: options.packageName,
|
|
7244
|
+
packageVersion: options.packageVersion,
|
|
7245
|
+
solutionRootFolderName: options.folderName,
|
|
7246
|
+
folderFullyQualifiedName: parentFolderPath,
|
|
7247
|
+
body: configBody
|
|
7248
|
+
}, scope));
|
|
7249
|
+
if (installError || !installResult?.pipelineDeploymentId) {
|
|
7250
|
+
if (!installError) {
|
|
7251
|
+
return fail(installFailureReason(feedScope), "The install request returned no pipeline deployment.", installFailureHint(feedScope, options));
|
|
7252
|
+
}
|
|
7253
|
+
const detail = await extractErrorDetails(installError);
|
|
7254
|
+
if (hasServerErrorCode(detail.details, DRAFT_VERSION_MISMATCH_CODE)) {
|
|
7255
|
+
return fail("pending_draft", detail.message, `${pendingDraftHint(feedScope, options)} Details: ${detail.details}`, { errorCode: detail.errorCode, retry: detail.retry });
|
|
7256
|
+
}
|
|
7257
|
+
return fail(installFailureReason(feedScope), detail.message, `${installFailureHint(feedScope, options)} Details: ${detail.details}`, { errorCode: detail.errorCode, retry: detail.retry });
|
|
7258
|
+
}
|
|
7259
|
+
const pipelineDeploymentId2 = installResult.pipelineDeploymentId;
|
|
7260
|
+
deadline ??= Date.now() + timeoutMs;
|
|
7261
|
+
const pollResult2 = await pollPipelineDeploymentAsync(api, auth, {
|
|
7262
|
+
pipelineDeploymentId: pipelineDeploymentId2,
|
|
7263
|
+
deploymentName: options.deploymentName,
|
|
7264
|
+
scope,
|
|
7265
|
+
timeoutMs: remainingTimeoutMs(timeoutMs, deadline),
|
|
7266
|
+
intervalMs: options.pollInterval ?? 5000,
|
|
7267
|
+
signal: options.signal,
|
|
7268
|
+
logPrefix: "deploy"
|
|
7269
|
+
});
|
|
7270
|
+
return { ok: true, pipelineDeploymentId: pipelineDeploymentId2, pollResult: pollResult2 };
|
|
7271
|
+
};
|
|
7272
|
+
let attempt = await installAndPollAsync();
|
|
7273
|
+
if (!attempt.ok) {
|
|
7274
|
+
return attempt;
|
|
7275
|
+
}
|
|
7276
|
+
let permanentlyDeletedResources;
|
|
7277
|
+
if (attempt.pollResult.outcome === PollOutcome.Completed && isPermanentDeletionRefusal(attempt.pollResult.data)) {
|
|
7278
|
+
const refused = attempt.pollResult.data;
|
|
7279
|
+
const keepCopiesHint = "remove those links from the --config-file (uip solution deploy config unlink <file> <resource>) and re-run";
|
|
7280
|
+
const consent = await settlePermanentDeletionRefusalAsync({
|
|
7281
|
+
api,
|
|
7282
|
+
deploymentName: options.deploymentName,
|
|
7283
|
+
scope,
|
|
7284
|
+
signal: options.signal,
|
|
7285
|
+
acknowledge: options.acknowledgePermanentDeletion === true,
|
|
7286
|
+
status: refused,
|
|
7287
|
+
verb: "Deploying",
|
|
7288
|
+
confirmHint: `re-run the same command with ${ACKNOWLEDGE_PERMANENT_DELETION_FLAG}`,
|
|
7289
|
+
keepCopiesHint
|
|
7290
|
+
});
|
|
7291
|
+
if (!consent.ok) {
|
|
7292
|
+
return failPermanentDeletion(consent, attempt.pipelineDeploymentId, refused.deploymentKey || undefined);
|
|
7293
|
+
}
|
|
7294
|
+
attempt = await installAndPollAsync();
|
|
7295
|
+
if (!attempt.ok) {
|
|
7296
|
+
return {
|
|
7297
|
+
...attempt,
|
|
7298
|
+
instructions: `${attempt.instructions} ${acknowledgedButNotRunHint(consent.resources, keepCopiesHint)}`
|
|
7299
|
+
};
|
|
7300
|
+
}
|
|
7301
|
+
if (attempt.pollResult.outcome === PollOutcome.Completed && isPermanentDeletionRefusal(attempt.pollResult.data)) {
|
|
7302
|
+
const deploymentKey = attempt.pollResult.data?.deploymentKey || undefined;
|
|
7303
|
+
return failPermanentDeletion(stillRequiresConfirmation(options.deploymentName, consent.resources, deploymentKey), attempt.pipelineDeploymentId, deploymentKey);
|
|
7304
|
+
}
|
|
7305
|
+
permanentlyDeletedResources = consent.resources.map((resource) => formatPermanentDeletionResources([resource]));
|
|
7306
|
+
}
|
|
7307
|
+
const { pipelineDeploymentId, pollResult } = attempt;
|
|
7906
7308
|
const folderPath = parentFolderPath ? `${parentFolderPath}/${options.folderName}` : options.folderName;
|
|
7907
7309
|
if (pollResult.outcome !== PollOutcome.Completed || !pollResult.data) {
|
|
7908
7310
|
const recoveryKey = pollResult.data?.deploymentKey || undefined;
|
|
@@ -7917,6 +7319,9 @@ async function deployRunAsync(options) {
|
|
|
7917
7319
|
return {
|
|
7918
7320
|
ok: true,
|
|
7919
7321
|
...feedFields,
|
|
7322
|
+
...permanentlyDeletedResources && {
|
|
7323
|
+
permanentlyDeletedResources
|
|
7324
|
+
},
|
|
7920
7325
|
status: "DeploymentSucceeded",
|
|
7921
7326
|
deploymentKey: recoveryDeployment?.key,
|
|
7922
7327
|
pipelineDeploymentId,
|
|
@@ -7939,18 +7344,18 @@ async function deployRunAsync(options) {
|
|
|
7939
7344
|
};
|
|
7940
7345
|
}
|
|
7941
7346
|
if (recovery?.kind === "ActivationFailed") {
|
|
7942
|
-
return
|
|
7347
|
+
return fail("activation_failed_post_deploy", `Deployment '${options.deploymentName}' completed but activation failed.`, `Inspect activation details in Orchestrator, then retry with: uip solution deploy activate ${options.deploymentName}${feedSelectorFlag(feedScope)}.`, { pipelineDeploymentId });
|
|
7943
7348
|
}
|
|
7944
7349
|
if (recovery?.kind === "DeployFailed") {
|
|
7945
7350
|
const reason2 = recoveryDeployment ? await describeDeploymentFailureAsync(auth, recoveryDeployment, SolutionDeploymentAction.Install, scope, options.signal) : NO_SERVER_REASON;
|
|
7946
|
-
return
|
|
7351
|
+
return fail("deploy_failed", `Deployment '${options.deploymentName}' failed (OperationStatus: ${recovery.operationStatus}): ${reason2}`, `${inspectHint(pipelineDeploymentId, feedScope)} Fix the underlying issue and retry: uip solution deploy run.`, { pipelineDeploymentId });
|
|
7947
7352
|
}
|
|
7948
7353
|
const { reason, message, exitCode, errorCode, retry } = mapPollFailure(pollResult, "Deployment");
|
|
7949
|
-
return
|
|
7354
|
+
return fail(reason, message, `Deployment may still be in progress. ${followHint(pipelineDeploymentId, feedScope)}`, { exitCode, pipelineDeploymentId, errorCode, retry });
|
|
7950
7355
|
}
|
|
7951
7356
|
const finalStatus = pollResult.data;
|
|
7952
7357
|
if (!finalStatus) {
|
|
7953
|
-
return
|
|
7358
|
+
return fail("no_final_status", "Deployment did not return a final status.", followHint(pipelineDeploymentId, feedScope), { pipelineDeploymentId });
|
|
7954
7359
|
}
|
|
7955
7360
|
const landedDespiteStatus = installLandedDespiteStatus(finalStatus);
|
|
7956
7361
|
if (finalStatus.status !== "DeploymentSucceeded" && !landedDespiteStatus) {
|
|
@@ -7962,11 +7367,9 @@ async function deployRunAsync(options) {
|
|
|
7962
7367
|
const details = finalStatus.synthesizedOperation !== undefined && finalStatus.deploymentKey ? await describeSynthesizedFailureAsync(auth, finalStatus.deploymentKey, scope, options.signal, fromPipeline) : fromPipeline;
|
|
7963
7368
|
const draftNote = leavesPendingDraft(finalStatus.status) ? `
|
|
7964
7369
|
Nothing was installed. The rejected attempt is kept as a pending draft${finalStatus.deploymentKey ? ` (${finalStatus.deploymentKey})` : ""}: fix the configuration and re-run this command, and the server re-validates that draft with the new file (settings and resource links the file does not name keep the values the draft was rejected with).${finalStatus.deploymentKey ? ` When this was an update of an existing deployment, you can discard the draft and upgrade the live version instead: uip solution deploy upgrade ${finalStatus.deploymentKey} --discard-draft --version ${options.packageVersion}` : ""}` : "";
|
|
7965
|
-
return
|
|
7370
|
+
return fail("deploy_failed", `Deployment failed with status: ${finalStatus.status}`, `${buildDeploymentFailureInstructions(details, pipelineDeploymentId)}${draftNote}`, { pipelineDeploymentId, ...classification });
|
|
7966
7371
|
}
|
|
7967
|
-
const resolvedFolder = await resolveInstalledFolder(await
|
|
7968
|
-
deploymentKey: finalStatus.deploymentKey || undefined
|
|
7969
|
-
}), {
|
|
7372
|
+
const resolvedFolder = await resolveInstalledFolder(await readInstalledFolderAsync(auth, options.deploymentName, finalStatus.deploymentKey || undefined, scope), {
|
|
7970
7373
|
folderName: options.folderName,
|
|
7971
7374
|
folderPath,
|
|
7972
7375
|
parentFolderPath
|
|
@@ -7974,6 +7377,7 @@ Nothing was installed. The rejected attempt is kept as a pending draft${finalSta
|
|
|
7974
7377
|
const baseSuccess = {
|
|
7975
7378
|
ok: true,
|
|
7976
7379
|
...feedFields,
|
|
7380
|
+
...permanentlyDeletedResources && { permanentlyDeletedResources },
|
|
7977
7381
|
status: finalStatus.status,
|
|
7978
7382
|
deploymentKey: finalStatus.deploymentKey,
|
|
7979
7383
|
pipelineDeploymentId,
|
|
@@ -7996,6 +7400,12 @@ Nothing was installed. The rejected attempt is kept as a pending draft${finalSta
|
|
|
7996
7400
|
if (options.skipActivate) {
|
|
7997
7401
|
return { ...baseSuccess, activationStatus: "Skipped" };
|
|
7998
7402
|
}
|
|
7403
|
+
if (reportedActivationStatus(finalStatus.deploymentResult) === "NeedsSetupToActivate") {
|
|
7404
|
+
return {
|
|
7405
|
+
...baseSuccess,
|
|
7406
|
+
...await describeInstalledRunAsync(auth, options.deploymentName, finalStatus, scope, feedScope)
|
|
7407
|
+
};
|
|
7408
|
+
}
|
|
7999
7409
|
const activationResult = await activateDeployment(auth, options.deploymentName, {
|
|
8000
7410
|
timeoutSeconds: options.timeout ?? 360,
|
|
8001
7411
|
pollIntervalMs: options.pollInterval ?? 5000,
|
|
@@ -8010,19 +7420,22 @@ Nothing was installed. The rejected attempt is kept as a pending draft${finalSta
|
|
|
8010
7420
|
...await describeInstalledNotLiveAsync(auth, refused, scope, feedScope)
|
|
8011
7421
|
};
|
|
8012
7422
|
}
|
|
8013
|
-
const fallback = activationResult.phase === "preActivateSteps" ? `Deployment '${options.deploymentName}' was deployed successfully but pre-activate steps lookup failed. Retry activation with: uip solution deploy activate ${options.deploymentName}. Details: ${activationResult.details}` : `Deployment '${options.deploymentName}' was deployed successfully but activation failed. Retry activation with: uip solution deploy activate ${options.deploymentName}. Details: ${activationResult.details}`;
|
|
8014
|
-
const pendingResources = refused && needsPendingResources(refused) ? await readPendingResourcesAsync(
|
|
8015
|
-
|
|
8016
|
-
accessToken: auth.accessToken
|
|
8017
|
-
})), refused.key, scope) : undefined;
|
|
8018
|
-
return fail3("activation_request_failed", activationResult.message, appendDeploymentStateInstructions(fallback, refused, pendingResources, feedSelectorFlag(feedScope)), { pipelineDeploymentId });
|
|
7423
|
+
const fallback = activationResult.phase === "preActivateSteps" ? `Deployment '${options.deploymentName}' was deployed successfully but pre-activate steps lookup failed. Retry activation with: uip solution deploy activate ${options.deploymentName}${feedSelectorFlag(feedScope)}. Details: ${activationResult.details}` : `Deployment '${options.deploymentName}' was deployed successfully but activation failed. Retry activation with: uip solution deploy activate ${options.deploymentName}${feedSelectorFlag(feedScope)}. Details: ${activationResult.details}`;
|
|
7424
|
+
const pendingResources = refused && needsPendingResources(refused) ? await readPendingResourcesAsync(pendingResourceApis(auth), refused, scope) : undefined;
|
|
7425
|
+
return fail("activation_request_failed", activationResult.message, appendDeploymentStateInstructions(fallback, refused, pendingResources, feedSelectorFlag(feedScope)), { pipelineDeploymentId, permanentlyDeletedResources });
|
|
8019
7426
|
}
|
|
8020
7427
|
if (activationResult.kind === "PollFailed") {
|
|
8021
7428
|
const { message, exitCode, errorCode, retry } = mapPollFailure(activationResult.poll, "Activation");
|
|
8022
|
-
return
|
|
7429
|
+
return fail("activation_poll_failed", message, `Deployment '${options.deploymentName}' was deployed successfully but activation polling did not complete. Activation may still be in progress; check with: ${listCommand(feedScope)}.`, {
|
|
7430
|
+
exitCode,
|
|
7431
|
+
pipelineDeploymentId,
|
|
7432
|
+
errorCode,
|
|
7433
|
+
retry,
|
|
7434
|
+
permanentlyDeletedResources
|
|
7435
|
+
});
|
|
8023
7436
|
}
|
|
8024
7437
|
if (activationResult.kind === "ActivationFailed") {
|
|
8025
|
-
return
|
|
7438
|
+
return fail("activation_failed", `Activation failed with status: ${activationResult.status}`, activationResult.errorMessage, { pipelineDeploymentId, permanentlyDeletedResources });
|
|
8026
7439
|
}
|
|
8027
7440
|
const activationStatus = activationResult.kind === "Success" ? activationResult.status : "NoInstance";
|
|
8028
7441
|
const activationInstanceId = activationResult.kind === "Success" ? activationResult.instanceId : undefined;
|
|
@@ -8031,33 +7444,31 @@ Nothing was installed. The rejected attempt is kept as a pending draft${finalSta
|
|
|
8031
7444
|
}
|
|
8032
7445
|
async function describeInstalledRunAsync(auth, deploymentName, finalStatus, scope, feedScope) {
|
|
8033
7446
|
const key = finalStatus.deploymentKey || undefined;
|
|
8034
|
-
const
|
|
7447
|
+
const record = finalStatus.deploymentResult;
|
|
7448
|
+
const reported = reportedActivationStatus(record);
|
|
7449
|
+
const row = key && !reported ? await findDeploymentBestEffort(auth, deploymentName, scope, {
|
|
8035
7450
|
deploymentKey: key
|
|
8036
7451
|
}) : undefined;
|
|
8037
7452
|
if (row) {
|
|
8038
7453
|
return describeInstalledNotLiveAsync(auth, row, scope, feedScope);
|
|
8039
7454
|
}
|
|
8040
|
-
const record = finalStatus.deploymentResult;
|
|
8041
7455
|
if (record?.status === "SuccessfulActivate") {
|
|
8042
7456
|
return { activationStatus: "SuccessfulActivate" };
|
|
8043
7457
|
}
|
|
8044
7458
|
const actions = record?.actions ?? [];
|
|
8045
|
-
const activationStatus = actions.includes("SetupActivation") ? "NeedsSetupToActivate" : actions.includes("Activate") ? "ReadyToActivate" : "Inactive";
|
|
7459
|
+
const activationStatus = reported ?? (actions.includes("SetupActivation") ? "NeedsSetupToActivate" : actions.includes("Activate") ? "ReadyToActivate" : "Inactive");
|
|
8046
7460
|
return describeInstalledNotLiveAsync(auth, {
|
|
8047
7461
|
name: deploymentName,
|
|
8048
7462
|
key,
|
|
8049
7463
|
operation: record?.operation ?? finalStatus.synthesizedOperation,
|
|
8050
|
-
operationStatus: "Successful",
|
|
7464
|
+
operationStatus: record?.operationStatus ?? "Successful",
|
|
8051
7465
|
activationStatus,
|
|
8052
7466
|
packageVersion: record?.packageVersion,
|
|
8053
7467
|
currentPackageVersion: record?.packageVersion
|
|
8054
7468
|
}, scope, feedScope);
|
|
8055
7469
|
}
|
|
8056
7470
|
async function describeInstalledNotLiveAsync(auth, deployment, scope, feedScope) {
|
|
8057
|
-
const pendingResources = needsPendingResources(deployment) && deployment.key ? await readPendingResourcesAsync(
|
|
8058
|
-
basePath: auth.basePath,
|
|
8059
|
-
accessToken: auth.accessToken
|
|
8060
|
-
})), deployment.key, scope) : undefined;
|
|
7471
|
+
const pendingResources = needsPendingResources(deployment) && deployment.key ? await readPendingResourcesAsync(pendingResourceApis(auth), { name: deployment.name, key: deployment.key }, scope) : undefined;
|
|
8061
7472
|
const nextSteps = deploymentNextSteps(deployment, pendingResources, feedSelectorFlag(feedScope));
|
|
8062
7473
|
return {
|
|
8063
7474
|
activationStatus: deployment.activationStatus ?? "Inactive",
|
|
@@ -8099,13 +7510,13 @@ function refuseFeedForSession(session, action) {
|
|
|
8099
7510
|
return;
|
|
8100
7511
|
}
|
|
8101
7512
|
const { message, instructions } = feedSessionRefusal(verdict, action, "deploy the package to the tenant feed");
|
|
8102
|
-
return
|
|
7513
|
+
return fail("feed_requires_user_session", message, instructions, {
|
|
8103
7514
|
errorCode: "permission_denied",
|
|
8104
7515
|
retry: "RetryWillNotFix"
|
|
8105
7516
|
});
|
|
8106
7517
|
}
|
|
8107
7518
|
async function describeSynthesizedFailureAsync(auth, deploymentKey, scope, signal, fromPipeline) {
|
|
8108
|
-
const deploymentsApi = new DeploymentsApi(new
|
|
7519
|
+
const deploymentsApi = new DeploymentsApi(new Configuration2({
|
|
8109
7520
|
basePath: auth.basePath,
|
|
8110
7521
|
accessToken: auth.accessToken
|
|
8111
7522
|
}));
|
|
@@ -8163,10 +7574,10 @@ function buildDeploymentExistsInstructions(options) {
|
|
|
8163
7574
|
} else {
|
|
8164
7575
|
parts.push(first?.key ? `To update the existing deployment instead, upgrade it in place — running deploy again does not upgrade it: uip solution deploy upgrade ${first.key}.` : "To update the existing deployment instead, upgrade it in place with 'uip solution deploy upgrade <deployment-key>' — running deploy again does not upgrade it.");
|
|
8165
7576
|
if (first?.name) {
|
|
8166
|
-
parts.push(`To remove it first, run: uip solution deploy uninstall '${first.name}' --yes.`);
|
|
7577
|
+
parts.push(`To remove it first, run: uip solution deploy uninstall '${first.name}'${feedSelectorFlag(scope)} --yes.`);
|
|
8167
7578
|
}
|
|
8168
7579
|
}
|
|
8169
|
-
parts.push(
|
|
7580
|
+
parts.push(`To see every deployment and its state, run: uip solution deploy list${feedSelectorFlag(scope)}.`);
|
|
8170
7581
|
parts.push(scope.kind === "tenant" ? "To create a second, separate deployment anyway, re-run this command with --yes and a different --name: re-using an existing deployment's name updates that deployment in place instead." : "To create a second, separate deployment anyway, re-run with --yes and a different --name (re-using an existing deployment's name updates that deployment in place) — Orchestrator may still refuse it while the existing deployment is running or in a failed state.");
|
|
8171
7582
|
if (existing.length === 0) {
|
|
8172
7583
|
parts.unshift(`A deployment of '${packageName}' already exists in ${scopeLabel(scope)}.`);
|
|
@@ -8205,14 +7616,14 @@ async function guardPendingDraft(auth, options, scope) {
|
|
|
8205
7616
|
}
|
|
8206
7617
|
const draftVersion = draft.targetPackageVersion ?? draft.packageVersion;
|
|
8207
7618
|
if (draft.operation === "ActivationSetup") {
|
|
8208
|
-
return
|
|
7619
|
+
return fail("pending_draft", `Deployment '${options.deploymentName}' has an unfinished Setup activation (${draft.key}): the Orchestrator "Setup activation" wizard was started on version ${draftVersion ?? "<version>"} and not completed.`, `While that draft exists the server would run it in place of this deploy, or refuse a different version. Finish the setup in Orchestrator (Solutions, the deployment, Setup activation); or discard it — in Orchestrator (Delete draft), or with uip solution deploy upgrade ${draft.key} --discard-draft${draft.currentPackageVersion ? ` --version ${draft.currentPackageVersion}` : ""} — then re-run this command.`, { errorCode: "invalid_argument", retry: "RetryWillNotFix" });
|
|
8209
7620
|
}
|
|
8210
7621
|
if (!draftVersion || draftVersion.toLowerCase() === options.packageVersion.toLowerCase()) {
|
|
8211
7622
|
return;
|
|
8212
7623
|
}
|
|
8213
7624
|
const liveVersion = draft.currentPackageVersion;
|
|
8214
7625
|
const discard = draft.operation === "Install" || !liveVersion ? "delete it in Orchestrator (Delete draft)" : `discard it — in Orchestrator (Delete draft), or with uip solution deploy upgrade ${draft.key} --discard-draft --version ${liveVersion}, which also re-applies the live version unchanged —`;
|
|
8215
|
-
return
|
|
7626
|
+
return fail("pending_draft", `Deployment '${options.deploymentName}' has a pending draft (${draft.key}) for version ${draftVersion}: an earlier attempt that never completed, usually one rejected by validation, or one still running.`, `The server reuses that draft for the name, so this request would not deploy ${options.packageVersion}: asking for the live version installs the draft's ${draftVersion} instead, and any other version is refused. To retry the draft with a corrected configuration, re-run with --package-version ${draftVersion}.
|
|
8216
7627
|
To deploy ${options.packageVersion} instead, ${discard} then re-run this command.`, { errorCode: "invalid_argument", retry: "RetryWillNotFix" });
|
|
8217
7628
|
}
|
|
8218
7629
|
async function guardExistingDeployment(auth, options, scope) {
|
|
@@ -8234,7 +7645,7 @@ async function guardExistingDeployment(auth, options, scope) {
|
|
|
8234
7645
|
if (existing.length === 0) {
|
|
8235
7646
|
return;
|
|
8236
7647
|
}
|
|
8237
|
-
return
|
|
7648
|
+
return fail("deployment_exists", buildDeploymentExistsMessage(options.packageName, scope, existing, await resolveDeploymentFolders(existing, options)), buildDeploymentExistsInstructions({
|
|
8238
7649
|
packageName: options.packageName,
|
|
8239
7650
|
scope,
|
|
8240
7651
|
existing,
|
|
@@ -8266,740 +7677,6 @@ async function resolveFeedDeployLocation(scope, options) {
|
|
|
8266
7677
|
return { folderKey: resolved.key, folderFQN: resolved.path };
|
|
8267
7678
|
}
|
|
8268
7679
|
|
|
8269
|
-
|
|
8270
|
-
var TERMINAL_STATUSES2 = new Set([
|
|
8271
|
-
"SuccessfulUninstall",
|
|
8272
|
-
"FailedUninstall"
|
|
8273
|
-
]);
|
|
8274
|
-
var fail4 = (reason, message, instructions, extras = {}) => ({
|
|
8275
|
-
ok: false,
|
|
8276
|
-
reason,
|
|
8277
|
-
message,
|
|
8278
|
-
instructions,
|
|
8279
|
-
exitCode: extras.exitCode ?? 1,
|
|
8280
|
-
errorCode: extras.errorCode,
|
|
8281
|
-
retry: extras.retry
|
|
8282
|
-
});
|
|
8283
|
-
function requestErrorInstructions(deploymentName, errorCode, details) {
|
|
8284
|
-
switch (errorCode) {
|
|
8285
|
-
case "authentication_required":
|
|
8286
|
-
return `Your session may have expired. Run 'uip login' and retry. Details: ${details}`;
|
|
8287
|
-
case "permission_denied":
|
|
8288
|
-
return `Your account lacks permission to uninstall this deployment. Check your Orchestrator roles, then retry. Details: ${details}`;
|
|
8289
|
-
case "rate_limited":
|
|
8290
|
-
return `Too many requests. Wait a moment and retry. Details: ${details}`;
|
|
8291
|
-
case "network_error":
|
|
8292
|
-
return `Could not reach Orchestrator. Check your connection and retry. Details: ${details}`;
|
|
8293
|
-
case "server_error":
|
|
8294
|
-
return `Orchestrator returned a server error. Wait and retry; if it persists, check Orchestrator status. Details: ${details}`;
|
|
8295
|
-
case "not_found":
|
|
8296
|
-
return `No deployment named '${deploymentName}' was found. Run 'uip solution deploy list' to see valid deployment names. Details: ${details}`;
|
|
8297
|
-
default:
|
|
8298
|
-
return `Uninstall request failed. Run 'uip solution deploy list' to check the deployment's state, then retry. Details: ${details}`;
|
|
8299
|
-
}
|
|
8300
|
-
}
|
|
8301
|
-
function buildDeploymentStateInstructions(deployment, details) {
|
|
8302
|
-
const availableActions = deployment.actions?.length ? deployment.actions.join(", ") : "none";
|
|
8303
|
-
const status = `(ActivationStatus: ${deployment.activationStatus}, OperationStatus: ${deployment.operationStatus})`;
|
|
8304
|
-
if (deployment.operationStatus === "InProgress") {
|
|
8305
|
-
return `Deployment '${deployment.name}' has an operation in progress ${status}, so it can't be uninstalled yet. Wait for it to finish — run 'uip solution deploy list' to recheck — then retry. Available actions: ${availableActions}. Details: ${details}`;
|
|
8306
|
-
}
|
|
8307
|
-
if (deployment.actions?.includes("Uninstall")) {
|
|
8308
|
-
return `Deployment '${deployment.name}' lists uninstall as available but Orchestrator rejected the request ${status}. Run 'uip solution deploy list' to recheck its state, then retry. If it stays stuck, uninstall it from the Orchestrator Solutions UI. Details: ${details}`;
|
|
8309
|
-
}
|
|
8310
|
-
const removalAdvice = deployment.actions?.includes(WorkflowAction.Delete) ? `Delete it with: uip solution deploy delete '${deployment.name}' --yes.` : "Remove it from the Orchestrator Solutions UI.";
|
|
8311
|
-
if (deployment.activationStatus === "Inactive") {
|
|
8312
|
-
return `Deployment '${deployment.name}' cannot be uninstalled in its current state ${status}. Available actions: ${availableActions}. Superseded or inactive deployments are never uninstallable. ${removalAdvice} Details: ${details}`;
|
|
8313
|
-
}
|
|
8314
|
-
return `Deployment '${deployment.name}' cannot be uninstalled in its current state ${status}. Available actions: ${availableActions}. Run 'uip solution deploy list' to recheck its state. ${removalAdvice} Details: ${details}`;
|
|
8315
|
-
}
|
|
8316
|
-
async function waitForOperationToFinishAsync(auth, deploymentName, opts) {
|
|
8317
|
-
let last;
|
|
8318
|
-
const poll = await pollUntil({
|
|
8319
|
-
fn: async () => {
|
|
8320
|
-
last = await findDeploymentByName(auth, deploymentName, opts.scope);
|
|
8321
|
-
return last;
|
|
8322
|
-
},
|
|
8323
|
-
until: (deployment) => deployment !== undefined && deployment.operationStatus !== "InProgress",
|
|
8324
|
-
getStatus: (deployment) => deployment?.operationStatus ?? "Unknown",
|
|
8325
|
-
label: `deployment '${deploymentName}' to finish its current operation`,
|
|
8326
|
-
logPrefix: "uninstall",
|
|
8327
|
-
timeoutMs: opts.remainingMs(),
|
|
8328
|
-
intervalMs: opts.intervalMs,
|
|
8329
|
-
signal: opts.signal
|
|
8330
|
-
});
|
|
8331
|
-
return { outcome: poll.outcome, state: last, error: poll.error };
|
|
8332
|
-
}
|
|
8333
|
-
async function requestUninstallAsync(api, auth, deploymentName, ctx) {
|
|
8334
|
-
const { options, sweep, intervalMs, remainingMs } = ctx;
|
|
8335
|
-
const { location } = sweep;
|
|
8336
|
-
const sweepIncomplete = !location && !sweep.complete;
|
|
8337
|
-
let state = location?.deployment;
|
|
8338
|
-
let waited = false;
|
|
8339
|
-
let rechecked = false;
|
|
8340
|
-
for (;; ) {
|
|
8341
|
-
const [uninstallError, result] = await catchError(api.pipelinesUninstall({ deploymentName }, location?.scope));
|
|
8342
|
-
if (!uninstallError) {
|
|
8343
|
-
return { ok: true, result };
|
|
8344
|
-
}
|
|
8345
|
-
const { message, details, errorCode, retry, context } = await extractErrorDetails(uninstallError);
|
|
8346
|
-
if (errorCode !== "invalid_argument") {
|
|
8347
|
-
if (errorCode === "not_found" && sweepIncomplete) {
|
|
8348
|
-
return incompleteSweepFailureAsync(deploymentName, sweep, details);
|
|
8349
|
-
}
|
|
8350
|
-
return fail4("uninstall_request_failed", message, requestErrorInstructions(deploymentName, errorCode, details), { errorCode, retry });
|
|
8351
|
-
}
|
|
8352
|
-
if (!rechecked && !waited && state?.operationStatus !== "InProgress") {
|
|
8353
|
-
rechecked = true;
|
|
8354
|
-
const [readError, fresh] = await catchError(findDeploymentByName(auth, deploymentName, location?.scope));
|
|
8355
|
-
if (!readError) {
|
|
8356
|
-
state = fresh;
|
|
8357
|
-
}
|
|
8358
|
-
}
|
|
8359
|
-
if (!waited && state?.operationStatus === "InProgress") {
|
|
8360
|
-
waited = true;
|
|
8361
|
-
const wait = await waitForOperationToFinishAsync(auth, deploymentName, {
|
|
8362
|
-
scope: location?.scope,
|
|
8363
|
-
intervalMs,
|
|
8364
|
-
remainingMs,
|
|
8365
|
-
signal: options.signal
|
|
8366
|
-
});
|
|
8367
|
-
if (wait.outcome === PollOutcome.Timeout) {
|
|
8368
|
-
return fail4("uninstall_blocked", `Deployment '${deploymentName}' still had an operation running after ${options.timeout ?? 360}s, so it could not be uninstalled.`, buildDeploymentStateInstructions(wait.state ?? state, details), { exitCode: 2, errorCode: "timeout", retry: "RetryLater" });
|
|
8369
|
-
}
|
|
8370
|
-
if (wait.outcome !== PollOutcome.Completed) {
|
|
8371
|
-
const {
|
|
8372
|
-
reason,
|
|
8373
|
-
message: pollMessage,
|
|
8374
|
-
exitCode,
|
|
8375
|
-
errorCode: pollErrorCode,
|
|
8376
|
-
retry: pollRetry
|
|
8377
|
-
} = mapPollFailure(wait, "Deployment");
|
|
8378
|
-
return fail4(reason, pollMessage, `The deployment may still be installing. Check it with: uip solution deploy list, then retry the uninstall.`, { exitCode, errorCode: pollErrorCode, retry: pollRetry });
|
|
8379
|
-
}
|
|
8380
|
-
state = wait.state;
|
|
8381
|
-
continue;
|
|
8382
|
-
}
|
|
8383
|
-
if (sweepIncomplete && (!state || isCompletedUninstall(state))) {
|
|
8384
|
-
if (isNameOrFeedRefusal(errorCode, context?.httpStatus)) {
|
|
8385
|
-
return incompleteSweepFailureAsync(deploymentName, sweep, details);
|
|
8386
|
-
}
|
|
8387
|
-
return fail4("uninstall_request_failed", message, requestErrorInstructions(deploymentName, errorCode, details), { errorCode, retry });
|
|
8388
|
-
}
|
|
8389
|
-
const instructions = state ? buildDeploymentStateInstructions(state, details) : `No deployment named '${deploymentName}' was found in any feed you can reach (tenant, Personal Workspace, or a folder feed). Check the name with 'uip solution deploy list'. Details: ${details}`;
|
|
8390
|
-
return fail4("uninstall_request_failed", message, instructions, {
|
|
8391
|
-
errorCode,
|
|
8392
|
-
retry
|
|
8393
|
-
});
|
|
8394
|
-
}
|
|
8395
|
-
}
|
|
8396
|
-
async function incompleteSweepFailureAsync(deploymentName, sweep, refusalDetails) {
|
|
8397
|
-
const report = await reportIncompleteSweepAsync(deploymentName, sweep.skipped);
|
|
8398
|
-
return fail4("uninstall_request_failed", report.message, `${INCOMPLETE_SWEEP_ADVICE} Without its feed the uninstall request went to the tenant feed, which refused it. ${report.nextStep} Details: ${refusalDetails} (feed search: ${report.details})`, { errorCode: report.errorCode, retry: report.retry });
|
|
8399
|
-
}
|
|
8400
|
-
async function uninstallDeploymentAsync(deploymentName, options = {}) {
|
|
8401
|
-
const [authError, auth] = await catchError(getSolutionAuthContext({
|
|
8402
|
-
tenant: options.tenant,
|
|
8403
|
-
loginValidity: options.loginValidity,
|
|
8404
|
-
envFilePath: options.envFilePath
|
|
8405
|
-
}));
|
|
8406
|
-
if (authError) {
|
|
8407
|
-
return fail4("auth_failed", authError.message, authError.message);
|
|
8408
|
-
}
|
|
8409
|
-
const api = new PipelinesApi(new Configuration2({
|
|
8410
|
-
basePath: auth.basePath,
|
|
8411
|
-
accessToken: auth.accessToken
|
|
8412
|
-
}));
|
|
8413
|
-
const deadline = Date.now() + (options.timeout ?? 360) * 1000;
|
|
8414
|
-
const intervalMs = options.pollInterval ?? 5000;
|
|
8415
|
-
const remainingMs = () => Math.max(deadline - Date.now(), 1);
|
|
8416
|
-
const sweep = await findDeploymentAcrossFeeds(auth, deploymentName, options);
|
|
8417
|
-
const location = sweep.location;
|
|
8418
|
-
const [requestError, requested] = await catchError(requestUninstallAsync(api, auth, deploymentName, {
|
|
8419
|
-
options,
|
|
8420
|
-
sweep,
|
|
8421
|
-
intervalMs,
|
|
8422
|
-
remainingMs
|
|
8423
|
-
}));
|
|
8424
|
-
if (requestError) {
|
|
8425
|
-
throw requestError;
|
|
8426
|
-
}
|
|
8427
|
-
if (!requested.ok) {
|
|
8428
|
-
return requested;
|
|
8429
|
-
}
|
|
8430
|
-
const uninstallResult = requested.result;
|
|
8431
|
-
if (uninstallResult.complete) {
|
|
8432
|
-
return {
|
|
8433
|
-
ok: true,
|
|
8434
|
-
status: "Uninstall completed immediately",
|
|
8435
|
-
deploymentName
|
|
8436
|
-
};
|
|
8437
|
-
}
|
|
8438
|
-
const instanceId = uninstallResult.instanceId;
|
|
8439
|
-
if (!instanceId) {
|
|
8440
|
-
return {
|
|
8441
|
-
ok: true,
|
|
8442
|
-
status: "Uninstall scheduled",
|
|
8443
|
-
deploymentName,
|
|
8444
|
-
scheduled: uninstallResult.scheduled
|
|
8445
|
-
};
|
|
8446
|
-
}
|
|
8447
|
-
const pollResult = await pollUntil({
|
|
8448
|
-
fn: () => api.pipelinesGetDeploymentInstanceStatus({ instanceId }, location?.scope),
|
|
8449
|
-
until: (result) => TERMINAL_STATUSES2.has(result.status),
|
|
8450
|
-
getStatus: (result) => result.status,
|
|
8451
|
-
label: `uninstall ${deploymentName}`,
|
|
8452
|
-
logPrefix: "uninstall",
|
|
8453
|
-
timeoutMs: remainingMs(),
|
|
8454
|
-
intervalMs,
|
|
8455
|
-
signal: options.signal
|
|
8456
|
-
});
|
|
8457
|
-
if (pollResult.outcome !== PollOutcome.Completed || !pollResult.data) {
|
|
8458
|
-
const { reason, message, exitCode, errorCode, retry } = mapPollFailure(pollResult, "Uninstall");
|
|
8459
|
-
return fail4(reason, message, "Uninstall may still be in progress.", {
|
|
8460
|
-
exitCode,
|
|
8461
|
-
errorCode,
|
|
8462
|
-
retry
|
|
8463
|
-
});
|
|
8464
|
-
}
|
|
8465
|
-
const finalStatus = pollResult.data;
|
|
8466
|
-
if (finalStatus.status !== "SuccessfulUninstall") {
|
|
8467
|
-
const errors2 = coerceWorkflowErrorMessages(finalStatus.errorMessage).map((e) => e.errorMessage).join(", ");
|
|
8468
|
-
return fail4("uninstall_failed", `Uninstall failed with status: ${finalStatus.status}`, errors2 || `Orchestrator ended the uninstall in a FailedUninstall state without an error detail. Run 'uip solution deploy list' to recheck the deployment's state and retry. If it stays in a failed state and that listing shows Delete among its actions, remove the record with: uip solution deploy delete '${deploymentName}' --yes. Remove it from the Orchestrator Solutions UI when it does not.`);
|
|
8469
|
-
}
|
|
8470
|
-
return {
|
|
8471
|
-
ok: true,
|
|
8472
|
-
status: finalStatus.status,
|
|
8473
|
-
deploymentName,
|
|
8474
|
-
instanceId
|
|
8475
|
-
};
|
|
8476
|
-
}
|
|
8477
|
-
|
|
8478
|
-
// src/services/deploy-upgrade-service.ts
|
|
8479
|
-
var fail5 = (reason, message, instructions, extras = {}) => ({
|
|
8480
|
-
ok: false,
|
|
8481
|
-
reason,
|
|
8482
|
-
message,
|
|
8483
|
-
instructions,
|
|
8484
|
-
exitCode: extras.exitCode ?? 1,
|
|
8485
|
-
errorCode: extras.errorCode,
|
|
8486
|
-
retry: extras.retry
|
|
8487
|
-
});
|
|
8488
|
-
var DEFAULT_TIMEOUT_SECONDS = 300;
|
|
8489
|
-
var DEFAULT_POLL_INTERVAL_MS = 5000;
|
|
8490
|
-
var AUTH_INSTRUCTIONS2 = "Run 'uip login' to refresh credentials, then retry. If the deployment is in a different tenant, switch with 'uip login tenant set <tenant>'.";
|
|
8491
|
-
var PACKAGE_INSTRUCTIONS = "Confirm the version is published to the tenant (or Personal Workspace) feed: uip solution packages list.";
|
|
8492
|
-
var TARGET_INSTRUCTIONS = "Address the deployment either by key — uip solution deploy upgrade <deployment-key> — or by name with its package: uip solution deploy upgrade --name <deployment-name> --package-name <package>. 'uip solution deploy list' reports all three.";
|
|
8493
|
-
var DEPLOYMENT_NOT_FOUND_INSTRUCTIONS = "Check the key with 'uip solution deploy list'. A server without the Pipelines deployment lookup answers 404 to every key for an external app; on one of those, address the deployment with --name and --package-name instead.";
|
|
8494
|
-
var LOOKUP_FAILED_INSTRUCTIONS = "The deployment lookup failed before any upgrade was requested. Retry, or address the deployment with --name and --package-name.";
|
|
8495
|
-
var INVALID_TARGET = {
|
|
8496
|
-
errorCode: "invalid_argument",
|
|
8497
|
-
retry: "RetryWillNotFix"
|
|
8498
|
-
};
|
|
8499
|
-
var GUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
8500
|
-
var UPGRADE_REFUSED_INSTRUCTIONS = "The server refused to start the upgrade. The deployment name may not exist, or may belong to a different package — check both with 'uip solution deploy list'. Another operation may still be running on it (wait, then retry), or it may be in a state the platform does not offer upgrades for.";
|
|
8501
|
-
async function upgradeDeploymentAsync(first, second) {
|
|
8502
|
-
const options = typeof first === "string" ? { ...second, deploymentKey: first } : first;
|
|
8503
|
-
const targetError = validateTarget(options);
|
|
8504
|
-
if (targetError) {
|
|
8505
|
-
return targetError;
|
|
8506
|
-
}
|
|
8507
|
-
const [authError, auth] = await catchError(getSolutionAuthContext({
|
|
8508
|
-
tenant: options.tenant,
|
|
8509
|
-
loginValidity: options.loginValidity,
|
|
8510
|
-
envFilePath: options.envFilePath
|
|
8511
|
-
}));
|
|
8512
|
-
if (authError) {
|
|
8513
|
-
return fail5("auth_failed", authError.message, AUTH_INSTRUCTIONS2);
|
|
8514
|
-
}
|
|
8515
|
-
const pipelinesApi = new PipelinesApi(new Configuration2({
|
|
8516
|
-
basePath: auth.basePath,
|
|
8517
|
-
accessToken: auth.accessToken
|
|
8518
|
-
}));
|
|
8519
|
-
const target = options.deploymentKey ? await resolveTargetByKeyAsync(pipelinesApi, auth, options, options.deploymentKey) : await resolveTargetByNameAsync(pipelinesApi, auth, options);
|
|
8520
|
-
if (!target.ok) {
|
|
8521
|
-
return target;
|
|
8522
|
-
}
|
|
8523
|
-
const { deploymentName, packageName, scope } = target;
|
|
8524
|
-
let targetVersion = options.version;
|
|
8525
|
-
if (targetVersion === undefined) {
|
|
8526
|
-
const [versionError, latest] = await catchError(pipelinesApi.pipelinesGetPackageVersion({ packageName, packageVersion: null }, scope));
|
|
8527
|
-
if (versionError || !latest) {
|
|
8528
|
-
const detail = versionError && await extractErrorDetails(versionError);
|
|
8529
|
-
if (!detail || detail.context?.httpStatus === 404) {
|
|
8530
|
-
return fail5("package_not_found", detail?.details ? `Package '${packageName}' was not found in the feed: ${detail.details}` : `Package '${packageName}' was not found in the feed.`, PACKAGE_INSTRUCTIONS, { errorCode: "not_found", retry: "RetryWillNotFix" });
|
|
8531
|
-
}
|
|
8532
|
-
return fail5("lookup_failed", detail.details ? `${detail.message}: ${detail.details}` : detail.message, `The version lookup for '${packageName}' failed before any upgrade was requested. Retry, or pass --version explicitly to skip the lookup.`, { errorCode: detail.errorCode, retry: detail.retry });
|
|
8533
|
-
}
|
|
8534
|
-
targetVersion = latest.packageVersion;
|
|
8535
|
-
}
|
|
8536
|
-
const [installError, installResult] = await catchError(pipelinesApi.pipelinesInstall({
|
|
8537
|
-
deploymentName,
|
|
8538
|
-
packageName,
|
|
8539
|
-
packageVersion: targetVersion,
|
|
8540
|
-
solutionRootFolderName: deploymentName
|
|
8541
|
-
}, scope));
|
|
8542
|
-
if (installError || !installResult?.pipelineDeploymentId) {
|
|
8543
|
-
let message = "The upgrade request returned no pipeline deployment.";
|
|
8544
|
-
let classification = {};
|
|
8545
|
-
let instructions = UPGRADE_REFUSED_INSTRUCTIONS;
|
|
8546
|
-
if (installError) {
|
|
8547
|
-
const detail = await extractErrorDetails(installError);
|
|
8548
|
-
message = detail.details ? `${detail.message}: ${detail.details}` : detail.message;
|
|
8549
|
-
classification = {
|
|
8550
|
-
errorCode: detail.errorCode,
|
|
8551
|
-
retry: detail.retry
|
|
8552
|
-
};
|
|
8553
|
-
if (detail.context?.httpStatus === 404) {
|
|
8554
|
-
instructions = `The server knows no such version of '${packageName}' in this feed. ${PACKAGE_INSTRUCTIONS} 'uip solution deploy list' shows the deployment's package and current version.`;
|
|
8555
|
-
}
|
|
8556
|
-
if (hasServerErrorCode(detail.details, DRAFT_VERSION_MISMATCH_CODE)) {
|
|
8557
|
-
return fail5("pending_draft", message, `'${deploymentName}' has a pending draft for another version: an earlier attempt that never completed, usually one rejected by validation, and the server will not upgrade past it. Discard it and upgrade the live version: ${discardRetryCommand(options, target)}${options.deploymentKey ? "" : `
|
|
8558
|
-
Under an external app the name form cannot find the draft; pass the deployment's key instead (InstallDeploymentKey from the original deploy, or Key from 'uip solution deploy list').`}`, INVALID_TARGET);
|
|
8559
|
-
}
|
|
8560
|
-
}
|
|
8561
|
-
return fail5("request_failed", message, instructions, classification);
|
|
8562
|
-
}
|
|
8563
|
-
const pipelineDeploymentId = installResult.pipelineDeploymentId;
|
|
8564
|
-
const base = {
|
|
8565
|
-
deploymentName,
|
|
8566
|
-
toVersion: targetVersion,
|
|
8567
|
-
pipelineDeploymentId,
|
|
8568
|
-
...target.fromVersion !== undefined && {
|
|
8569
|
-
fromVersion: target.fromVersion
|
|
8570
|
-
},
|
|
8571
|
-
...target.installDeploymentKey !== undefined && {
|
|
8572
|
-
installDeploymentKey: target.installDeploymentKey
|
|
8573
|
-
},
|
|
8574
|
-
...target.discardedDraftKey !== undefined && {
|
|
8575
|
-
discardedDraftKey: target.discardedDraftKey
|
|
8576
|
-
}
|
|
8577
|
-
};
|
|
8578
|
-
if (options.noWait) {
|
|
8579
|
-
return { ok: true, ...base, status: "Accepted" };
|
|
8580
|
-
}
|
|
8581
|
-
const timeoutSeconds = Number.isFinite(options.timeout) ? options.timeout : DEFAULT_TIMEOUT_SECONDS;
|
|
8582
|
-
const poll = await pollPipelineDeploymentAsync(pipelinesApi, auth, {
|
|
8583
|
-
pipelineDeploymentId,
|
|
8584
|
-
deploymentName,
|
|
8585
|
-
scope,
|
|
8586
|
-
timeoutMs: timeoutSeconds * 1000,
|
|
8587
|
-
intervalMs: Number.isFinite(options.pollInterval) ? options.pollInterval : DEFAULT_POLL_INTERVAL_MS,
|
|
8588
|
-
signal: options.signal,
|
|
8589
|
-
logPrefix: "deploy upgrade"
|
|
8590
|
-
});
|
|
8591
|
-
if (poll.outcome !== PollOutcome.Completed) {
|
|
8592
|
-
const failure = mapPollFailure(poll, `Upgrade ${pipelineDeploymentId}`);
|
|
8593
|
-
const isTimeout = poll.outcome === PollOutcome.Timeout;
|
|
8594
|
-
const lastStatus = poll.data?.status ?? "unknown";
|
|
8595
|
-
return fail5(isTimeout ? "install_timeout" : failure.reason, isTimeout ? `The upgrade of '${deploymentName}' to ${targetVersion} did not finish within ${timeoutSeconds}s (last status: ${lastStatus}).` : `${failure.message} while upgrading '${deploymentName}' to ${targetVersion} (last status: ${lastStatus}).`, isTimeout ? `It may still be running. ${trackingHint(pipelineDeploymentId, target.listFlag)} Or pass a longer --timeout.` : `The upgrade may still be running. ${trackingHint(pipelineDeploymentId, target.listFlag)}`, {
|
|
8596
|
-
exitCode: failure.exitCode,
|
|
8597
|
-
errorCode: failure.errorCode,
|
|
8598
|
-
retry: failure.retry
|
|
8599
|
-
});
|
|
8600
|
-
}
|
|
8601
|
-
const finalStatus = poll.data;
|
|
8602
|
-
if (!finalStatus) {
|
|
8603
|
-
return fail5("deploy_failed", `The upgrade of '${deploymentName}' returned no final status.`, trackingHint(pipelineDeploymentId, target.listFlag));
|
|
8604
|
-
}
|
|
8605
|
-
const landedDespiteStatus = installLandedDespiteStatus(finalStatus);
|
|
8606
|
-
if (finalStatus.status !== "DeploymentSucceeded" && !landedDespiteStatus) {
|
|
8607
|
-
return fail5("deploy_failed", `The upgrade of '${deploymentName}' to ${targetVersion} ended in ${finalStatus.status}.`, `${await describeUpgradeFailureAsync(auth.basePath, auth.accessToken, pipelineDeploymentId, finalStatus, scope, options.signal)}
|
|
8608
|
-
${leavesPendingDraft(finalStatus.status) ? `Nothing was installed; the deployment stays on the version it was already running. The rejected attempt is kept as a pending draft${finalStatus.deploymentKey ? ` (${finalStatus.deploymentKey})` : ""}, which a plain retry would run into, so once the cause is fixed discard it and retry: ${discardRetryCommand(options, target, finalStatus.deploymentKey || undefined)}` : "Fix the reported problem, then retry the upgrade. The deployment stays on the version it was already running."}`, classifyTerminalFailure(finalStatus.status));
|
|
8609
|
-
}
|
|
8610
|
-
const described = await describeUpgradedDeploymentAsync(auth, deploymentName, finalStatus, scope, target.listFlag);
|
|
8611
|
-
return {
|
|
8612
|
-
ok: true,
|
|
8613
|
-
...base,
|
|
8614
|
-
deploymentKey: finalStatus.deploymentKey,
|
|
8615
|
-
operation: finalStatus.deploymentResult?.operation ?? finalStatus.synthesizedOperation,
|
|
8616
|
-
status: finalStatus.status,
|
|
8617
|
-
...finalStatus.deploymentResult?.status && {
|
|
8618
|
-
deploymentStatus: finalStatus.deploymentResult.status,
|
|
8619
|
-
actions: finalStatus.deploymentResult.actions ?? []
|
|
8620
|
-
},
|
|
8621
|
-
...described,
|
|
8622
|
-
...landedDespiteStatus && {
|
|
8623
|
-
nextSteps: [
|
|
8624
|
-
explainPipelineStatusAfterInstall(finalStatus),
|
|
8625
|
-
...described.nextSteps ?? []
|
|
8626
|
-
]
|
|
8627
|
-
}
|
|
8628
|
-
};
|
|
8629
|
-
}
|
|
8630
|
-
async function describeUpgradedDeploymentAsync(auth, deploymentName, finalStatus, scope, listFlag) {
|
|
8631
|
-
const record = finalStatus.deploymentResult;
|
|
8632
|
-
const actions = record?.actions ?? [];
|
|
8633
|
-
if (record?.status === "SuccessfulActivate") {
|
|
8634
|
-
return { activationStatus: "Active" };
|
|
8635
|
-
}
|
|
8636
|
-
const [, rows] = await catchError(findDeploymentsByName(auth, deploymentName, scope));
|
|
8637
|
-
const row = rows?.find((candidate) => candidate.key === finalStatus.deploymentKey);
|
|
8638
|
-
const activationStatus = row?.activationStatus ?? (actions.includes("SetupActivation") ? "NeedsSetupToActivate" : actions.includes("Activate") ? "ReadyToActivate" : undefined);
|
|
8639
|
-
if (!activationStatus) {
|
|
8640
|
-
return {};
|
|
8641
|
-
}
|
|
8642
|
-
const state = {
|
|
8643
|
-
name: deploymentName,
|
|
8644
|
-
operation: row?.operation ?? record?.operation ?? finalStatus.synthesizedOperation,
|
|
8645
|
-
operationStatus: row?.operationStatus ?? "Successful",
|
|
8646
|
-
activationStatus,
|
|
8647
|
-
packageVersion: row?.packageVersion ?? record?.packageVersion,
|
|
8648
|
-
currentPackageVersion: row?.currentPackageVersion ?? record?.packageVersion
|
|
8649
|
-
};
|
|
8650
|
-
const pendingResources = needsPendingResources(state) && finalStatus.deploymentKey ? await readPendingResourcesAsync(new DeploymentsApi(new Configuration({
|
|
8651
|
-
basePath: auth.basePath,
|
|
8652
|
-
accessToken: auth.accessToken
|
|
8653
|
-
})), finalStatus.deploymentKey, scope) : undefined;
|
|
8654
|
-
const nextSteps = deploymentNextSteps(state, pendingResources, listFlag ? ` ${listFlag}` : "");
|
|
8655
|
-
return {
|
|
8656
|
-
activationStatus,
|
|
8657
|
-
...pendingResources ? { pendingResources } : {},
|
|
8658
|
-
...nextSteps && nextSteps.length > 0 ? { nextSteps } : {}
|
|
8659
|
-
};
|
|
8660
|
-
}
|
|
8661
|
-
function trackingHint(pipelineDeploymentId, listFlag) {
|
|
8662
|
-
return listFlag ? `Track it with: uip solution deploy list ${listFlag} (deploy status reads the tenant feed and cannot see this run).` : `Track it with: uip solution deploy status ${pipelineDeploymentId}, or uip solution deploy list.`;
|
|
8663
|
-
}
|
|
8664
|
-
function discardRetryCommand(options, target, draftKey) {
|
|
8665
|
-
const version = options.version ? ` --version ${options.version}` : "";
|
|
8666
|
-
const key = draftKey ?? options.deploymentKey;
|
|
8667
|
-
if (key) {
|
|
8668
|
-
return `uip solution deploy upgrade ${key} --discard-draft${version}`;
|
|
8669
|
-
}
|
|
8670
|
-
const workspace = options.personalWorkspace ? " --personal-workspace" : "";
|
|
8671
|
-
return `uip solution deploy upgrade --name ${target.deploymentName} --package-name ${target.packageName}${workspace} --discard-draft${version}`;
|
|
8672
|
-
}
|
|
8673
|
-
function validateTarget(options) {
|
|
8674
|
-
const byKey = options.deploymentKey !== undefined;
|
|
8675
|
-
const byName = options.deploymentName !== undefined || options.packageName !== undefined;
|
|
8676
|
-
if (options.version !== undefined && options.version.trim() === "") {
|
|
8677
|
-
return fail5("invalid_target", "--version was given but is empty.", "Pass the version to upgrade to (uip solution packages list shows the published ones), or omit --version to upgrade to the newest.", INVALID_TARGET);
|
|
8678
|
-
}
|
|
8679
|
-
if (byKey && byName) {
|
|
8680
|
-
return fail5("invalid_target", "Pass either a deployment key or --name with --package-name, not both.", TARGET_INSTRUCTIONS, INVALID_TARGET);
|
|
8681
|
-
}
|
|
8682
|
-
if (byKey) {
|
|
8683
|
-
return GUID_PATTERN.test(options.deploymentKey) ? undefined : fail5("invalid_target", `'${options.deploymentKey}' is not a deployment key.`, `A deployment key is a GUID, reported as Key by 'uip solution deploy list'. To address the deployment by name instead: ${TARGET_INSTRUCTIONS}`, INVALID_TARGET);
|
|
8684
|
-
}
|
|
8685
|
-
if (!options.deploymentName || !options.packageName) {
|
|
8686
|
-
return fail5("invalid_target", "--name and --package-name go together: the Pipelines install route needs both.", TARGET_INSTRUCTIONS, INVALID_TARGET);
|
|
8687
|
-
}
|
|
8688
|
-
return;
|
|
8689
|
-
}
|
|
8690
|
-
async function resolveTargetByNameAsync(pipelinesApi, auth, options) {
|
|
8691
|
-
const deploymentName = options.deploymentName;
|
|
8692
|
-
let scope;
|
|
8693
|
-
if (options.personalWorkspace) {
|
|
8694
|
-
const verdict = classifyFeedSession(auth);
|
|
8695
|
-
if (verdict !== "user") {
|
|
8696
|
-
const { message, instructions } = feedSessionRefusal(verdict, `Upgrading the Personal Workspace deployment '${deploymentName}'`, "address the deployment by key");
|
|
8697
|
-
return fail5("feed_requires_user_session", message, instructions, {
|
|
8698
|
-
errorCode: "permission_denied",
|
|
8699
|
-
retry: "RetryWillNotFix"
|
|
8700
|
-
});
|
|
8701
|
-
}
|
|
8702
|
-
const [pwError, pw] = await catchError(resolvePersonalWorkspace({
|
|
8703
|
-
tenant: options.tenant,
|
|
8704
|
-
loginValidity: options.loginValidity,
|
|
8705
|
-
envFilePath: options.envFilePath
|
|
8706
|
-
}));
|
|
8707
|
-
if (pwError || !pw) {
|
|
8708
|
-
return fail5("personal_workspace_failed", pwError?.message ?? "Personal Workspace could not be resolved.", "Ensure your user has a Personal Workspace, then retry.");
|
|
8709
|
-
}
|
|
8710
|
-
scope = folderKeyInitOverride(pw.key);
|
|
8711
|
-
}
|
|
8712
|
-
const [existsError] = await catchError(pipelinesApi.pipelinesGetPreActivateSteps({ deploymentName }, scope));
|
|
8713
|
-
if (existsError) {
|
|
8714
|
-
const detail = await extractErrorDetails(existsError);
|
|
8715
|
-
const where = scope ? "your Personal Workspace feed" : `the tenant feed of '${auth.tenantName}'`;
|
|
8716
|
-
if (isDeploymentNotFound(detail)) {
|
|
8717
|
-
return fail5("deployment_not_found", `Deployment '${deploymentName}' was not found in ${where}. 'deploy upgrade' never creates a deployment.`, `Check the name with 'uip solution deploy list'${scope ? "" : " (add --personal-workspace for a Personal Workspace deployment)"}. For a first deployment use 'uip solution deploy run'.`, { errorCode: "not_found", retry: "RetryWillNotFix" });
|
|
8718
|
-
}
|
|
8719
|
-
return fail5("lookup_failed", detail.details ? `${detail.message}: ${detail.details}` : detail.message, `The existence check for '${deploymentName}' failed before any upgrade was requested. Retry, or address the deployment by key: uip solution deploy upgrade <deployment-key>.`, { errorCode: detail.errorCode, retry: detail.retry });
|
|
8720
|
-
}
|
|
8721
|
-
const [rowsError, rows] = await catchError(findDeploymentsByName(auth, deploymentName, scope));
|
|
8722
|
-
if (rowsError) {
|
|
8723
|
-
const unreadable = rowsError instanceof DeploymentSearchNeedsUserSessionError || classifyFeedSession(auth) === "application" && isAuthRefusal(rowsError);
|
|
8724
|
-
if (!unreadable) {
|
|
8725
|
-
const detail = await extractErrorDetails(rowsError);
|
|
8726
|
-
return fail5("lookup_failed", `The status check for '${deploymentName}' failed: ${detail.message}`, "The deployment exists, but whether it is still installed could not be confirmed, and upgrading an uninstalled name would deploy the package afresh under it. Retry, or address the deployment by key: uip solution deploy upgrade <deployment-key>.", { errorCode: detail.errorCode, retry: detail.retry });
|
|
8727
|
-
}
|
|
8728
|
-
}
|
|
8729
|
-
if (isCompletedUninstall(rows ? newestDeploymentRow(rows) : undefined)) {
|
|
8730
|
-
return fail5("deployment_uninstalled", `Deployment '${deploymentName}' has been uninstalled, so there is nothing to upgrade.`, "The install route would create a new deployment under that name rather than upgrade this one. Deploy the package afresh with 'uip solution deploy run', or pick a live deployment from 'uip solution deploy list'.", INVALID_TARGET);
|
|
8731
|
-
}
|
|
8732
|
-
const resolved = {
|
|
8733
|
-
deploymentName,
|
|
8734
|
-
packageName: options.packageName,
|
|
8735
|
-
listFlag: scope ? "--personal-workspace" : undefined
|
|
8736
|
-
};
|
|
8737
|
-
let discardedDraftKey;
|
|
8738
|
-
const newest = rows ? newestDeploymentRow(rows) : undefined;
|
|
8739
|
-
if (newest?.operationStatus === "Draft") {
|
|
8740
|
-
const draft = {
|
|
8741
|
-
key: newest.key,
|
|
8742
|
-
firstInstall: newest.operation === "Install",
|
|
8743
|
-
activationSetup: newest.operation === "ActivationSetup",
|
|
8744
|
-
targetVersion: newest.targetPackageVersion ?? newest.packageVersion,
|
|
8745
|
-
liveVersion: newest.currentPackageVersion
|
|
8746
|
-
};
|
|
8747
|
-
const refusal = refusePendingDraft(options, resolved, draft);
|
|
8748
|
-
if (refusal) {
|
|
8749
|
-
return refusal;
|
|
8750
|
-
}
|
|
8751
|
-
const discarded = await discardDraftAsync(pipelinesApi, deploymentName, draft.key, scope);
|
|
8752
|
-
if (discarded) {
|
|
8753
|
-
return discarded;
|
|
8754
|
-
}
|
|
8755
|
-
discardedDraftKey = draft.key;
|
|
8756
|
-
}
|
|
8757
|
-
return {
|
|
8758
|
-
ok: true,
|
|
8759
|
-
...resolved,
|
|
8760
|
-
scope,
|
|
8761
|
-
discardedDraftKey
|
|
8762
|
-
};
|
|
8763
|
-
}
|
|
8764
|
-
function isDeploymentNotFound(detail) {
|
|
8765
|
-
const status = detail.context?.httpStatus;
|
|
8766
|
-
if (status === 404) {
|
|
8767
|
-
return true;
|
|
8768
|
-
}
|
|
8769
|
-
return status === 400 && (/"errorCode"\s*:\s*"4004"/.test(detail.details) || (detail.parsedErrors?.deploymentName ?? []).some((message) => /not found/i.test(message)));
|
|
8770
|
-
}
|
|
8771
|
-
async function resolveTargetByKeyAsync(pipelinesApi, auth, options, deploymentKey) {
|
|
8772
|
-
const [lookupError, info] = await catchError(pipelinesApi.pipelinesGetDeploymentByKey({ key: deploymentKey }));
|
|
8773
|
-
if (lookupError || !info) {
|
|
8774
|
-
const detail = lookupError ? await extractErrorDetails(lookupError) : undefined;
|
|
8775
|
-
if (detail?.context?.httpStatus === 404 && classifyFeedSession(auth) === "user") {
|
|
8776
|
-
return resolveTargetByKeyViaSolutionsAsync(pipelinesApi, auth, options, deploymentKey);
|
|
8777
|
-
}
|
|
8778
|
-
if (!detail || detail.context?.httpStatus === 404) {
|
|
8779
|
-
return fail5("deployment_not_found", `Deployment '${deploymentKey}' was not found in tenant '${auth.tenantName}'.`, DEPLOYMENT_NOT_FOUND_INSTRUCTIONS, { errorCode: "not_found", retry: "RetryWillNotFix" });
|
|
8780
|
-
}
|
|
8781
|
-
return fail5("lookup_failed", detail.details ? `${detail.message}: ${detail.details}` : detail.message, LOOKUP_FAILED_INSTRUCTIONS, { errorCode: detail.errorCode, retry: detail.retry });
|
|
8782
|
-
}
|
|
8783
|
-
if (info.status === DeploymentStatus.SuccessfulUninstall) {
|
|
8784
|
-
return fail5("deployment_uninstalled", `Deployment '${info.deploymentName}' (${deploymentKey}) has been uninstalled, so there is nothing to upgrade.`, "The install route would create a new deployment under that name rather than upgrade this one. Deploy the package afresh with 'uip solution deploy run', or pick a live deployment from 'uip solution deploy list'.", INVALID_TARGET);
|
|
8785
|
-
}
|
|
8786
|
-
let scope;
|
|
8787
|
-
if (info.locationKey) {
|
|
8788
|
-
const verdict = classifyFeedSession(auth);
|
|
8789
|
-
if (verdict !== "user") {
|
|
8790
|
-
const { message, instructions } = feedSessionRefusal(verdict, `Upgrading deployment '${info.deploymentName}', which is in a Personal Workspace or folder feed (folder key ${info.locationKey}),`, "run the upgrade from the Orchestrator UI");
|
|
8791
|
-
return fail5("feed_requires_user_session", message, instructions, {
|
|
8792
|
-
errorCode: "permission_denied",
|
|
8793
|
-
retry: "RetryWillNotFix"
|
|
8794
|
-
});
|
|
8795
|
-
}
|
|
8796
|
-
scope = folderKeyInitOverride(info.locationKey);
|
|
8797
|
-
} else if (options.personalWorkspace) {
|
|
8798
|
-
return fail5("invalid_target", `Deployment '${info.deploymentName}' (${deploymentKey}) is on the tenant feed, not in a Personal Workspace.`, "Drop --personal-workspace: with a deployment key the feed is read from the deployment itself.", INVALID_TARGET);
|
|
8799
|
-
}
|
|
8800
|
-
const listFlag = info.locationKey ? `--feed ${info.locationKey}` : undefined;
|
|
8801
|
-
let live = info;
|
|
8802
|
-
let discardedDraftKey;
|
|
8803
|
-
if (info.status === DeploymentStatus.Draft) {
|
|
8804
|
-
const draft = {
|
|
8805
|
-
key: info.deploymentKey,
|
|
8806
|
-
firstInstall: info.operation === DeploymentOperation.Install,
|
|
8807
|
-
activationSetup: info.operation === DeploymentOperation.ActivationSetup,
|
|
8808
|
-
targetVersion: info.targetPackageVersion ?? info.packageVersion,
|
|
8809
|
-
liveVersion: info.packageVersion
|
|
8810
|
-
};
|
|
8811
|
-
const refusal = refusePendingDraft(options, {
|
|
8812
|
-
deploymentName: info.deploymentName,
|
|
8813
|
-
packageName: info.packageName,
|
|
8814
|
-
listFlag
|
|
8815
|
-
}, draft);
|
|
8816
|
-
if (refusal) {
|
|
8817
|
-
return refusal;
|
|
8818
|
-
}
|
|
8819
|
-
const discarded = await discardDraftAsync(pipelinesApi, info.deploymentName, draft.key, scope);
|
|
8820
|
-
if (discarded) {
|
|
8821
|
-
return discarded;
|
|
8822
|
-
}
|
|
8823
|
-
const [relookupError, current] = await catchError(pipelinesApi.pipelinesGetDeploymentByKey({
|
|
8824
|
-
key: info.installDeploymentKey
|
|
8825
|
-
}));
|
|
8826
|
-
if (relookupError || !current) {
|
|
8827
|
-
const detail = relookupError ? await extractErrorDetails(relookupError) : undefined;
|
|
8828
|
-
return fail5("lookup_failed", `The pending draft ${draft.key} of '${info.deploymentName}' was discarded, but the live deployment could not be looked up again${detail ? `: ${detail.message}` : "."}`, `Nothing was upgraded. Retry the upgrade: uip solution deploy upgrade ${info.installDeploymentKey}${options.version ? ` --version ${options.version}` : ""}`, detail ? { errorCode: detail.errorCode, retry: detail.retry } : {});
|
|
8829
|
-
}
|
|
8830
|
-
if (current.status === DeploymentStatus.Draft || current.status === DeploymentStatus.SuccessfulUninstall) {
|
|
8831
|
-
return fail5("pending_draft", `The pending draft ${draft.key} of '${info.deploymentName}' was discarded, but the deployment's newest generation is now ${current.status === DeploymentStatus.Draft ? `another draft (${current.deploymentKey})` : "an uninstall"}.`, "Nothing was upgraded. Another operation on this deployment ran in between; check it with 'uip solution deploy list', then retry.", INVALID_TARGET);
|
|
8832
|
-
}
|
|
8833
|
-
live = current;
|
|
8834
|
-
discardedDraftKey = draft.key;
|
|
8835
|
-
}
|
|
8836
|
-
return {
|
|
8837
|
-
ok: true,
|
|
8838
|
-
deploymentName: live.deploymentName,
|
|
8839
|
-
packageName: live.packageName,
|
|
8840
|
-
scope,
|
|
8841
|
-
listFlag,
|
|
8842
|
-
fromVersion: live.packageVersion ?? undefined,
|
|
8843
|
-
installDeploymentKey: live.installDeploymentKey,
|
|
8844
|
-
discardedDraftKey
|
|
8845
|
-
};
|
|
8846
|
-
}
|
|
8847
|
-
async function resolveTargetByKeyViaSolutionsAsync(pipelinesApi, auth, options, deploymentKey) {
|
|
8848
|
-
let scope;
|
|
8849
|
-
if (options.personalWorkspace) {
|
|
8850
|
-
const [pwError, pw] = await catchError(resolvePersonalWorkspace({
|
|
8851
|
-
tenant: options.tenant,
|
|
8852
|
-
loginValidity: options.loginValidity,
|
|
8853
|
-
envFilePath: options.envFilePath
|
|
8854
|
-
}));
|
|
8855
|
-
if (pwError || !pw) {
|
|
8856
|
-
return fail5("personal_workspace_failed", pwError?.message ?? "Personal Workspace could not be resolved.", "Ensure your user has a Personal Workspace, then retry.");
|
|
8857
|
-
}
|
|
8858
|
-
scope = folderKeyInitOverride(pw.key);
|
|
8859
|
-
}
|
|
8860
|
-
const deploymentsApi = new DeploymentsApi(new Configuration({
|
|
8861
|
-
basePath: auth.basePath,
|
|
8862
|
-
accessToken: auth.accessToken
|
|
8863
|
-
}));
|
|
8864
|
-
const [readError, row] = await catchError(deploymentsApi.deploymentsGetByKey({ deploymentKey }, scope));
|
|
8865
|
-
if (readError || !row) {
|
|
8866
|
-
const detail = readError ? await extractErrorDetails(readError) : undefined;
|
|
8867
|
-
if (!detail || detail.context?.httpStatus === 404) {
|
|
8868
|
-
return fail5("deployment_not_found", `Deployment '${deploymentKey}' was not found in ${scope ? "your Personal Workspace feed" : `the tenant feed of '${auth.tenantName}'`}.`, `Check the key with 'uip solution deploy list'. Neither the Pipelines deployment lookup nor the Solutions read found it; the latter reads a key on the tenant feed, or with --personal-workspace in your workspace, so address a folder-feed deployment with --name and --package-name instead.`, { errorCode: "not_found", retry: "RetryWillNotFix" });
|
|
8869
|
-
}
|
|
8870
|
-
return fail5("lookup_failed", detail.details ? `${detail.message}: ${detail.details}` : detail.message, LOOKUP_FAILED_INSTRUCTIONS, { errorCode: detail.errorCode, retry: detail.retry });
|
|
8871
|
-
}
|
|
8872
|
-
if (row.status === "SuccessfulUninstall") {
|
|
8873
|
-
return fail5("deployment_uninstalled", `Deployment '${row.name}' (${deploymentKey}) has been uninstalled, so there is nothing to upgrade.`, "The install route would create a new deployment under that name rather than upgrade this one. Deploy the package afresh with 'uip solution deploy run', or pick a live deployment from 'uip solution deploy list'.", INVALID_TARGET);
|
|
8874
|
-
}
|
|
8875
|
-
const target = await resolveTargetByNameAsync(pipelinesApi, auth, {
|
|
8876
|
-
...options,
|
|
8877
|
-
deploymentName: row.name,
|
|
8878
|
-
packageName: row.packageName
|
|
8879
|
-
});
|
|
8880
|
-
if (!target.ok) {
|
|
8881
|
-
return target;
|
|
8882
|
-
}
|
|
8883
|
-
return { ...target, installDeploymentKey: row.installDeploymentKey };
|
|
8884
|
-
}
|
|
8885
|
-
function refusePendingDraft(options, target, draft) {
|
|
8886
|
-
const targetVersion = draft.targetVersion ?? "<version>";
|
|
8887
|
-
const feed = target.listFlag ? ` ${target.listFlag}` : "";
|
|
8888
|
-
const retryDraft = `uip solution deploy run --name ${target.deploymentName} --package-name ${target.packageName} --package-version ${targetVersion} --config-file <fixed-config>${feed} --yes`;
|
|
8889
|
-
if (draft.firstInstall) {
|
|
8890
|
-
return fail5("pending_draft", `Deployment '${target.deploymentName}' was never installed: its first install (${draft.key}) is still a pending draft, so there is nothing to upgrade.`, `The draft is an attempt that never completed, usually one rejected by validation, or one still running. To retry it with a corrected configuration: ${retryDraft} (the server re-validates the draft with the new file). To abandon it, delete it in Orchestrator.`, INVALID_TARGET);
|
|
8891
|
-
}
|
|
8892
|
-
if (options.discardDraft) {
|
|
8893
|
-
return;
|
|
8894
|
-
}
|
|
8895
|
-
if (draft.activationSetup) {
|
|
8896
|
-
return fail5("pending_draft", `Deployment '${target.deploymentName}' has an unfinished Setup activation (${draft.key}): the Orchestrator "Setup activation" wizard was started on version ${targetVersion} and not completed.`, `While that draft exists the server would run it in place of this upgrade, or refuse a different version. Finish the setup in Orchestrator (Solutions, the deployment, Setup activation), then retry; or discard it and upgrade the live version: ${discardRetryCommand(options, target, draft.key)}`, INVALID_TARGET);
|
|
8897
|
-
}
|
|
8898
|
-
const live = draft.liveVersion ? ` ${draft.liveVersion}` : "";
|
|
8899
|
-
return fail5("pending_draft", `Deployment '${target.deploymentName}' has a pending draft (${draft.key}) for version ${targetVersion}: an earlier attempt that never completed, usually one rejected by validation, or one still running.`, `The server would run that draft, with the configuration it was built with, in place of this upgrade, or refuse a different version. To discard it and upgrade the live version${live}: ${discardRetryCommand(options, target, draft.key)}
|
|
8900
|
-
To retry the draft itself with a corrected configuration instead: ${retryDraft}`, INVALID_TARGET);
|
|
8901
|
-
}
|
|
8902
|
-
async function discardDraftAsync(pipelinesApi, deploymentName, draftKey, scope) {
|
|
8903
|
-
const [error] = await catchError(pipelinesApi.pipelinesDeleteDeploymentByKey({ deploymentKey: draftKey }, scope));
|
|
8904
|
-
if (!error) {
|
|
8905
|
-
return;
|
|
8906
|
-
}
|
|
8907
|
-
const detail = await extractErrorDetails(error);
|
|
8908
|
-
const status = detail.context?.httpStatus;
|
|
8909
|
-
const hasBody = !isBareResponse(detail.details);
|
|
8910
|
-
if (hasServerErrorCode(detail.details, "DeploymentNotFound") || status === 404 && hasBody) {
|
|
8911
|
-
return;
|
|
8912
|
-
}
|
|
8913
|
-
const message = `The pending draft ${draftKey} of '${deploymentName}' could not be discarded: ${hasBody ? `${detail.message}: ${detail.details}` : detail.message}`;
|
|
8914
|
-
if (status === 405 || status === 404 && !hasBody) {
|
|
8915
|
-
return fail5("discard_draft_failed", message, "This server cannot discard drafts through the Pipelines API yet. Nothing was upgraded. Delete the draft in Orchestrator, then retry the upgrade.", {
|
|
8916
|
-
errorCode: status === 405 ? "method_not_allowed" : "not_found",
|
|
8917
|
-
retry: "RetryWillNotFix"
|
|
8918
|
-
});
|
|
8919
|
-
}
|
|
8920
|
-
if (hasServerErrorCode(detail.details, "DeploymentAlreadyInProgress")) {
|
|
8921
|
-
return fail5("discard_draft_failed", message, "The draft is still being validated. Nothing was upgraded. Wait for its run to finish (uip solution deploy list shows it), then retry.", { errorCode: "invalid_argument", retry: "RetryLater" });
|
|
8922
|
-
}
|
|
8923
|
-
if (hasServerErrorCode(detail.details, "DeploymentInvalidState")) {
|
|
8924
|
-
return fail5("discard_draft_failed", message, "The draft is no longer one that can be discarded: it moved on (it was promoted, or it is a rollback). Nothing was upgraded. Check the deployment with 'uip solution deploy list', then retry.", INVALID_TARGET);
|
|
8925
|
-
}
|
|
8926
|
-
return fail5("discard_draft_failed", message, "Nothing was upgraded. Retry, or delete the draft in Orchestrator and then retry the upgrade.", { errorCode: detail.errorCode, retry: detail.retry });
|
|
8927
|
-
}
|
|
8928
|
-
function classifyTerminalFailure(status) {
|
|
8929
|
-
return status === "ValidationFailed" || status === "ConflictFixingError" ? { errorCode: "invalid_argument", retry: "RetryWillNotFix" } : {};
|
|
8930
|
-
}
|
|
8931
|
-
async function describeUpgradeFailureAsync(basePath, accessToken, pipelineDeploymentId, finalStatus, scope, signal) {
|
|
8932
|
-
const fromPipeline = formatDeploymentFailureDetails(pipelineDeploymentId, finalStatus);
|
|
8933
|
-
const explained = finalStatus.validationResult?.validationErrors?.length || finalStatus.validationResult?.conflictErrors?.length || finalStatus.conflictFixingErrors?.length || finalStatus.deploymentScheduleErrors?.length || finalStatus.deploymentResult?.errorMessage;
|
|
8934
|
-
if (explained || !finalStatus.deploymentKey) {
|
|
8935
|
-
return fromPipeline;
|
|
8936
|
-
}
|
|
8937
|
-
const deploymentsApi = new DeploymentsApi(new Configuration({ basePath, accessToken }));
|
|
8938
|
-
const reason = await describeValidationFailureAsync(deploymentsApi, finalStatus.deploymentKey, SolutionDeploymentAction.Upgrade, scope, signal);
|
|
8939
|
-
return reason === NO_SERVER_REASON ? fromPipeline : `Validation: ${reason}
|
|
8940
|
-
${fromPipeline}`;
|
|
8941
|
-
}
|
|
8942
|
-
|
|
8943
|
-
// src/services/packages-list-service.ts
|
|
8944
|
-
var fail6 = (reason, message, instructions, extras = {}) => ({
|
|
8945
|
-
ok: false,
|
|
8946
|
-
reason,
|
|
8947
|
-
message,
|
|
8948
|
-
instructions,
|
|
8949
|
-
exitCode: 1,
|
|
8950
|
-
...extras
|
|
8951
|
-
});
|
|
8952
|
-
async function listPackagesAsync(options = {}) {
|
|
8953
|
-
const limit = options.limit ?? DEFAULT_PAGE_SIZE;
|
|
8954
|
-
const offset = options.offset ?? 0;
|
|
8955
|
-
const [authError, auth] = await catchError(getSolutionAuthContext({
|
|
8956
|
-
tenant: options.tenant,
|
|
8957
|
-
loginValidity: options.loginValidity,
|
|
8958
|
-
envFilePath: options.envFilePath
|
|
8959
|
-
}));
|
|
8960
|
-
if (authError) {
|
|
8961
|
-
return fail6("auth_failed", authError.message, authError.message);
|
|
8962
|
-
}
|
|
8963
|
-
const [scopeError, scope] = await catchError(resolveFeedScope({
|
|
8964
|
-
personalWorkspace: options.personalWorkspace,
|
|
8965
|
-
feed: options.feed,
|
|
8966
|
-
tenant: options.tenant,
|
|
8967
|
-
loginValidity: options.loginValidity,
|
|
8968
|
-
envFilePath: options.envFilePath
|
|
8969
|
-
}));
|
|
8970
|
-
if (scopeError) {
|
|
8971
|
-
const { message, instructions, ...extras } = await describeFeedResolutionFailureAsync(scopeError, options, auth);
|
|
8972
|
-
return fail6("feed_resolution_failed", message, instructions, extras);
|
|
8973
|
-
}
|
|
8974
|
-
const searchApi = new SearchApi(new Configuration({
|
|
8975
|
-
basePath: auth.basePath,
|
|
8976
|
-
accessToken: auth.accessToken
|
|
8977
|
-
}));
|
|
8978
|
-
const [listError, result] = await catchError(searchApi.searchSearchPackages({
|
|
8979
|
-
searchFilter: {
|
|
8980
|
-
orderByColumn: options.sortBy ?? "publishDate",
|
|
8981
|
-
orderByDirection: options.sortOrder ?? "Descending",
|
|
8982
|
-
take: limit,
|
|
8983
|
-
skip: offset,
|
|
8984
|
-
searchTerm: options.name
|
|
8985
|
-
}
|
|
8986
|
-
}, feedScopeInitOverride(scope)));
|
|
8987
|
-
if (listError) {
|
|
8988
|
-
const { message, instructions, ...extras } = await describeSearchFailureAsync(listError, "packages", auth, {
|
|
8989
|
-
userSessionsOnly: true
|
|
8990
|
-
});
|
|
8991
|
-
return fail6("list_request_failed", message, instructions, extras);
|
|
8992
|
-
}
|
|
8993
|
-
const packages = result.values ?? [];
|
|
8994
|
-
return {
|
|
8995
|
-
ok: true,
|
|
8996
|
-
packages,
|
|
8997
|
-
limit,
|
|
8998
|
-
offset,
|
|
8999
|
-
total: result.count
|
|
9000
|
-
};
|
|
9001
|
-
}
|
|
9002
|
-
|
|
9003
|
-
export { extractDeploymentErrors, formatDeploymentErrorsAsText, activateDeploymentAsync, listDeploymentsAsync, deployRunAsync, uninstallDeploymentAsync, upgradeDeploymentAsync, listPackagesAsync };
|
|
7680
|
+
export { deployRunAsync };
|
|
9004
7681
|
|
|
9005
|
-
//# debugId=
|
|
7682
|
+
//# debugId=01897782E2F73B9764756E2164756E21
|