@astrale-os/sdk 0.6.0-beta.13 → 0.6.0-beta.14
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 +4 -0
- package/dist/deployment/adapter/adapter.d.ts +1 -6
- package/dist/deployment/adapter/legacy/adapter.d.ts +0 -10
- package/dist/deployment/adapter/legacy/deploy/context.d.ts +0 -2
- package/dist/deployment/adapter/legacy/deploy/result.d.ts +2 -3
- package/dist/deployment/adapter/legacy/index.d.ts +10 -8
- package/dist/deployment/adapter/legacy/prepare/context.d.ts +0 -2
- package/dist/deployment/adapter/release/context.d.ts +16 -2
- package/dist/deployment/address/index.d.ts +1 -1
- package/dist/deployment/address/index.js +1 -0
- package/dist/deployment/address/summary.d.ts +30 -0
- package/dist/deployment/address/summary.js +117 -1
- package/dist/deployment/build/index.d.ts +1 -1
- package/dist/deployment/build/index.js +1 -1
- package/dist/deployment/build/manifest.d.ts +5 -0
- package/dist/deployment/build/manifest.js +10 -0
- package/dist/deployment/index.d.ts +1 -1
- package/dist/deployment/release/legacy/index.d.ts +15 -10
- package/dist/deployment/release/legacy/index.js +15 -10
- package/dist/deployment/verify/readiness/deployment.js +3 -13
- package/dist/deployment/verify/readiness/fetch.d.ts +13 -0
- package/dist/deployment/verify/readiness/fetch.js +26 -0
- package/dist/deployment/verify/readiness/identity.d.ts +3 -6
- package/dist/deployment/verify/readiness/identity.js +3 -3
- package/dist/deployment/verify/readiness/index.d.ts +12 -8
- package/dist/deployment/verify/readiness/index.js +15 -4
- package/dist/deployment/verify/readiness/legacy/index.d.ts +2 -0
- package/dist/deployment/verify/readiness/legacy/index.js +2 -0
- package/dist/deployment/verify/readiness/legacy/publication.d.ts +12 -0
- package/dist/deployment/verify/readiness/legacy/publication.js +23 -0
- package/dist/deployment/verify/readiness/release.d.ts +8 -0
- package/dist/deployment/verify/readiness/release.js +22 -0
- package/dist/execution/identity/authentication.d.ts +7 -0
- package/dist/execution/identity/authentication.js +7 -1
- package/dist/execution/identity/delivery.d.ts +11 -4
- package/dist/execution/identity/delivery.js +47 -20
- package/dist/execution/identity/identity.d.ts +7 -3
- package/dist/execution/identity/identity.js +2 -2
- package/dist/execution/invocation/admission/authentication.d.ts +1 -2
- package/dist/execution/invocation/admission/authentication.js +1 -2
- package/dist/execution/invocation/admission/authority.d.ts +10 -4
- package/dist/execution/invocation/admission/authority.js +5 -1
- package/dist/execution/invocation/invocation.js +51 -14
- package/dist/execution/runtime/index.d.ts +1 -0
- package/dist/execution/runtime/index.js +1 -0
- package/dist/execution/runtime/load.d.ts +3 -3
- package/dist/execution/runtime/load.js +3 -2
- package/dist/execution/runtime/release.d.ts +22 -0
- package/dist/execution/runtime/release.js +14 -0
- package/dist/execution/serve.d.ts +2 -2
- package/dist/execution/service/create.js +9 -7
- package/dist/execution/service/release.d.ts +2 -2
- package/dist/execution/service/release.js +3 -2
- package/dist/execution/service/service.d.ts +9 -5
- package/dist/execution/service/serving/delivery.d.ts +6 -0
- package/dist/execution/service/{publication → serving}/delivery.js +5 -1
- package/dist/execution/service/{publication → serving}/index.d.ts +1 -1
- package/dist/execution/service/serving/installation.d.ts +4 -0
- package/dist/execution/service/serving/installation.js +9 -0
- package/dist/execution/service/serving/legacy/index.d.ts +15 -0
- package/dist/execution/service/serving/legacy/index.js +19 -0
- package/dist/execution/service/serving/source.d.ts +18 -0
- package/dist/execution/service/serving/source.js +19 -0
- package/dist/project/define.js +57 -28
- package/dist/project/install-command.d.ts +10 -0
- package/dist/project/install-command.js +13 -0
- package/dist/project/project.d.ts +4 -2
- package/dist/tooling/cli/arguments.d.ts +0 -2
- package/dist/tooling/cli/arguments.js +22 -15
- package/dist/tooling/cli/commit.d.ts +23 -0
- package/dist/tooling/cli/commit.js +216 -0
- package/dist/tooling/cli/deploy-mode.d.ts +19 -12
- package/dist/tooling/cli/deploy-mode.js +14 -32
- package/dist/tooling/cli/deploy-result.d.ts +10 -7
- package/dist/tooling/cli/deploy-result.js +4 -3
- package/dist/tooling/cli/development/candidate.d.ts +2 -3
- package/dist/tooling/cli/development/candidate.js +2 -9
- package/dist/tooling/cli/development/deployment.d.ts +2 -8
- package/dist/tooling/cli/development/deployment.js +2 -21
- package/dist/tooling/cli/development/develop.d.ts +4 -3
- package/dist/tooling/cli/development/develop.js +8 -112
- package/dist/tooling/cli/development/report.d.ts +1 -3
- package/dist/tooling/cli/development/report.js +1 -4
- package/dist/tooling/cli/help.js +28 -26
- package/dist/tooling/cli/immutable-deployment.d.ts +27 -0
- package/dist/tooling/cli/immutable-deployment.js +95 -0
- package/dist/tooling/cli/index.d.ts +2 -4
- package/dist/tooling/cli/index.js +2 -3
- package/dist/tooling/cli/legacy/deploy-result.d.ts +5 -3
- package/dist/tooling/cli/legacy/deploy-result.js +5 -3
- package/dist/tooling/cli/legacy/stable-target-adapter.d.ts +5 -3
- package/dist/tooling/cli/legacy/stable-target-deploy.d.ts +42 -0
- package/dist/tooling/cli/legacy/stable-target-deploy.js +104 -0
- package/dist/tooling/cli/orchestrate.js +46 -97
- package/dist/tooling/cli/secrets.d.ts +9 -0
- package/dist/tooling/cli/secrets.js +19 -0
- package/package.json +1 -1
- package/dist/deployment/verify/readiness/publication.d.ts +0 -11
- package/dist/deployment/verify/readiness/publication.js +0 -41
- package/dist/execution/service/publication/delivery.d.ts +0 -2
- package/dist/execution/service/publication/installation.d.ts +0 -3
- package/dist/execution/service/publication/installation.js +0 -8
- package/dist/execution/service/publication/source.d.ts +0 -3
- package/dist/execution/service/publication/source.js +0 -11
- package/dist/tooling/cli/astrale/authority.d.ts +0 -5
- package/dist/tooling/cli/astrale/authority.js +0 -11
- package/dist/tooling/cli/astrale/executable.d.ts +0 -2
- package/dist/tooling/cli/astrale/executable.js +0 -47
- package/dist/tooling/cli/astrale/failure.d.ts +0 -6
- package/dist/tooling/cli/astrale/failure.js +0 -48
- package/dist/tooling/cli/astrale/instance.d.ts +0 -11
- package/dist/tooling/cli/astrale/instance.js +0 -52
- package/dist/tooling/cli/astrale/process.d.ts +0 -13
- package/dist/tooling/cli/astrale/process.js +0 -94
- package/dist/tooling/cli/astrale/version.d.ts +0 -18
- package/dist/tooling/cli/astrale/version.js +0 -55
- package/dist/tooling/cli/development/release-evidence.d.ts +0 -4
- package/dist/tooling/cli/development/release-evidence.js +0 -10
- package/dist/tooling/cli/development/session-file.d.ts +0 -53
- package/dist/tooling/cli/development/session-file.js +0 -337
- package/dist/tooling/cli/development/target-lock.d.ts +0 -16
- package/dist/tooling/cli/development/target-lock.js +0 -68
- package/dist/tooling/cli/development/view.d.ts +0 -28
- package/dist/tooling/cli/development/view.js +0 -151
- package/dist/tooling/cli/environment-release.d.ts +0 -24
- package/dist/tooling/cli/environment-release.js +0 -46
- package/dist/tooling/cli/evidence.d.ts +0 -14
- package/dist/tooling/cli/evidence.js +0 -53
- package/dist/tooling/cli/installation/index.d.ts +0 -2
- package/dist/tooling/cli/installation/index.js +0 -1
- package/dist/tooling/cli/installation/observation.d.ts +0 -10
- package/dist/tooling/cli/installation/observation.js +0 -44
- package/dist/tooling/cli/installation/reconcile.d.ts +0 -32
- package/dist/tooling/cli/installation/reconcile.js +0 -122
- /package/dist/execution/service/{publication → serving}/index.js +0 -0
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { rm, rmdir } from 'node:fs/promises';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
|
-
import { resolveAstraleInstanceIssuer } from '../astrale/instance.js';
|
|
4
|
-
import { resolveCompatibleAstrale } from '../astrale/version.js';
|
|
5
3
|
import { loadPrivateCredentialFile } from '../credential.js';
|
|
6
4
|
import { deprecationWarnings } from '../deprecations.js';
|
|
7
5
|
import { loadPrivateSecretsFile } from '../dotenv.js';
|
|
@@ -11,31 +9,21 @@ import { deployDevelopmentCandidate } from './deployment.js';
|
|
|
11
9
|
import { DevelopmentLifecycle } from './lifecycle.js';
|
|
12
10
|
import { acquireProjectLock } from './project-lock.js';
|
|
13
11
|
import { LatestRebuild } from './rebuild.js';
|
|
14
|
-
import { developmentReleaseEvidence } from './release-evidence.js';
|
|
15
12
|
import { reportDevelopmentDeployment } from './report.js';
|
|
16
|
-
import { DevelopmentSessionFileWriter } from './session-file.js';
|
|
17
13
|
import { watchSources } from './source-watch.js';
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
14
|
+
/**
|
|
15
|
+
* Watch one Project Environment and serialize complete remote deployment generations. Each
|
|
16
|
+
* generation replaces the Environment's stable target in place; none installs anything.
|
|
17
|
+
*/
|
|
21
18
|
export async function develop(input) {
|
|
22
19
|
const lifecycle = new DevelopmentLifecycle();
|
|
23
|
-
let sessionFile;
|
|
24
20
|
let lock;
|
|
25
|
-
let targetLock;
|
|
26
|
-
let view;
|
|
27
|
-
let installationExecutable;
|
|
28
|
-
let installationIssuer;
|
|
29
21
|
let sourceWatch;
|
|
30
22
|
let rebuild;
|
|
31
23
|
let current;
|
|
32
|
-
let lastEvidence;
|
|
33
24
|
let failure;
|
|
34
25
|
const cleanup = [];
|
|
35
26
|
try {
|
|
36
|
-
if (input.sessionFile !== undefined) {
|
|
37
|
-
sessionFile = await DevelopmentSessionFileWriter.create(input.sessionFile);
|
|
38
|
-
}
|
|
39
27
|
lock = await acquireProjectLock({
|
|
40
28
|
projectRoot: input.projectDir,
|
|
41
29
|
environment: input.environment,
|
|
@@ -53,53 +41,15 @@ export async function develop(input) {
|
|
|
53
41
|
overrideSecrets,
|
|
54
42
|
});
|
|
55
43
|
current = await builder.prepare(lifecycle.signal);
|
|
56
|
-
if (credential !== undefined && current.installation?.identity !== undefined) {
|
|
57
|
-
throw new TypeError('--credential-file cannot be combined with the Environment installation identity.');
|
|
58
|
-
}
|
|
59
|
-
if (sessionFile !== undefined && (current.installation === undefined || input.deployOnly)) {
|
|
60
|
-
throw new TypeError('--session-file requires an Environment installation that is active for this development session.');
|
|
61
|
-
}
|
|
62
44
|
info(`Domain: ${current.artifact.build.schema.compiled.root.origin}`);
|
|
63
45
|
for (const warning of deprecationWarnings(current.artifact.build))
|
|
64
46
|
warn(warning);
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
projectDir: input.projectDir,
|
|
68
|
-
signal: lifecycle.signal,
|
|
69
|
-
});
|
|
70
|
-
installationIssuer = await resolveAstraleInstanceIssuer({
|
|
71
|
-
executable: installationExecutable,
|
|
72
|
-
projectDir: input.projectDir,
|
|
73
|
-
instance: current.installation.instance,
|
|
74
|
-
signal: lifecycle.signal,
|
|
75
|
-
});
|
|
76
|
-
targetLock = await acquireDevelopmentTargetLock({
|
|
77
|
-
issuer: installationIssuer,
|
|
78
|
-
origin: current.artifact.build.schema.compiled.root.origin,
|
|
79
|
-
});
|
|
80
|
-
view = new DevelopmentView({
|
|
81
|
-
executable: installationExecutable,
|
|
82
|
-
projectDir: input.projectDir,
|
|
83
|
-
instance: current.installation.instance,
|
|
84
|
-
...(credential === undefined
|
|
85
|
-
? { identity: input.identity ?? current.installation.identity }
|
|
86
|
-
: { credential }),
|
|
87
|
-
});
|
|
88
|
-
if (current.artifact.build.frontend !== undefined)
|
|
89
|
-
await view.prepare(lifecycle.signal);
|
|
90
|
-
}
|
|
91
|
-
const first = await deployDevelopmentCandidate(current, { ...input, credential, installationExecutable }, lifecycle.signal);
|
|
92
|
-
lastEvidence =
|
|
93
|
-
first.installation === undefined ? undefined : developmentReleaseEvidence(first.installation);
|
|
94
|
-
await sessionFile?.transition('ready', lastEvidence);
|
|
95
|
-
reportDevelopmentDeployment(first.deployment, first.installation, current.adapter, input);
|
|
96
|
-
await refreshView(view, first.deployment.release, lifecycle.signal);
|
|
47
|
+
const first = await deployDevelopmentCandidate(current, { ...input, ...(credential === undefined ? {} : { credential }) }, lifecycle.signal);
|
|
48
|
+
reportDevelopmentDeployment(first, current.adapter, input);
|
|
97
49
|
let restartReported = false;
|
|
98
50
|
rebuild = new LatestRebuild({
|
|
99
51
|
async prepare(_ignored, signal) {
|
|
100
52
|
info(`Rebuilding: ${input.environment}`);
|
|
101
|
-
if (lastEvidence !== undefined)
|
|
102
|
-
await sessionFile?.transition('updating', lastEvidence);
|
|
103
53
|
return builder.prepare(signal);
|
|
104
54
|
},
|
|
105
55
|
async commit(candidate, signal) {
|
|
@@ -109,45 +59,17 @@ export async function develop(input) {
|
|
|
109
59
|
}
|
|
110
60
|
if (sameDeploymentCandidate(current, candidate)) {
|
|
111
61
|
current = candidate;
|
|
112
|
-
await sessionFile?.transition('ready', lastEvidence);
|
|
113
62
|
sourceWatch?.update(candidate.sources);
|
|
114
63
|
return;
|
|
115
64
|
}
|
|
116
|
-
|
|
117
|
-
await resolveAstraleInstanceIssuer({
|
|
118
|
-
executable: installationExecutable,
|
|
119
|
-
projectDir: input.projectDir,
|
|
120
|
-
instance: candidate.installation.instance,
|
|
121
|
-
expectedIssuer: installationIssuer,
|
|
122
|
-
signal,
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
if (candidate.artifact.build.frontend !== undefined)
|
|
126
|
-
await view?.prepare(signal);
|
|
127
|
-
const deployed = await deployDevelopmentCandidate(candidate, { ...input, credential, installationExecutable }, signal);
|
|
65
|
+
const deployed = await deployDevelopmentCandidate(candidate, { ...input, ...(credential === undefined ? {} : { credential }) }, signal);
|
|
128
66
|
current = candidate;
|
|
129
|
-
lastEvidence =
|
|
130
|
-
deployed.installation === undefined
|
|
131
|
-
? undefined
|
|
132
|
-
: developmentReleaseEvidence(deployed.installation);
|
|
133
|
-
await sessionFile?.transition('ready', lastEvidence);
|
|
134
67
|
sourceWatch?.update(candidate.sources);
|
|
135
68
|
info(`Updated: ${candidate.artifact.build.schema.compiled.root.revision}`);
|
|
136
|
-
reportDevelopmentDeployment(deployed
|
|
137
|
-
await refreshView(view, deployed.deployment.release, signal);
|
|
69
|
+
reportDevelopmentDeployment(deployed, candidate.adapter, input);
|
|
138
70
|
},
|
|
139
71
|
async failed(cause) {
|
|
140
72
|
error(cause instanceof Error ? cause.message : String(cause));
|
|
141
|
-
if (lastEvidence === undefined)
|
|
142
|
-
return;
|
|
143
|
-
try {
|
|
144
|
-
await sessionFile?.transition('recovering', lastEvidence);
|
|
145
|
-
}
|
|
146
|
-
catch (sessionCause) {
|
|
147
|
-
const terminal = new AggregateError([cause, sessionCause], 'Development rebuild failed and session evidence could not be recovered.');
|
|
148
|
-
failure ??= terminal;
|
|
149
|
-
lifecycle.stop(terminal);
|
|
150
|
-
}
|
|
151
73
|
},
|
|
152
74
|
});
|
|
153
75
|
sourceWatch = watchSources({
|
|
@@ -176,21 +98,13 @@ export async function develop(input) {
|
|
|
176
98
|
failure = cause;
|
|
177
99
|
}
|
|
178
100
|
lifecycle.stop(failure);
|
|
179
|
-
try {
|
|
180
|
-
await sessionFile?.transition('stopping', lastEvidence);
|
|
181
|
-
}
|
|
182
|
-
catch (cause) {
|
|
183
|
-
failure ??= cause;
|
|
184
|
-
}
|
|
185
101
|
for (const operation of [
|
|
186
102
|
() => sourceWatch?.stop(),
|
|
187
103
|
() => rebuild?.stop(failure),
|
|
188
|
-
() => view?.close(AbortSignal.timeout(30_000)),
|
|
189
104
|
() => rm(join(input.projectDir, '.astrale', 'development', input.environment, 'source'), {
|
|
190
105
|
recursive: true,
|
|
191
106
|
force: true,
|
|
192
107
|
}),
|
|
193
|
-
() => targetLock?.release(),
|
|
194
108
|
() => lock?.release(),
|
|
195
109
|
]) {
|
|
196
110
|
try {
|
|
@@ -213,12 +127,6 @@ export async function develop(input) {
|
|
|
213
127
|
cleanup.push(cause);
|
|
214
128
|
}
|
|
215
129
|
}
|
|
216
|
-
try {
|
|
217
|
-
await sessionFile?.transition(failure === undefined && cleanup.length === 0 ? 'stopped' : 'failed');
|
|
218
|
-
}
|
|
219
|
-
catch (cause) {
|
|
220
|
-
cleanup.push(cause);
|
|
221
|
-
}
|
|
222
130
|
lifecycle.dispose();
|
|
223
131
|
if (failure !== undefined) {
|
|
224
132
|
if (cleanup.length > 0)
|
|
@@ -229,15 +137,3 @@ export async function develop(input) {
|
|
|
229
137
|
throw new AggregateError(cleanup, 'Development cleanup failed.');
|
|
230
138
|
return 0;
|
|
231
139
|
}
|
|
232
|
-
async function refreshView(view, release, signal) {
|
|
233
|
-
if (view === undefined)
|
|
234
|
-
return;
|
|
235
|
-
try {
|
|
236
|
-
const pageUrl = await view.refresh(release, signal);
|
|
237
|
-
if (pageUrl !== undefined)
|
|
238
|
-
info(`View: ${pageUrl}`);
|
|
239
|
-
}
|
|
240
|
-
catch (cause) {
|
|
241
|
-
error(`View unavailable: ${cause instanceof Error ? cause.message : String(cause)}`);
|
|
242
|
-
}
|
|
243
|
-
}
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import type { ReadyDeployResult } from '../../../deployment/adapter/index.js';
|
|
2
|
-
|
|
3
|
-
export declare function reportDevelopmentDeployment(deployed: ReadyDeployResult, installation: InstallationEvidence | undefined, adapter: {
|
|
2
|
+
export declare function reportDevelopmentDeployment(deployed: ReadyDeployResult, adapter: {
|
|
4
3
|
readonly name: string;
|
|
5
4
|
readonly version: string;
|
|
6
5
|
}, input: {
|
|
7
6
|
readonly environment: string;
|
|
8
|
-
readonly deployOnly: boolean;
|
|
9
7
|
}): void;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { info } from '../log.js';
|
|
2
|
-
export function reportDevelopmentDeployment(deployed,
|
|
2
|
+
export function reportDevelopmentDeployment(deployed, adapter, input) {
|
|
3
3
|
info(`Environment: ${input.environment}`);
|
|
4
4
|
info(`Adapter: ${adapter.name}@${adapter.version}`);
|
|
5
5
|
info(`Deployment: ${deployed.progress.provider.evidence.deployment}`);
|
|
@@ -8,7 +8,4 @@ export function reportDevelopmentDeployment(deployed, installation, adapter, inp
|
|
|
8
8
|
}
|
|
9
9
|
info(`Public: ${deployed.release.addressing.publicUrl}`);
|
|
10
10
|
info(`Publication: ${deployed.release.publication.schema.revision} · ${deployed.release.publication.etag}`);
|
|
11
|
-
info(installation === undefined
|
|
12
|
-
? `Installation: skipped${input.deployOnly ? ' (--deploy-only)' : ''}`
|
|
13
|
-
: `Installation: ${installation.instance} · ${installation.status}`);
|
|
14
11
|
}
|
package/dist/tooling/cli/help.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { installCommand } from '../../project/install-command.js';
|
|
1
2
|
import { COMMANDS } from './arguments.js';
|
|
2
3
|
/** Resolve help without parsing a project or performing any command effects. */
|
|
3
4
|
export function helpRequest(argv) {
|
|
@@ -20,7 +21,7 @@ Usage:
|
|
|
20
21
|
Commands:
|
|
21
22
|
dev [environment] Remotely deploy and watch one Project Environment.
|
|
22
23
|
build Build, verify and print the build digest.
|
|
23
|
-
deploy <environment> Deploy
|
|
24
|
+
deploy <environment> Deploy one Environment; never installs.
|
|
24
25
|
test Run Project tests, optionally against one Environment.
|
|
25
26
|
lint Check Domain source and architecture.
|
|
26
27
|
package Prepare public declarations for publication.
|
|
@@ -65,12 +66,9 @@ Arguments:
|
|
|
65
66
|
|
|
66
67
|
Options:
|
|
67
68
|
--environment <name> Select the environment without a positional argument.
|
|
68
|
-
--
|
|
69
|
-
--as <identity> Select the Astrale identity for Services and installation calls.
|
|
70
|
-
--session-file <path> Write one retained DevelopmentSessionFileV1 snapshot at an
|
|
71
|
-
absolute path in a caller-owned private directory.
|
|
69
|
+
--as <identity> Select the Astrale identity for the adapter's provider calls.
|
|
72
70
|
--credential-file <path>
|
|
73
|
-
Use one private operator credential for
|
|
71
|
+
Use one private operator credential for the adapter's provider
|
|
74
72
|
calls without exposing it in Project configuration.
|
|
75
73
|
--secrets-file <path> Load one private, absolute secrets file for this development
|
|
76
74
|
session instead of the adapter-declared secrets file.
|
|
@@ -80,25 +78,23 @@ Behavior:
|
|
|
80
78
|
The selected Environment must exist; no other Environment is chosen as a fallback.
|
|
81
79
|
Builds and verifies the Domain, Runtime, frontend, and adapter artifact, then
|
|
82
80
|
deploys it through the selected Environment. It never starts a local Worker,
|
|
83
|
-
Vite server, or tunnel
|
|
84
|
-
|
|
81
|
+
Vite server, or tunnel, and never installs the Domain: install the URL it prints with
|
|
82
|
+
${installCommand()}. Imported source changes
|
|
83
|
+
produce serialized remote updates; configuration changes require restarting the
|
|
84
|
+
command. It serves only legacy direct-mode Environments; an Environment that
|
|
85
|
+
deploys immutable deployments is refused.
|
|
85
86
|
A shared direct-provider target additionally requires an external single-writer
|
|
86
87
|
boundary such as a CI/CD concurrency group.
|
|
87
|
-
The session file is machine-readable and authoritative when requested; human
|
|
88
|
-
stdout/stderr remains diagnostic. It requires an adapter that reports exact
|
|
89
|
-
installed Release evidence, so it is rejected for an Environment without an
|
|
90
|
-
installation and when --deploy-only suppresses installation.
|
|
91
88
|
A credential file is admitted and read once. Its value is passed only to the
|
|
92
|
-
deployment adapter
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
admission is absent.
|
|
89
|
+
deployment adapter; it never enters Domain Runtime secrets or diagnostics. It is
|
|
90
|
+
currently unavailable on Windows because private no-reparse file admission is
|
|
91
|
+
absent.
|
|
96
92
|
A secrets-file override is read once, passed to the Domain runtime as secrets,
|
|
97
93
|
never mutates the authored project, and is not watched for later changes. It is
|
|
98
94
|
also unavailable on Windows because private no-reparse admission is absent.
|
|
99
95
|
|
|
100
96
|
Stopping the watcher stops only local build orchestration. The remote deployment
|
|
101
|
-
|
|
97
|
+
remains available.
|
|
102
98
|
`,
|
|
103
99
|
build: `Build and verify a Domain without deploying it, and print its build digest.
|
|
104
100
|
|
|
@@ -129,20 +125,26 @@ Arguments:
|
|
|
129
125
|
Options:
|
|
130
126
|
--environment <name> Select the environment without a positional argument.
|
|
131
127
|
--json Print one DeployResultV1 on stdout; progress goes to stderr.
|
|
132
|
-
--
|
|
133
|
-
--as <identity> Select the Astrale identity for Services and installation calls.
|
|
128
|
+
--as <identity> Select the Astrale identity for the adapter's provider calls.
|
|
134
129
|
-h, --help Show help for deploy.
|
|
135
130
|
|
|
136
131
|
Behavior:
|
|
137
|
-
Builds and verifies the Domain
|
|
138
|
-
secrets, and
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
132
|
+
Builds and verifies the Domain and Runtime, rebuilds the Bundle exactly as build
|
|
133
|
+
does, loads declared secrets, and deploys through the selected adapter. It never
|
|
134
|
+
installs the Domain: install the URL it prints with
|
|
135
|
+
${installCommand()}.
|
|
136
|
+
The Environment's configuration selects how it deploys. An adapter that implements
|
|
137
|
+
deployRelease makes one immutable deployment per release with no Kernel call: the
|
|
138
|
+
SDK seals the release for the deployment's URL, records the commit it was built
|
|
139
|
+
from, and the adapter creates that deployment or reuses it. Any other Environment
|
|
140
|
+
replaces its stable target in place (legacy direct mode, deprecated), warns on
|
|
141
|
+
stderr, serves a v3 Publication only, and warns when the uploaded code has another
|
|
142
|
+
build digest than the Bundle. Among those, adapter-astrale's instance mode still
|
|
143
|
+
calls the Services of its instance through that instance's Kernel, and installs
|
|
144
|
+
the Services Domain there when it is missing.
|
|
143
145
|
With --json, stdout holds only one DeployResultV1: the deployment's URL, which
|
|
144
146
|
astrale domain install takes, its digests, adapter and state. Exit status: 0 deployed,
|
|
145
|
-
1 failed, 2 usage error; a failed run prints nothing on stdout.
|
|
147
|
+
1 failed or refused, 2 usage error; a failed run prints nothing on stdout.
|
|
146
148
|
`,
|
|
147
149
|
test: `Run Project tests locally or against one selected Environment.
|
|
148
150
|
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { Adapter, Build, LegacyAdapter, ResolvedRuntimeReference } from '../../deployment/index.js';
|
|
2
|
+
import type { DeployResultV1 } from './deploy-result.js';
|
|
3
|
+
/**
|
|
4
|
+
* Deploy one canonical Environment (CT33) as the immutable deployment of one sealed release.
|
|
5
|
+
*
|
|
6
|
+
* The SDK derives everything before the adapter's only effectful call: it bundles exactly as
|
|
7
|
+
* `astrale-domain build` does, asks the adapter to freeze the Environment's configuration and say
|
|
8
|
+
* where its host places deployments, derives the deployment label and URL from them (S3), seals
|
|
9
|
+
* the `DomainRelease` v4 the deployment serves at that URL (S4a), and reads the commit it is built
|
|
10
|
+
* from. `deployRelease` then creates that deployment or reuses it. The SDK makes no Kernel call,
|
|
11
|
+
* the deploy calls no instance and installs nothing: `astrale domain install <url>` installs the
|
|
12
|
+
* URL it prints.
|
|
13
|
+
*
|
|
14
|
+
* Returns the deploy result, or nothing once a failure is reported on stderr.
|
|
15
|
+
*/
|
|
16
|
+
export declare function deployImmutable(input: {
|
|
17
|
+
readonly projectDir: string;
|
|
18
|
+
readonly environment: string;
|
|
19
|
+
/** A canonical Environment's adapter (CT33), which implements adapter interface v2. */
|
|
20
|
+
readonly adapter: Adapter<object> | LegacyAdapter<object>;
|
|
21
|
+
readonly parameters: object;
|
|
22
|
+
readonly build: Build;
|
|
23
|
+
readonly runtime: ResolvedRuntimeReference;
|
|
24
|
+
readonly identity?: string;
|
|
25
|
+
readonly signal: AbortSignal;
|
|
26
|
+
readonly report: (line: string) => void;
|
|
27
|
+
}): Promise<DeployResultV1 | undefined>;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { resolve } from 'node:path';
|
|
2
|
+
import { deploymentContent, deploymentLabel, deploymentLine, deploymentUrl, } from '../../deployment/address/index.js';
|
|
3
|
+
import { assemble } from '../../deployment/index.js';
|
|
4
|
+
import { bundleBuild } from './build.js';
|
|
5
|
+
import { deploymentCommit } from './commit.js';
|
|
6
|
+
import { deployResult } from './deploy-result.js';
|
|
7
|
+
import { error } from './log.js';
|
|
8
|
+
import { environmentSecrets } from './secrets.js';
|
|
9
|
+
/**
|
|
10
|
+
* Deploy one canonical Environment (CT33) as the immutable deployment of one sealed release.
|
|
11
|
+
*
|
|
12
|
+
* The SDK derives everything before the adapter's only effectful call: it bundles exactly as
|
|
13
|
+
* `astrale-domain build` does, asks the adapter to freeze the Environment's configuration and say
|
|
14
|
+
* where its host places deployments, derives the deployment label and URL from them (S3), seals
|
|
15
|
+
* the `DomainRelease` v4 the deployment serves at that URL (S4a), and reads the commit it is built
|
|
16
|
+
* from. `deployRelease` then creates that deployment or reuses it. The SDK makes no Kernel call,
|
|
17
|
+
* the deploy calls no instance and installs nothing: `astrale domain install <url>` installs the
|
|
18
|
+
* URL it prints.
|
|
19
|
+
*
|
|
20
|
+
* Returns the deploy result, or nothing once a failure is reported on stderr.
|
|
21
|
+
*/
|
|
22
|
+
export async function deployImmutable(input) {
|
|
23
|
+
const { parameters, environment, build, signal } = input;
|
|
24
|
+
const adapter = releaseAdapter(input.adapter);
|
|
25
|
+
const identity = input.identity === undefined ? {} : { identity: input.identity };
|
|
26
|
+
const bundle = await bundleBuild({
|
|
27
|
+
bundler: adapter.bundler,
|
|
28
|
+
projectDir: input.projectDir,
|
|
29
|
+
build,
|
|
30
|
+
runtime: input.runtime,
|
|
31
|
+
signal,
|
|
32
|
+
});
|
|
33
|
+
const secrets = environmentSecrets(adapter, parameters, input.projectDir, input.runtime.runtime);
|
|
34
|
+
const configuration = adapter.configure(parameters, {
|
|
35
|
+
environment,
|
|
36
|
+
secrets: Object.freeze(Object.keys(secrets).sort()),
|
|
37
|
+
});
|
|
38
|
+
const placement = await adapter.placement(parameters, { environment, signal, ...identity });
|
|
39
|
+
const origin = build.schema.compiled.root.origin;
|
|
40
|
+
const label = deploymentLabel(deploymentLine({ origin, environment, addressing: placement.addressing }), deploymentContent(bundle.digest, configuration));
|
|
41
|
+
const release = assemble(build, bundle.digest, deploymentUrl(label, placement.routingDomain));
|
|
42
|
+
const commit = await deploymentCommit({
|
|
43
|
+
projectDir: input.projectDir,
|
|
44
|
+
// The configuration sits in the Project directory, and names its runtime relative to it.
|
|
45
|
+
runtimeModule: resolve(input.projectDir, input.runtime.reference.path),
|
|
46
|
+
signal,
|
|
47
|
+
});
|
|
48
|
+
const deployed = await adapter.deployRelease(parameters, {
|
|
49
|
+
projectDir: input.projectDir,
|
|
50
|
+
environment,
|
|
51
|
+
...identity,
|
|
52
|
+
secrets,
|
|
53
|
+
bundle,
|
|
54
|
+
configuration,
|
|
55
|
+
placement,
|
|
56
|
+
label,
|
|
57
|
+
release,
|
|
58
|
+
commit,
|
|
59
|
+
signal,
|
|
60
|
+
});
|
|
61
|
+
if (deployed.status !== 'ready') {
|
|
62
|
+
error(`Deployment failed during ${deployed.phase}: ${deployed.error.message}`);
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
65
|
+
const result = deployResult({ environment, adapter, release, deployment: deployed });
|
|
66
|
+
input.report(`Domain: ${result.origin}`);
|
|
67
|
+
input.report(`Environment: ${environment}`);
|
|
68
|
+
input.report(`Adapter: ${result.deployment.adapter}`);
|
|
69
|
+
input.report(`Deployment: ${label} · ${result.deployment.state}`);
|
|
70
|
+
input.report(`URL: ${result.url}`);
|
|
71
|
+
input.report(`Release: ${release.document.digest}`);
|
|
72
|
+
input.report(`Build: ${release.buildDigest}`);
|
|
73
|
+
input.report(secretsLine(label, result.secrets.state));
|
|
74
|
+
input.report('Ready: deployment verified');
|
|
75
|
+
return result;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* What the deploy did to the secrets of the one deployment it made or reused: `bound` to the new
|
|
79
|
+
* deployment, or `updated` or left `unchanged` in place on the reused one. No other deployment's
|
|
80
|
+
* secrets are ever written. A value rewritten in place is served once the host propagated it,
|
|
81
|
+
* which is eventually consistent (about 4 s on Workers for Platforms, AM-114).
|
|
82
|
+
*/
|
|
83
|
+
function secretsLine(label, state) {
|
|
84
|
+
return state === 'updated'
|
|
85
|
+
? `Secrets: updated in place on ${label}; the new values are served once propagated ` +
|
|
86
|
+
'(eventually consistent, about 4 s)'
|
|
87
|
+
: `Secrets: ${state}`;
|
|
88
|
+
}
|
|
89
|
+
/** The adapter of a canonical Environment: CT33 selects canonical only beside `deployRelease`. */
|
|
90
|
+
function releaseAdapter(adapter) {
|
|
91
|
+
if (!('deployRelease' in adapter) || typeof adapter.deployRelease !== 'function') {
|
|
92
|
+
throw new TypeError(`Adapter ${adapter.name}@${adapter.version} implements no deployRelease and deploys no immutable deployment.`);
|
|
93
|
+
}
|
|
94
|
+
return adapter;
|
|
95
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `@astrale-os/sdk/cli` — the `astrale-domain` CLI
|
|
3
|
-
* (dev | build | deploy | test | lint | package),
|
|
4
|
-
*
|
|
3
|
+
* (dev | build | deploy | test | lint | package), its JSON results, and the explicit dotenv
|
|
4
|
+
* boundary.
|
|
5
5
|
*
|
|
6
6
|
* Node-only: the CLI imports `node:fs`/`node:module`/`node:url` and runs under
|
|
7
7
|
* Bun (it imports the project's `astrale.config.ts` directly). This subpath is
|
|
@@ -14,5 +14,3 @@ export { run } from './run.js';
|
|
|
14
14
|
export type { BuildResultV1 } from './build.js';
|
|
15
15
|
export type { DeployResultV1, DeploymentSecretsState } from './deploy-result.js';
|
|
16
16
|
export { loadDeclaredSecrets } from './dotenv.js';
|
|
17
|
-
export { DEVELOPMENT_SESSION_FILE_VERSION, acceptDevelopmentSessionFileV1, } from './development/session-file.js';
|
|
18
|
-
export type { DevelopmentSessionFileV1, DevelopmentSessionPhaseV1, DevelopmentSessionProjectV1, DevelopmentSessionReleaseV1, } from './development/session-file.js';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `@astrale-os/sdk/cli` — the `astrale-domain` CLI
|
|
3
|
-
* (dev | build | deploy | test | lint | package),
|
|
4
|
-
*
|
|
3
|
+
* (dev | build | deploy | test | lint | package), its JSON results, and the explicit dotenv
|
|
4
|
+
* boundary.
|
|
5
5
|
*
|
|
6
6
|
* Node-only: the CLI imports `node:fs`/`node:module`/`node:url` and runs under
|
|
7
7
|
* Bun (it imports the project's `astrale.config.ts` directly). This subpath is
|
|
@@ -12,4 +12,3 @@
|
|
|
12
12
|
*/
|
|
13
13
|
export { run } from './run.js';
|
|
14
14
|
export { loadDeclaredSecrets } from './dotenv.js';
|
|
15
|
-
export { DEVELOPMENT_SESSION_FILE_VERSION, acceptDevelopmentSessionFileV1, } from './development/session-file.js';
|
|
@@ -12,9 +12,11 @@ import type { DeployResultV1 } from '../deploy-result.js';
|
|
|
12
12
|
*
|
|
13
13
|
* @deprecated Stable-target deploy path only. Replacement: `deployResult`, the result of an
|
|
14
14
|
* immutable deployment. Consumers: the direct-mode configurations of domains ai-gateway, closing,
|
|
15
|
-
* grc, integrations and issues (until SV15),
|
|
16
|
-
*
|
|
17
|
-
*
|
|
15
|
+
* grc, integrations and issues (until SV15), domains organization (until it leaves direct mode,
|
|
16
|
+
* AM-147), the Services `beta` and `prod` (until SV12), `development` (until SV9) and frozen
|
|
17
|
+
* `admin-beta` (until D19) environments, shell (until SH2) and its frozen `legacy-v3` (until D22),
|
|
18
|
+
* and ui:domain (until UI1). Deleted with the legacy deploy path (D10), once no configuration on
|
|
19
|
+
* any repository's main selects it (CT33, AM-147).
|
|
18
20
|
*/
|
|
19
21
|
export declare function stableTargetDeployResult(input: {
|
|
20
22
|
readonly environment: string;
|
|
@@ -10,9 +10,11 @@
|
|
|
10
10
|
*
|
|
11
11
|
* @deprecated Stable-target deploy path only. Replacement: `deployResult`, the result of an
|
|
12
12
|
* immutable deployment. Consumers: the direct-mode configurations of domains ai-gateway, closing,
|
|
13
|
-
* grc, integrations and issues (until SV15),
|
|
14
|
-
*
|
|
15
|
-
*
|
|
13
|
+
* grc, integrations and issues (until SV15), domains organization (until it leaves direct mode,
|
|
14
|
+
* AM-147), the Services `beta` and `prod` (until SV12), `development` (until SV9) and frozen
|
|
15
|
+
* `admin-beta` (until D19) environments, shell (until SH2) and its frozen `legacy-v3` (until D22),
|
|
16
|
+
* and ui:domain (until UI1). Deleted with the legacy deploy path (D10), once no configuration on
|
|
17
|
+
* any repository's main selects it (CT33, AM-147).
|
|
16
18
|
*/
|
|
17
19
|
export function stableTargetDeployResult(input) {
|
|
18
20
|
const { publication, addressing } = input.deployment.release;
|
|
@@ -5,9 +5,11 @@ import type { Adapter, LegacyAdapter } from '../../../deployment/adapter/index.j
|
|
|
5
5
|
*
|
|
6
6
|
* @deprecated Stable-target deploy path only. Replacement: `deployRelease` of adapter interface
|
|
7
7
|
* v2. Consumers: `astrale-domain deploy` and `astrale-domain dev` on the direct-mode
|
|
8
|
-
* configurations of domains ai-gateway, closing, grc, integrations and issues (until SV15),
|
|
9
|
-
* (until
|
|
10
|
-
*
|
|
8
|
+
* configurations of domains ai-gateway, closing, grc, integrations and issues (until SV15), domains
|
|
9
|
+
* organization (until it leaves direct mode, AM-147), the Services `beta` and `prod` (until SV12),
|
|
10
|
+
* `development` (until SV9) and frozen `admin-beta` (until D19) environments, shell (until SH2)
|
|
11
|
+
* and its frozen `legacy-v3` (until D22), and ui:domain (until UI1). Deleted with the legacy
|
|
12
|
+
* deploy path (D10), once no configuration on any repository's main selects it (CT33, AM-147).
|
|
11
13
|
*/
|
|
12
14
|
export type StableTargetAdapter<Parameters extends object = object> = (Adapter<Parameters> | LegacyAdapter<Parameters>) & Pick<LegacyAdapter<Parameters>, 'prepare' | 'deploy'>;
|
|
13
15
|
/**
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { Build, ResolvedRuntimeReference } from '../../../deployment/index.js';
|
|
2
|
+
import type { LegacyDirectReason } from '../deploy-mode.js';
|
|
3
|
+
import type { DeployResultV1 } from '../deploy-result.js';
|
|
4
|
+
import type { LoadedEnvironment } from '../project.js';
|
|
5
|
+
/**
|
|
6
|
+
* What a direct-mode deploy prints on stderr before any effect (AM-59): its Environment replaces
|
|
7
|
+
* one stable target in place and serves a v3 Publication only, which the deployment model
|
|
8
|
+
* replaces with one immutable deployment per release.
|
|
9
|
+
*
|
|
10
|
+
* @deprecated Stable-target deploy path only; see `deployStableTarget`.
|
|
11
|
+
*/
|
|
12
|
+
export declare function directModeDeprecation(environment: string, reasons: readonly LegacyDirectReason[]): string;
|
|
13
|
+
/**
|
|
14
|
+
* Deploy one Environment on the legacy direct-mode path (CT33): bundle exactly as
|
|
15
|
+
* `astrale-domain build` does, let `prepare` place that Bundle at the Environment's stable target
|
|
16
|
+
* and `deploy` replace the code it runs, then verify the v3 Publication it serves. It warns first,
|
|
17
|
+
* then behaves exactly as before. The SDK never installs the deployed Domain here and makes no
|
|
18
|
+
* Kernel call of its own; adapter-astrale's instance mode still calls the Services of its instance
|
|
19
|
+
* through that instance's Kernel, and installs the Services Domain there when it is missing.
|
|
20
|
+
*
|
|
21
|
+
* Returns the deploy result, or nothing once a failure is reported on stderr.
|
|
22
|
+
*
|
|
23
|
+
* @deprecated Stable-target deploy path only. Replacement: `deployImmutable`, the immutable
|
|
24
|
+
* deployment of one sealed release through `deployRelease`. Consumers: the direct-mode
|
|
25
|
+
* configurations of domains ai-gateway, closing, grc, integrations and issues (until SV15), domains
|
|
26
|
+
* organization (until it leaves direct mode, AM-147), the Services `beta` and `prod` (until SV12),
|
|
27
|
+
* `development` (until SV9) and frozen `admin-beta` (until D19) environments, shell (until SH2)
|
|
28
|
+
* and its frozen `legacy-v3` (until D22), ui:domain (until UI1), and adapter-astrale's instance
|
|
29
|
+
* mode until adapter-astrale implements deployRelease (S8). Deleted with the legacy deploy path
|
|
30
|
+
* (D10), once no configuration on any repository's main selects it (CT33, AM-147).
|
|
31
|
+
*/
|
|
32
|
+
export declare function deployStableTarget(input: {
|
|
33
|
+
readonly projectDir: string;
|
|
34
|
+
readonly environment: string;
|
|
35
|
+
readonly definition: LoadedEnvironment;
|
|
36
|
+
readonly reasons: readonly LegacyDirectReason[];
|
|
37
|
+
readonly build: Build;
|
|
38
|
+
readonly runtime: ResolvedRuntimeReference;
|
|
39
|
+
readonly identity?: string;
|
|
40
|
+
readonly signal: AbortSignal;
|
|
41
|
+
readonly report: (line: string) => void;
|
|
42
|
+
}): Promise<DeployResultV1 | undefined>;
|