@astrale-os/sdk 0.6.0-beta.13 → 0.6.0-beta.15
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 +9 -11
- 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 +12 -12
- package/dist/deployment/adapter/legacy/prepare/context.d.ts +0 -2
- package/dist/deployment/adapter/release/context.d.ts +23 -3
- package/dist/deployment/adapter/release/index.d.ts +1 -0
- package/dist/deployment/adapter/release/list.d.ts +41 -0
- package/dist/deployment/adapter/release/list.js +1 -0
- package/dist/deployment/address/index.d.ts +1 -1
- package/dist/deployment/address/index.js +1 -0
- package/dist/deployment/address/summary.d.ts +31 -1
- 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 +17 -12
- package/dist/deployment/release/legacy/index.js +17 -12
- 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 +14 -3
- package/dist/execution/identity/authentication.js +16 -7
- package/dist/execution/identity/callback.d.ts +5 -2
- package/dist/execution/identity/callback.js +11 -5
- package/dist/execution/identity/delivery.d.ts +11 -4
- package/dist/execution/identity/delivery.js +47 -20
- package/dist/execution/identity/identity.d.ts +12 -6
- package/dist/execution/identity/identity.js +3 -3
- 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/execution/workflows/run.js +1 -1
- package/dist/platform/versioning/name.d.ts +4 -3
- package/dist/platform/versioning/name.js +4 -3
- package/dist/project/define.js +58 -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 +1 -3
- package/dist/tooling/cli/arguments.js +51 -22
- 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 +16 -13
- package/dist/tooling/cli/deploy-mode.js +45 -36
- package/dist/tooling/cli/deploy-result.d.ts +10 -7
- package/dist/tooling/cli/deploy-result.js +4 -3
- package/dist/tooling/cli/dotenv.d.ts +2 -2
- package/dist/tooling/cli/dotenv.js +3 -33
- package/dist/tooling/cli/help.js +73 -29
- 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 +3 -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/{development → legacy/development}/candidate.d.ts +3 -4
- package/dist/tooling/cli/{development → legacy/development}/candidate.js +7 -14
- package/dist/tooling/cli/legacy/development/deployment.d.ts +10 -0
- package/dist/tooling/cli/legacy/development/deployment.js +20 -0
- package/dist/tooling/cli/legacy/development/deprecation.d.ts +11 -0
- package/dist/tooling/cli/legacy/development/deprecation.js +13 -0
- package/dist/tooling/cli/legacy/development/develop.d.ts +15 -0
- package/dist/tooling/cli/legacy/development/develop.js +142 -0
- package/dist/tooling/cli/legacy/development/index.d.ts +21 -0
- package/dist/tooling/cli/legacy/development/index.js +21 -0
- package/dist/tooling/cli/legacy/development/report.d.ts +7 -0
- package/dist/tooling/cli/{development → legacy/development}/report.js +2 -5
- package/dist/tooling/cli/legacy/development/secrets-file.d.ts +2 -0
- package/dist/tooling/cli/legacy/development/secrets-file.js +33 -0
- package/dist/tooling/cli/legacy/stable-target-adapter.d.ts +5 -3
- package/dist/tooling/cli/legacy/stable-target-deploy.d.ts +40 -0
- package/dist/tooling/cli/legacy/stable-target-deploy.js +102 -0
- package/dist/tooling/cli/list.d.ts +114 -0
- package/dist/tooling/cli/list.js +297 -0
- package/dist/tooling/cli/orchestrate.d.ts +1 -1
- package/dist/tooling/cli/orchestrate.js +91 -95
- package/dist/tooling/cli/secrets.d.ts +9 -0
- package/dist/tooling/cli/secrets.js +19 -0
- package/package.json +7 -7
- 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/deployment.d.ts +0 -16
- package/dist/tooling/cli/development/deployment.js +0 -39
- package/dist/tooling/cli/development/develop.d.ts +0 -11
- package/dist/tooling/cli/development/develop.js +0 -243
- 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/report.d.ts +0 -9
- 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
- /package/dist/tooling/cli/{credential.d.ts → legacy/development/credential.d.ts} +0 -0
- /package/dist/tooling/cli/{credential.js → legacy/development/credential.js} +0 -0
- /package/dist/tooling/cli/{development → legacy/development}/lease.d.ts +0 -0
- /package/dist/tooling/cli/{development → legacy/development}/lease.js +0 -0
- /package/dist/tooling/cli/{development → legacy/development}/lifecycle.d.ts +0 -0
- /package/dist/tooling/cli/{development → legacy/development}/lifecycle.js +0 -0
- /package/dist/tooling/cli/{development → legacy/development}/project-imports.d.ts +0 -0
- /package/dist/tooling/cli/{development → legacy/development}/project-imports.js +0 -0
- /package/dist/tooling/cli/{development → legacy/development}/project-lock.d.ts +0 -0
- /package/dist/tooling/cli/{development → legacy/development}/project-lock.js +0 -0
- /package/dist/tooling/cli/{development → legacy/development}/rebuild.d.ts +0 -0
- /package/dist/tooling/cli/{development → legacy/development}/rebuild.js +0 -0
- /package/dist/tooling/cli/{development → legacy/development}/source-watch.d.ts +0 -0
- /package/dist/tooling/cli/{development → legacy/development}/source-watch.js +0 -0
- /package/dist/tooling/cli/{development → legacy/development}/sources.d.ts +0 -0
- /package/dist/tooling/cli/{development → legacy/development}/sources.js +0 -0
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { rm, rmdir } from 'node:fs/promises';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { deprecationWarnings } from '../../deprecations.js';
|
|
4
|
+
import { error, info, warn } from '../../log.js';
|
|
5
|
+
import { DevelopmentCandidateBuilder, discoverRuntimePath, sameDeploymentCandidate, sameEnvironment, } from './candidate.js';
|
|
6
|
+
import { loadPrivateCredentialFile } from './credential.js';
|
|
7
|
+
import { deployDevelopmentCandidate } from './deployment.js';
|
|
8
|
+
import { DevelopmentLifecycle } from './lifecycle.js';
|
|
9
|
+
import { acquireProjectLock } from './project-lock.js';
|
|
10
|
+
import { LatestRebuild } from './rebuild.js';
|
|
11
|
+
import { reportDevelopmentDeployment } from './report.js';
|
|
12
|
+
import { loadPrivateSecretsFile } from './secrets-file.js';
|
|
13
|
+
import { watchSources } from './source-watch.js';
|
|
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
|
+
*
|
|
18
|
+
* @deprecated Deploy the Environment with `astrale-domain deploy`, then install the printed URL
|
|
19
|
+
* with `astrale domain install <url> --direct -i <instance>`.
|
|
20
|
+
*/
|
|
21
|
+
export async function develop(input) {
|
|
22
|
+
const lifecycle = new DevelopmentLifecycle();
|
|
23
|
+
let lock;
|
|
24
|
+
let sourceWatch;
|
|
25
|
+
let rebuild;
|
|
26
|
+
let current;
|
|
27
|
+
let failure;
|
|
28
|
+
const cleanup = [];
|
|
29
|
+
try {
|
|
30
|
+
lock = await acquireProjectLock({
|
|
31
|
+
projectRoot: input.projectDir,
|
|
32
|
+
environment: input.environment,
|
|
33
|
+
});
|
|
34
|
+
const overrideSecrets = input.secretsFile === undefined
|
|
35
|
+
? undefined
|
|
36
|
+
: Object.freeze(loadPrivateSecretsFile(input.secretsFile));
|
|
37
|
+
const credential = input.credentialFile === undefined
|
|
38
|
+
? undefined
|
|
39
|
+
: loadPrivateCredentialFile(input.credentialFile);
|
|
40
|
+
const runtimePath = await discoverRuntimePath(input.configPath);
|
|
41
|
+
const builder = new DevelopmentCandidateBuilder({
|
|
42
|
+
...input,
|
|
43
|
+
runtimePath,
|
|
44
|
+
overrideSecrets,
|
|
45
|
+
});
|
|
46
|
+
current = await builder.prepare(lifecycle.signal);
|
|
47
|
+
info(`Domain: ${current.artifact.build.schema.compiled.root.origin}`);
|
|
48
|
+
for (const warning of deprecationWarnings(current.artifact.build))
|
|
49
|
+
warn(warning);
|
|
50
|
+
const first = await deployDevelopmentCandidate(current, { ...input, ...(credential === undefined ? {} : { credential }) }, lifecycle.signal);
|
|
51
|
+
reportDevelopmentDeployment(first, current.adapter, input);
|
|
52
|
+
let restartReported = false;
|
|
53
|
+
rebuild = new LatestRebuild({
|
|
54
|
+
async prepare(_ignored, signal) {
|
|
55
|
+
info(`Rebuilding: ${input.environment}`);
|
|
56
|
+
return builder.prepare(signal);
|
|
57
|
+
},
|
|
58
|
+
async commit(candidate, signal) {
|
|
59
|
+
if (!sameEnvironment(current, candidate)) {
|
|
60
|
+
restartReported = true;
|
|
61
|
+
throw new Error('Project Environment configuration changed; restart pnpm dev to apply it.');
|
|
62
|
+
}
|
|
63
|
+
if (sameDeploymentCandidate(current, candidate)) {
|
|
64
|
+
current = candidate;
|
|
65
|
+
sourceWatch?.update(candidate.sources);
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const deployed = await deployDevelopmentCandidate(candidate, { ...input, ...(credential === undefined ? {} : { credential }) }, signal);
|
|
69
|
+
current = candidate;
|
|
70
|
+
sourceWatch?.update(candidate.sources);
|
|
71
|
+
info(`Updated: ${candidate.artifact.build.schema.compiled.root.revision}`);
|
|
72
|
+
reportDevelopmentDeployment(deployed, candidate.adapter, input);
|
|
73
|
+
},
|
|
74
|
+
async failed(cause) {
|
|
75
|
+
error(cause instanceof Error ? cause.message : String(cause));
|
|
76
|
+
},
|
|
77
|
+
});
|
|
78
|
+
sourceWatch = watchSources({
|
|
79
|
+
projectDir: input.projectDir,
|
|
80
|
+
configPath: input.configPath,
|
|
81
|
+
sources: current.sources,
|
|
82
|
+
onInvalidate: () => rebuild.invalidate(),
|
|
83
|
+
onRestartRequired: () => {
|
|
84
|
+
if (restartReported)
|
|
85
|
+
return;
|
|
86
|
+
restartReported = true;
|
|
87
|
+
error('Project Environment configuration changed; restart pnpm dev to apply it.');
|
|
88
|
+
},
|
|
89
|
+
onError: (cause) => {
|
|
90
|
+
failure = cause;
|
|
91
|
+
lifecycle.stop(cause);
|
|
92
|
+
},
|
|
93
|
+
});
|
|
94
|
+
info('Ready: watching for remote deployments');
|
|
95
|
+
// Edits made while the first build/deployment was in flight predate this watcher.
|
|
96
|
+
// Catch up once; artifact deduplication prevents an unchanged second deployment.
|
|
97
|
+
rebuild.invalidate();
|
|
98
|
+
await lifecycle.stopped;
|
|
99
|
+
}
|
|
100
|
+
catch (cause) {
|
|
101
|
+
failure = cause;
|
|
102
|
+
}
|
|
103
|
+
lifecycle.stop(failure);
|
|
104
|
+
for (const operation of [
|
|
105
|
+
() => sourceWatch?.stop(),
|
|
106
|
+
() => rebuild?.stop(failure),
|
|
107
|
+
() => rm(join(input.projectDir, '.astrale', 'development', input.environment, 'source'), {
|
|
108
|
+
recursive: true,
|
|
109
|
+
force: true,
|
|
110
|
+
}),
|
|
111
|
+
() => lock?.release(),
|
|
112
|
+
]) {
|
|
113
|
+
try {
|
|
114
|
+
await operation();
|
|
115
|
+
}
|
|
116
|
+
catch (cause) {
|
|
117
|
+
cleanup.push(cause);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
for (const directory of [
|
|
121
|
+
join(input.projectDir, '.astrale', 'development', input.environment),
|
|
122
|
+
join(input.projectDir, '.astrale', 'development'),
|
|
123
|
+
]) {
|
|
124
|
+
try {
|
|
125
|
+
await rmdir(directory);
|
|
126
|
+
}
|
|
127
|
+
catch (cause) {
|
|
128
|
+
const code = cause.code;
|
|
129
|
+
if (code !== 'ENOENT' && code !== 'ENOTEMPTY' && code !== 'EEXIST')
|
|
130
|
+
cleanup.push(cause);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
lifecycle.dispose();
|
|
134
|
+
if (failure !== undefined) {
|
|
135
|
+
if (cleanup.length > 0)
|
|
136
|
+
error(new AggregateError(cleanup, 'Development cleanup failed.').message);
|
|
137
|
+
throw failure;
|
|
138
|
+
}
|
|
139
|
+
if (cleanup.length > 0)
|
|
140
|
+
throw new AggregateError(cleanup, 'Development cleanup failed.');
|
|
141
|
+
return 0;
|
|
142
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `astrale-domain dev` (legacy, deprecated).
|
|
3
|
+
*
|
|
4
|
+
* Development is not a command of the deployment model: a developer, or an agent, iterates with
|
|
5
|
+
* `astrale-domain deploy development`, then `astrale domain install <url> --direct -i <instance>`. This
|
|
6
|
+
* folder keeps the watch loop that updates one deployment per Domain origin and Environment in
|
|
7
|
+
* place and its private file boundaries, exactly as before. Every run warns with that replacement
|
|
8
|
+
* on stderr.
|
|
9
|
+
*
|
|
10
|
+
* Short-term consumers: the `dev` scripts of the Domain packages that still deploy in place,
|
|
11
|
+
* namely the domains repository's ai-gateway, closing, grc, integrations, issues, organization and
|
|
12
|
+
* services packages, the Shell, and ui's Domain, and of the Projects create-astrale-domain
|
|
13
|
+
* scaffolds while its template still declares `dev`. Projects that pin an SDK release older than
|
|
14
|
+
* this folder never reach it.
|
|
15
|
+
*
|
|
16
|
+
* Deletion: once none of those packages runs `astrale-domain dev`, a separate breaking release
|
|
17
|
+
* deletes this folder with the `dev` command and its `--credential-file` and `--secrets-file`
|
|
18
|
+
* flags.
|
|
19
|
+
*/
|
|
20
|
+
export { develop } from './develop.js';
|
|
21
|
+
export { developmentDeprecation } from './deprecation.js';
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `astrale-domain dev` (legacy, deprecated).
|
|
3
|
+
*
|
|
4
|
+
* Development is not a command of the deployment model: a developer, or an agent, iterates with
|
|
5
|
+
* `astrale-domain deploy development`, then `astrale domain install <url> --direct -i <instance>`. This
|
|
6
|
+
* folder keeps the watch loop that updates one deployment per Domain origin and Environment in
|
|
7
|
+
* place and its private file boundaries, exactly as before. Every run warns with that replacement
|
|
8
|
+
* on stderr.
|
|
9
|
+
*
|
|
10
|
+
* Short-term consumers: the `dev` scripts of the Domain packages that still deploy in place,
|
|
11
|
+
* namely the domains repository's ai-gateway, closing, grc, integrations, issues, organization and
|
|
12
|
+
* services packages, the Shell, and ui's Domain, and of the Projects create-astrale-domain
|
|
13
|
+
* scaffolds while its template still declares `dev`. Projects that pin an SDK release older than
|
|
14
|
+
* this folder never reach it.
|
|
15
|
+
*
|
|
16
|
+
* Deletion: once none of those packages runs `astrale-domain dev`, a separate breaking release
|
|
17
|
+
* deletes this folder with the `dev` command and its `--credential-file` and `--secrets-file`
|
|
18
|
+
* flags.
|
|
19
|
+
*/
|
|
20
|
+
export { develop } from './develop.js';
|
|
21
|
+
export { developmentDeprecation } from './deprecation.js';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ReadyDeployResult } from '../../../../deployment/adapter/index.js';
|
|
2
|
+
export declare function reportDevelopmentDeployment(deployed: ReadyDeployResult, adapter: {
|
|
3
|
+
readonly name: string;
|
|
4
|
+
readonly version: string;
|
|
5
|
+
}, input: {
|
|
6
|
+
readonly environment: string;
|
|
7
|
+
}): void;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { info } from '
|
|
2
|
-
export function reportDevelopmentDeployment(deployed,
|
|
1
|
+
import { info } from '../../log.js';
|
|
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
|
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { closeSync, constants, fstatSync, openSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { parseDotenv } from '../../dotenv.js';
|
|
3
|
+
/** Load one explicit development-session secret snapshot without following a leaf symlink. */
|
|
4
|
+
export function loadPrivateSecretsFile(path, platform = process.platform) {
|
|
5
|
+
if (platform === 'win32') {
|
|
6
|
+
throw new Error('--secrets-file is unavailable on Windows until private no-reparse file admission is supported.');
|
|
7
|
+
}
|
|
8
|
+
let descriptor;
|
|
9
|
+
try {
|
|
10
|
+
descriptor = openSync(path, constants.O_RDONLY | constants.O_NOFOLLOW);
|
|
11
|
+
}
|
|
12
|
+
catch (cause) {
|
|
13
|
+
if (cause instanceof Error && 'code' in cause && cause.code === 'ENOENT') {
|
|
14
|
+
throw new Error(`Secrets file '${path}' is missing.`, { cause });
|
|
15
|
+
}
|
|
16
|
+
if (cause instanceof Error && 'code' in cause && cause.code === 'ELOOP') {
|
|
17
|
+
throw new Error(`Secrets file '${path}' must be a regular file and not a symlink.`, { cause });
|
|
18
|
+
}
|
|
19
|
+
throw cause;
|
|
20
|
+
}
|
|
21
|
+
try {
|
|
22
|
+
const info = fstatSync(descriptor);
|
|
23
|
+
if (!info.isFile())
|
|
24
|
+
throw new Error(`Secrets file '${path}' must be a regular file.`);
|
|
25
|
+
if ((info.mode & 0o077) !== 0) {
|
|
26
|
+
throw new Error(`Secrets file '${path}' must not be accessible by group or other users.`);
|
|
27
|
+
}
|
|
28
|
+
return parseDotenv(readFileSync(descriptor, 'utf8'));
|
|
29
|
+
}
|
|
30
|
+
finally {
|
|
31
|
+
closeSync(descriptor);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -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,40 @@
|
|
|
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.
|
|
19
|
+
*
|
|
20
|
+
* Returns the deploy result, or nothing once a failure is reported on stderr.
|
|
21
|
+
*
|
|
22
|
+
* @deprecated Stable-target deploy path only. Replacement: `deployImmutable`, the immutable
|
|
23
|
+
* deployment of one sealed release through `deployRelease`. Consumers: the direct-mode
|
|
24
|
+
* configurations of domains ai-gateway, closing, grc, integrations and issues (until SV15), domains
|
|
25
|
+
* organization (until it leaves direct mode, AM-147), the Services `beta` and `prod` (until SV12),
|
|
26
|
+
* `development` (until SV9) and frozen `admin-beta` (until D19) environments, shell (until SH2)
|
|
27
|
+
* and its frozen `legacy-v3` (until D22), and ui:domain (until UI1). Deleted with the legacy deploy
|
|
28
|
+
* path (D10), once no configuration on any repository's main selects it (CT33, AM-147).
|
|
29
|
+
*/
|
|
30
|
+
export declare function deployStableTarget(input: {
|
|
31
|
+
readonly projectDir: string;
|
|
32
|
+
readonly environment: string;
|
|
33
|
+
readonly definition: LoadedEnvironment;
|
|
34
|
+
readonly reasons: readonly LegacyDirectReason[];
|
|
35
|
+
readonly build: Build;
|
|
36
|
+
readonly runtime: ResolvedRuntimeReference;
|
|
37
|
+
readonly identity?: string;
|
|
38
|
+
readonly signal: AbortSignal;
|
|
39
|
+
readonly report: (line: string) => void;
|
|
40
|
+
}): Promise<DeployResultV1 | undefined>;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { verifyDeployment, verifyPreflight } from '../../../deployment/index.js';
|
|
2
|
+
import { bundleBuild } from '../build.js';
|
|
3
|
+
import { error, warn } from '../log.js';
|
|
4
|
+
import { environmentSecrets } from '../secrets.js';
|
|
5
|
+
import { stableTargetDeployResult } from './deploy-result.js';
|
|
6
|
+
import { stableTargetAdapter } from './stable-target-adapter.js';
|
|
7
|
+
import { stableTargetBuildWarning } from './uploaded-build.js';
|
|
8
|
+
/**
|
|
9
|
+
* What a direct-mode deploy prints on stderr before any effect (AM-59): its Environment replaces
|
|
10
|
+
* one stable target in place and serves a v3 Publication only, which the deployment model
|
|
11
|
+
* replaces with one immutable deployment per release.
|
|
12
|
+
*
|
|
13
|
+
* @deprecated Stable-target deploy path only; see `deployStableTarget`.
|
|
14
|
+
*/
|
|
15
|
+
export function directModeDeprecation(environment, reasons) {
|
|
16
|
+
const selected = reasons.map((reason) => {
|
|
17
|
+
if (reason.reason === 'direct-parameter')
|
|
18
|
+
return reason.parameter;
|
|
19
|
+
return reason.reason === 'no-namespace' ? 'no namespace' : 'no deployRelease';
|
|
20
|
+
});
|
|
21
|
+
return (`Environment ${environment} deploys in direct mode (${selected.join(', ')}), which is ` +
|
|
22
|
+
'deprecated and will be removed: it replaces one stable target in place and serves a v3 ' +
|
|
23
|
+
'Publication only. Its replacement deploys one immutable deployment per release, through an ' +
|
|
24
|
+
'adapter that implements deployRelease.');
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Deploy one Environment on the legacy direct-mode path (CT33): bundle exactly as
|
|
28
|
+
* `astrale-domain build` does, let `prepare` place that Bundle at the Environment's stable target
|
|
29
|
+
* and `deploy` replace the code it runs, then verify the v3 Publication it serves. It warns first,
|
|
30
|
+
* then behaves exactly as before. The SDK never installs the deployed Domain here and makes no
|
|
31
|
+
* Kernel call of its own.
|
|
32
|
+
*
|
|
33
|
+
* Returns the deploy result, or nothing once a failure is reported on stderr.
|
|
34
|
+
*
|
|
35
|
+
* @deprecated Stable-target deploy path only. Replacement: `deployImmutable`, the immutable
|
|
36
|
+
* deployment of one sealed release through `deployRelease`. Consumers: the direct-mode
|
|
37
|
+
* configurations of domains ai-gateway, closing, grc, integrations and issues (until SV15), domains
|
|
38
|
+
* organization (until it leaves direct mode, AM-147), the Services `beta` and `prod` (until SV12),
|
|
39
|
+
* `development` (until SV9) and frozen `admin-beta` (until D19) environments, shell (until SH2)
|
|
40
|
+
* and its frozen `legacy-v3` (until D22), and ui:domain (until UI1). Deleted with the legacy deploy
|
|
41
|
+
* path (D10), once no configuration on any repository's main selects it (CT33, AM-147).
|
|
42
|
+
*/
|
|
43
|
+
export async function deployStableTarget(input) {
|
|
44
|
+
const { build, signal, report } = input;
|
|
45
|
+
warn(directModeDeprecation(input.environment, input.reasons));
|
|
46
|
+
const adapter = stableTargetAdapter(input.definition.deployment.adapter);
|
|
47
|
+
const parameters = input.definition.deployment.parameters;
|
|
48
|
+
// `deploy` rebuilds exactly as `build` does; preparation then only places that Bundle.
|
|
49
|
+
const bundle = await bundleBuild({
|
|
50
|
+
bundler: adapter.bundler,
|
|
51
|
+
projectDir: input.projectDir,
|
|
52
|
+
build,
|
|
53
|
+
runtime: input.runtime,
|
|
54
|
+
signal,
|
|
55
|
+
});
|
|
56
|
+
const source = await adapter.prepare(parameters, {
|
|
57
|
+
projectDir: input.projectDir,
|
|
58
|
+
environment: input.environment,
|
|
59
|
+
mode: 'release',
|
|
60
|
+
signal,
|
|
61
|
+
build,
|
|
62
|
+
runtime: input.runtime,
|
|
63
|
+
bundle,
|
|
64
|
+
});
|
|
65
|
+
const artifact = verifyPreflight({ build, runtime: input.runtime, source });
|
|
66
|
+
const secrets = environmentSecrets(adapter, parameters, input.projectDir, input.runtime.runtime);
|
|
67
|
+
const deployed = await adapter.deploy(parameters, {
|
|
68
|
+
projectDir: input.projectDir,
|
|
69
|
+
environment: input.environment,
|
|
70
|
+
...(input.identity === undefined ? {} : { identity: input.identity }),
|
|
71
|
+
secrets,
|
|
72
|
+
artifact,
|
|
73
|
+
signal,
|
|
74
|
+
});
|
|
75
|
+
const result = verifyDeployment(artifact, deployed);
|
|
76
|
+
if (result.status === 'failed') {
|
|
77
|
+
error(`Deployment failed during ${result.phase}: ${result.error.message}`);
|
|
78
|
+
return undefined;
|
|
79
|
+
}
|
|
80
|
+
const uploaded = result.progress.provider.evidence.build;
|
|
81
|
+
if (uploaded !== undefined) {
|
|
82
|
+
// prepare/deploy places a stable target: a differing upload only warns.
|
|
83
|
+
const warning = stableTargetBuildWarning(bundle, uploaded);
|
|
84
|
+
if (warning !== undefined)
|
|
85
|
+
warn(warning);
|
|
86
|
+
}
|
|
87
|
+
report(`Domain: ${result.release.publication.origin}`);
|
|
88
|
+
report(`Environment: ${input.environment}`);
|
|
89
|
+
report(`Adapter: ${adapter.name}@${adapter.version}`);
|
|
90
|
+
report(`Deployment: ${result.progress.provider.evidence.deployment}`);
|
|
91
|
+
if (result.progress.provider.evidence.preflight !== undefined) {
|
|
92
|
+
report(`Preflight: ${result.progress.provider.evidence.preflight}; public readiness verified`);
|
|
93
|
+
}
|
|
94
|
+
report(`Public: ${result.release.addressing.publicUrl}`);
|
|
95
|
+
report(`Publication: ${result.release.publication.schema.revision} · ${result.release.publication.etag}`);
|
|
96
|
+
report('Ready: deployment verified');
|
|
97
|
+
return stableTargetDeployResult({
|
|
98
|
+
environment: input.environment,
|
|
99
|
+
adapter,
|
|
100
|
+
deployment: result,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import type { DeploymentRecordV1, DeploymentSummaryV1 } from '../../deployment/address/index.js';
|
|
2
|
+
import type { DeploymentCallTarget, ListedDeployment } from '../../deployment/index.js';
|
|
3
|
+
import type { LoadedEnvironment } from './project.js';
|
|
4
|
+
/**
|
|
5
|
+
* `astrale-domain list --json` on stdout: the deployments of the Project's Environments that their
|
|
6
|
+
* hosts keep for the caller, each with its computed name and where it is called. It changes
|
|
7
|
+
* nothing, at any host or instance.
|
|
8
|
+
*/
|
|
9
|
+
export interface ListResultV1 {
|
|
10
|
+
readonly format: 'astrale.deployment-list';
|
|
11
|
+
readonly version: 1;
|
|
12
|
+
readonly origin: string;
|
|
13
|
+
/** Environment by Environment in the Project's order, each in its host's order. */
|
|
14
|
+
readonly deployments: readonly ListedDeploymentV1[];
|
|
15
|
+
/**
|
|
16
|
+
* The selected Environments whose deployments are not in `deployments`, and why: the listing is
|
|
17
|
+
* complete exactly when this is empty.
|
|
18
|
+
*/
|
|
19
|
+
readonly unlisted: readonly UnlistedEnvironmentV1[];
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* One deployment: what its host knows (`DeploymentSummaryV1`), the Environment it was listed for
|
|
23
|
+
* and its adapter, its computed name, and its call target. `lastCallAt` and a preview's `expiresAt`
|
|
24
|
+
* are as of the listing: an adapter reads the calls its host counted since it last recorded them
|
|
25
|
+
* (adapter-astrale: `CloudflareDeployment.lastCalls`), or every call from the calls dataset of a
|
|
26
|
+
* platform namespace (adapter-cloudflare), which omits both without Account Analytics Read.
|
|
27
|
+
*/
|
|
28
|
+
export type ListedDeploymentV1 = Omit<DeploymentSummaryV1, 'record'> & {
|
|
29
|
+
/** The Project Environment whose line holds the deployment, as its host listed it. */
|
|
30
|
+
readonly environment: string;
|
|
31
|
+
/** `<adapter name>@<adapter version>` */
|
|
32
|
+
readonly adapter: string;
|
|
33
|
+
/**
|
|
34
|
+
* The deployment's name (`deploymentName`, CT28), computed from its record and never stored:
|
|
35
|
+
* `1.4.2 + 7 commits · a1b2c3d · staging`. Print it as it is, environment included (AM-57).
|
|
36
|
+
*/
|
|
37
|
+
readonly name: string;
|
|
38
|
+
/**
|
|
39
|
+
* The record its deployer declared, as `acceptDeploymentRecord` admits it. `null` when there is
|
|
40
|
+
* no admitted record: the host returns a record this SDK refuses or one that describes another
|
|
41
|
+
* deployment, or keeps none (the adapter lists it without a record, as a platform namespace lists
|
|
42
|
+
* a deployment it has not activated). The deployment is then listed from what its host knows, and
|
|
43
|
+
* named in the listed Environment, from the commit of that record only when the record names this
|
|
44
|
+
* deployment, origin and Environment.
|
|
45
|
+
*/
|
|
46
|
+
readonly record: DeploymentRecordV1 | null;
|
|
47
|
+
/**
|
|
48
|
+
* Why there is no admitted record: the refusal of the stored one, or that its host keeps none;
|
|
49
|
+
* present exactly when `record` is `null`.
|
|
50
|
+
*/
|
|
51
|
+
readonly recordRefusal?: string;
|
|
52
|
+
/** Where to call this deployment alone, such as to rotate one of its secrets in place. */
|
|
53
|
+
readonly callTarget: DeploymentCallTarget;
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* An Environment the listing did not list:
|
|
57
|
+
* - `legacy-direct`: it replaces one stable target in place and makes no immutable deployment;
|
|
58
|
+
* - `refused`: `deploy` refuses its configuration, so it deploys nothing;
|
|
59
|
+
* - `unsupported`: its adapter deploys immutable deployments but lists none.
|
|
60
|
+
*/
|
|
61
|
+
export interface UnlistedEnvironmentV1 {
|
|
62
|
+
readonly environment: string;
|
|
63
|
+
readonly adapter: string;
|
|
64
|
+
readonly reason: 'legacy-direct' | 'refused' | 'unsupported';
|
|
65
|
+
}
|
|
66
|
+
/** What a listing found, beside the result: what to tell a person, and what failed. */
|
|
67
|
+
export interface DeploymentListing {
|
|
68
|
+
readonly result: ListResultV1;
|
|
69
|
+
/** One line for each Environment not listed and each record not admitted, for stderr. */
|
|
70
|
+
readonly notices: readonly string[];
|
|
71
|
+
/** Environments whose host could not be listed: their deployments are missing from the result. */
|
|
72
|
+
readonly failures: readonly {
|
|
73
|
+
readonly environment: string;
|
|
74
|
+
readonly adapter: string;
|
|
75
|
+
readonly error: Error;
|
|
76
|
+
}[];
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* List the deployments of the selected Environments, one adapter `list` call each.
|
|
80
|
+
*
|
|
81
|
+
* Only an Environment that deploys immutable deployments (CT33 canonical) is listed; the others are
|
|
82
|
+
* `unlisted`, with the reason. A record the host returns but `acceptDeploymentRecord` refuses never
|
|
83
|
+
* fails the listing: that deployment is listed from what its host knows, its record `null`. This
|
|
84
|
+
* covers a host whose SDK still admits a record this SDK refuses; a host that refuses a stored
|
|
85
|
+
* record itself may fail its own list (Admin's Services does, AM-152). An Environment whose host
|
|
86
|
+
* cannot be listed, or whose adapter answers anything but deployments, is a failure, and the others
|
|
87
|
+
* are still listed.
|
|
88
|
+
*/
|
|
89
|
+
export declare function listDeployments(input: {
|
|
90
|
+
readonly origin: string;
|
|
91
|
+
/** The selected Environments, in the Project's order. */
|
|
92
|
+
readonly environments: readonly (readonly [string, LoadedEnvironment])[];
|
|
93
|
+
readonly identity?: string;
|
|
94
|
+
readonly signal: AbortSignal;
|
|
95
|
+
}): Promise<DeploymentListing>;
|
|
96
|
+
/**
|
|
97
|
+
* One listed deployment, its record admitted when it describes exactly this deployment of this
|
|
98
|
+
* origin and Environment. Its name comes from the admitted record; otherwise it is named in the
|
|
99
|
+
* listed Environment, with the commit of the stored record only when that record names this
|
|
100
|
+
* deployment, origin and Environment, as `deploymentName` reads a commit.
|
|
101
|
+
*/
|
|
102
|
+
export declare function listedDeployment(deployment: ListedDeployment, listing: {
|
|
103
|
+
readonly origin: string;
|
|
104
|
+
readonly environment: string;
|
|
105
|
+
readonly adapter: string;
|
|
106
|
+
}): ListedDeploymentV1;
|
|
107
|
+
/**
|
|
108
|
+
* The listing as a table for a person, at `now`: each deployment's release, its name as computed
|
|
109
|
+
* (never shortened, AM-57), its Environment and state, its last call and its expiry, and the URL
|
|
110
|
+
* `astrale domain install` takes. Without deployments, it says so only for what was listed: nothing
|
|
111
|
+
* when a host `failed` (stderr says which), and that some Environments were not listed when any
|
|
112
|
+
* was not.
|
|
113
|
+
*/
|
|
114
|
+
export declare function renderDeploymentList(result: ListResultV1, now: number, failed?: boolean): readonly string[];
|