@fabrika/provider-zerops 0.8.2 → 0.9.0-cloudflare.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +16 -14
- package/src/api/client.ts +6 -0
- package/src/api/types.ts +12 -0
- package/src/cli.ts +11 -0
- package/src/collaborators.ts +0 -14
- package/src/control.ts +33 -57
- package/src/execution.ts +113 -102
- package/src/installation/admin.ts +1 -1
- package/src/installation/deploy-options.ts +1 -2
- package/src/installation/deploy.ts +41 -75
- package/src/installation/generated/platform-console-schema.ts +3 -0
- package/src/installation/generated/platform-proxy-manifest.ts +21 -1
- package/src/installation/guide.md +9 -6
- package/src/installation/hosts.ts +1 -7
- package/src/installation/index.ts +0 -13
- package/src/installation/init-options.ts +2 -1
- package/src/installation/install-environment.ts +42 -106
- package/src/installation/install-options.ts +3 -1
- package/src/installation/install-secrets.ts +24 -68
- package/src/installation/install.ts +8 -4
- package/src/installation/sidecar.ts +5 -26
- package/src/installation/topology/setups.ts +5 -0
- package/src/installation/upgrade-options.ts +2 -2
- package/src/managed-env.ts +1 -174
- package/src/manifest.ts +11 -14
- package/src/namespace/claims.ts +56 -1
- package/src/namespace/errors.ts +1 -1
- package/src/namespace/manifest.ts +6 -19
- package/src/namespace/provisioning.ts +15 -3
- package/src/namespace/proxy-attempt.ts +43 -2
- package/src/namespace/proxy-reads.ts +12 -22
- package/src/namespace-cli.ts +152 -0
- package/src/plan.ts +2 -7
- package/src/provider.ts +128 -126
- package/src/proxy-manifest-carrier.ts +18 -0
- package/src/types.ts +0 -2
- package/types/src/api/client.d.ts +5 -0
- package/types/src/api/errors.d.ts +24 -0
- package/types/src/api/polling.d.ts +41 -0
- package/types/src/api/readers.d.ts +1115 -0
- package/types/src/api/service-env-limit.d.ts +17 -0
- package/types/src/api/service-env-response.d.ts +23 -0
- package/types/src/api/types.d.ts +687 -0
- package/types/src/api.d.ts +6 -0
- package/types/src/authoring.d.ts +9 -0
- package/types/src/cli-args.d.ts +19 -0
- package/types/src/cli.d.ts +13 -0
- package/types/src/collaborators.d.ts +16 -0
- package/types/src/compile.d.ts +91 -0
- package/types/src/control.d.ts +40 -0
- package/types/src/database-budget.d.ts +38 -0
- package/types/src/descriptor.d.ts +28 -0
- package/types/src/execution.d.ts +125 -0
- package/types/src/exposure.d.ts +47 -0
- package/types/src/index.d.ts +31 -0
- package/types/src/installation/admin-options.d.ts +24 -0
- package/types/src/installation/admin.d.ts +35 -0
- package/types/src/installation/checker-release.d.ts +12 -0
- package/types/src/installation/deploy-options.d.ts +37 -0
- package/types/src/installation/deploy.d.ts +136 -0
- package/types/src/installation/generated/platform-console-schema.d.ts +2 -0
- package/types/src/installation/generated/platform-proxy-manifest.d.ts +2 -0
- package/types/src/installation/hosts.d.ts +34 -0
- package/types/src/installation/index.d.ts +7 -0
- package/types/src/installation/init-options.d.ts +38 -0
- package/types/src/installation/init.d.ts +60 -0
- package/types/src/installation/install-collaborators.d.ts +24 -0
- package/types/src/installation/install-environment.d.ts +63 -0
- package/types/src/installation/install-options.d.ts +49 -0
- package/types/src/installation/install-project.d.ts +13 -0
- package/types/src/installation/install-provisioning.d.ts +58 -0
- package/types/src/installation/install-secrets.d.ts +17 -0
- package/types/src/installation/install-token.d.ts +10 -0
- package/types/src/installation/install.d.ts +23 -0
- package/types/src/installation/installation-source.d.ts +8 -0
- package/types/src/installation/log.d.ts +44 -0
- package/types/src/installation/machine-key.d.ts +19 -0
- package/types/src/installation/placement-options.d.ts +11 -0
- package/types/src/installation/platform-archive.d.ts +7 -0
- package/types/src/installation/platform-source.d.ts +8 -0
- package/types/src/installation/platform-upload.d.ts +3 -0
- package/types/src/installation/sidecar.d.ts +49 -0
- package/types/src/installation/source-options.d.ts +1 -0
- package/types/src/installation/topology/artifacts.d.ts +8 -0
- package/types/src/installation/topology/index.d.ts +5 -0
- package/types/src/installation/topology/installation-schemas.d.ts +2242 -0
- package/types/src/installation/topology/invariants.d.ts +23 -0
- package/types/src/installation/topology/setups.d.ts +59 -0
- package/types/src/installation/topology/topology.d.ts +153 -0
- package/types/src/installation/topology/validate.d.ts +11 -0
- package/types/src/installation/upgrade-options.d.ts +26 -0
- package/types/src/installation/upgrade-output.d.ts +6 -0
- package/types/src/installation/upgrade.d.ts +88 -0
- package/types/src/managed-env.d.ts +24 -0
- package/types/src/manifest.d.ts +204 -0
- package/types/src/namespace/claims.d.ts +16 -0
- package/types/src/namespace/codec.d.ts +334 -0
- package/types/src/namespace/constants.d.ts +25 -0
- package/types/src/namespace/errors.d.ts +15 -0
- package/types/src/namespace/manifest.d.ts +4 -0
- package/types/src/namespace/operator.d.ts +12 -0
- package/types/src/namespace/provisioning.d.ts +4 -0
- package/types/src/namespace/proxy-attempt.d.ts +39 -0
- package/types/src/namespace/proxy-reads.d.ts +22 -0
- package/types/src/namespace/proxy-secrets.d.ts +8 -0
- package/types/src/namespace/proxy-source.d.ts +74 -0
- package/types/src/namespace/topology.d.ts +9 -0
- package/types/src/namespace/types.d.ts +101 -0
- package/types/src/namespace/update.d.ts +6 -0
- package/types/src/namespace/validation.d.ts +12 -0
- package/types/src/namespace-cli.d.ts +2 -0
- package/types/src/namespace.d.ts +9 -0
- package/types/src/plan.d.ts +11 -0
- package/types/src/provider.d.ts +63 -0
- package/types/src/proxy-manifest-carrier.d.ts +24 -0
- package/types/src/schema.generated.d.ts +376 -0
- package/types/src/service-names.d.ts +4 -0
- package/types/src/service-references.d.ts +13 -0
- package/types/src/source/constants.d.ts +6 -0
- package/types/src/source/port.d.ts +60 -0
- package/types/src/source/types.d.ts +4 -0
- package/types/src/source/validation.d.ts +19 -0
- package/types/src/source.d.ts +2 -0
- package/types/src/types.d.ts +119 -0
- package/types/src/version-attempt.d.ts +8 -0
- package/src/installation/mcp.ts +0 -102
- package/src/installation/proxy-manifest.ts +0 -214
- package/src/installation/secrets.ts +0 -78
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fabrika/provider-zerops",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0-cloudflare.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -12,27 +12,28 @@
|
|
|
12
12
|
},
|
|
13
13
|
"files": [
|
|
14
14
|
"src",
|
|
15
|
-
"!src/**/__tests__/**"
|
|
15
|
+
"!src/**/__tests__/**",
|
|
16
|
+
"types"
|
|
16
17
|
],
|
|
17
18
|
"exports": {
|
|
18
19
|
".": {
|
|
19
20
|
"bun": "./src/index.ts",
|
|
20
|
-
"types": "./src/index.ts",
|
|
21
|
+
"types": "./types/src/index.d.ts",
|
|
21
22
|
"default": "./src/index.ts"
|
|
22
23
|
},
|
|
23
24
|
"./cli": {
|
|
24
25
|
"bun": "./src/cli.ts",
|
|
25
|
-
"types": "./src/cli.ts",
|
|
26
|
+
"types": "./types/src/cli.d.ts",
|
|
26
27
|
"default": "./src/cli.ts"
|
|
27
28
|
},
|
|
28
29
|
"./installation": {
|
|
29
30
|
"bun": "./src/installation/index.ts",
|
|
30
|
-
"types": "./src/installation/index.ts",
|
|
31
|
+
"types": "./types/src/installation/index.d.ts",
|
|
31
32
|
"default": "./src/installation/index.ts"
|
|
32
33
|
},
|
|
33
34
|
"./installation/topology": {
|
|
34
35
|
"bun": "./src/installation/topology/index.ts",
|
|
35
|
-
"types": "./src/installation/topology/index.ts",
|
|
36
|
+
"types": "./types/src/installation/topology/index.d.ts",
|
|
36
37
|
"default": "./src/installation/topology/index.ts"
|
|
37
38
|
}
|
|
38
39
|
},
|
|
@@ -43,14 +44,15 @@
|
|
|
43
44
|
},
|
|
44
45
|
"dependencies": {
|
|
45
46
|
"zod": "^3.25.76",
|
|
46
|
-
"@fabrika/
|
|
47
|
-
"@fabrika/auth
|
|
48
|
-
"@fabrika/
|
|
49
|
-
"@fabrika/
|
|
50
|
-
"@fabrika/
|
|
51
|
-
"@fabrika/
|
|
52
|
-
"@fabrika/
|
|
53
|
-
"@fabrika/
|
|
47
|
+
"@fabrika/app": "0.9.0-cloudflare.1",
|
|
48
|
+
"@fabrika/auth": "0.9.0-cloudflare.1",
|
|
49
|
+
"@fabrika/auth-core": "0.9.0-cloudflare.1",
|
|
50
|
+
"@fabrika/email": "0.9.0-cloudflare.1",
|
|
51
|
+
"@fabrika/iam-contract": "0.9.0-cloudflare.1",
|
|
52
|
+
"@fabrika/installation-init": "0.9.0-cloudflare.1",
|
|
53
|
+
"@fabrika/operations-contract": "0.9.0-cloudflare.1",
|
|
54
|
+
"@fabrika/provider-contract": "0.9.0-cloudflare.1",
|
|
55
|
+
"@fabrika/proxy-core": "0.9.0-cloudflare.1",
|
|
54
56
|
"yaml": "^2.9.1"
|
|
55
57
|
}
|
|
56
58
|
}
|
package/src/api/client.ts
CHANGED
|
@@ -347,6 +347,12 @@ export const createZeropsApi = (options: ZeropsApiOptions): ZeropsApi => {
|
|
|
347
347
|
await request('enable subdomain access', 'PUT', `/service-stack/${serviceId}/enable-subdomain-access`, { signal })
|
|
348
348
|
},
|
|
349
349
|
|
|
350
|
+
startService: async ({ serviceId, signal }) =>
|
|
351
|
+
readResponse('start service', processSchema, await request('start service', 'PUT', `/service-stack/${serviceId}/start`, { signal })),
|
|
352
|
+
|
|
353
|
+
stopService: async ({ serviceId, signal }) =>
|
|
354
|
+
readResponse('stop service', processSchema, await request('stop service', 'PUT', `/service-stack/${serviceId}/stop`, { signal })),
|
|
355
|
+
|
|
350
356
|
configureAutoscaling: async ({ serviceId, autoscalingProfileId, signal }) => {
|
|
351
357
|
const payload = await request('configure autoscaling', 'PUT', `/service-stack/${serviceId}/autoscaling`, {
|
|
352
358
|
body: { autoscalingProfileId },
|
package/src/api/types.ts
CHANGED
|
@@ -500,6 +500,18 @@ export interface ZeropsApi {
|
|
|
500
500
|
*/
|
|
501
501
|
enableSubdomainAccess(input: { serviceId: string; signal: AbortSignal }): Promise<void>
|
|
502
502
|
|
|
503
|
+
// ── service-stack: running state ──────────────────────────────────────────────
|
|
504
|
+
|
|
505
|
+
/**
|
|
506
|
+
* Start a stopped service. VERIFIED AS A SHAPE: `PUT /service-stack/{id}/start` (`StartServiceStack`), no body,
|
|
507
|
+
* `ResponseProcess`. Measured 2026-10-21: a stopped Bun service served again about 9 s after the call. Files written
|
|
508
|
+
* at runtime survive a stop and a start; a deploy replaces the container and loses them.
|
|
509
|
+
*/
|
|
510
|
+
startService(input: { serviceId: string; signal: AbortSignal }): Promise<ZeropsProcess>
|
|
511
|
+
|
|
512
|
+
/** Stop a service. VERIFIED AS A SHAPE: `PUT /service-stack/{id}/stop` (`StopServiceStack`), no body, `ResponseProcess`. */
|
|
513
|
+
stopService(input: { serviceId: string; signal: AbortSignal }): Promise<ZeropsProcess>
|
|
514
|
+
|
|
503
515
|
// ── service-stack: autoscaling ────────────────────────────────────────────────
|
|
504
516
|
|
|
505
517
|
/**
|
package/src/cli.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
|
+
import type { AppCli } from '@fabrika/provider-contract/app-cli'
|
|
2
3
|
import { constants } from 'node:fs'
|
|
3
4
|
import { open } from 'node:fs/promises'
|
|
4
5
|
import { resolve } from 'node:path'
|
|
@@ -12,6 +13,7 @@ import {
|
|
|
12
13
|
manifestServiceHostnames,
|
|
13
14
|
ZEROPS_SOURCE_DESCRIPTOR_MAX_BYTES,
|
|
14
15
|
} from './manifest'
|
|
16
|
+
import { zeropsNamespaceCli } from './namespace-cli'
|
|
15
17
|
import type { ZeropsAppConfig } from './types'
|
|
16
18
|
|
|
17
19
|
const USAGE = `Zerops app tools
|
|
@@ -106,6 +108,15 @@ export const runZeropsCli = async (argv: readonly string[]): Promise<void> => {
|
|
|
106
108
|
console.info(`wrote ${output} (${manifestServiceHostnames(manifest).length} service(s))`)
|
|
107
109
|
}
|
|
108
110
|
|
|
111
|
+
/** What `fabrika app build`, `app register` and `fabrika namespace` run for an application on Zerops. */
|
|
112
|
+
export const appCli: AppCli = {
|
|
113
|
+
provider: 'zerops',
|
|
114
|
+
entryRuntime: 'bun',
|
|
115
|
+
build: (argv) => runZeropsCli(['build', ...argv]),
|
|
116
|
+
registrationManifest: buildZeropsManifestText,
|
|
117
|
+
namespaces: zeropsNamespaceCli,
|
|
118
|
+
}
|
|
119
|
+
|
|
109
120
|
if (import.meta.main) {
|
|
110
121
|
await runZeropsCli(process.argv.slice(2)).catch((error: unknown) => {
|
|
111
122
|
console.error(error instanceof Error ? error.message : String(error))
|
package/src/collaborators.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { reconcileSchema } from '@fabrika/auth'
|
|
2
|
-
import type { SchemaReconciler } from '@fabrika/provider-contract'
|
|
3
1
|
import { createZeropsApi, type ZeropsApi } from './api'
|
|
4
2
|
import { type ExposureAlerter, sendExposureAlert } from './exposure'
|
|
5
3
|
import type { ZeropsSourcePort } from './source/port'
|
|
@@ -28,7 +26,6 @@ export interface ZeropsCollaborators {
|
|
|
28
26
|
api: ZeropsApi
|
|
29
27
|
/** Injected by the Zerops control composition; dry runs do not require it. */
|
|
30
28
|
source?: ZeropsSourcePort
|
|
31
|
-
reconcileSchema: SchemaReconciler
|
|
32
29
|
/** Raises the Operations alert for a refused activation; best-effort. */
|
|
33
30
|
alertExposure: ExposureAlerter
|
|
34
31
|
sleep: Sleeper
|
|
@@ -36,19 +33,8 @@ export interface ZeropsCollaborators {
|
|
|
36
33
|
|
|
37
34
|
export type ZeropsCollaboratorFactory = (target: ZeropsRuntimeTarget) => ZeropsCollaborators
|
|
38
35
|
|
|
39
|
-
const defaultReconcileSchema: SchemaReconciler = (input) =>
|
|
40
|
-
reconcileSchema({
|
|
41
|
-
url: input.url,
|
|
42
|
-
app: input.app,
|
|
43
|
-
schema: input.schema,
|
|
44
|
-
...(input.returnOrigins === undefined ? {} : { returnOrigins: input.returnOrigins }),
|
|
45
|
-
adminKey: input.adminKey,
|
|
46
|
-
signal: input.signal,
|
|
47
|
-
})
|
|
48
|
-
|
|
49
36
|
export const defaultZeropsCollaborators: ZeropsCollaboratorFactory = (target) => ({
|
|
50
37
|
api: createZeropsApi({ token: target.accessToken, baseUrl: target.apiBaseUrl }),
|
|
51
|
-
reconcileSchema: defaultReconcileSchema,
|
|
52
38
|
alertExposure: sendExposureAlert,
|
|
53
39
|
sleep: defaultSleep,
|
|
54
40
|
})
|
package/src/control.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { appEnvironmentId } from '@fabrika/auth-core'
|
|
2
1
|
import type {
|
|
3
2
|
ControlProvider,
|
|
4
3
|
JsonValue,
|
|
@@ -8,6 +7,7 @@ import type {
|
|
|
8
7
|
ProviderDeployInput,
|
|
9
8
|
ProviderDeploymentNamespace,
|
|
10
9
|
ProviderDeployOutcome,
|
|
10
|
+
ProviderDevEnvironmentInput,
|
|
11
11
|
ProviderEnvelope,
|
|
12
12
|
ProviderEnvironment,
|
|
13
13
|
ProviderReconcileOutcome,
|
|
@@ -16,7 +16,6 @@ import type {
|
|
|
16
16
|
ProviderSourceBinding,
|
|
17
17
|
ProviderSourceResolution,
|
|
18
18
|
ProviderSourceResolutionInput,
|
|
19
|
-
SchemaReconciler,
|
|
20
19
|
} from '@fabrika/provider-contract'
|
|
21
20
|
import { decodeEnvelope, ProviderSecretError } from '@fabrika/provider-contract'
|
|
22
21
|
import { z } from 'zod'
|
|
@@ -31,9 +30,8 @@ import {
|
|
|
31
30
|
} from './api'
|
|
32
31
|
import { defaultSleep, defaultZeropsCollaborators, type Sleeper } from './collaborators'
|
|
33
32
|
import { createdServices, type ExposureAlerter, isObjectStorageType } from './exposure'
|
|
34
|
-
import { assertAuthoredManagedInputs, assertAuthoredManagedName, assertNoFrameworkReference
|
|
33
|
+
import { assertAuthoredManagedInputs, assertAuthoredManagedName, assertNoFrameworkReference } from './managed-env'
|
|
35
34
|
import {
|
|
36
|
-
approvedSchemaOf,
|
|
37
35
|
assertFabrikaManifestCoordinates,
|
|
38
36
|
type FabrikaManifest,
|
|
39
37
|
manifestServiceHostnames,
|
|
@@ -90,11 +88,8 @@ const envelope = <T>(codec: ProviderCodec<T>, value: T): ProviderEnvelope => ({
|
|
|
90
88
|
export interface ZeropsControlProviderOptions {
|
|
91
89
|
readonly accessToken: string
|
|
92
90
|
readonly apiBaseUrl?: string
|
|
93
|
-
readonly propustkaUrl?: string
|
|
94
|
-
readonly adminKey?: string
|
|
95
91
|
readonly api?: ZeropsApi
|
|
96
92
|
readonly source: ZeropsSourcePort
|
|
97
|
-
readonly reconcileSchema?: SchemaReconciler
|
|
98
93
|
readonly alertExposure?: ExposureAlerter
|
|
99
94
|
readonly sleep?: Sleeper
|
|
100
95
|
readonly namespaces?: {
|
|
@@ -228,7 +223,6 @@ export const createZeropsControlProvider = (options: ZeropsControlProviderOption
|
|
|
228
223
|
return {
|
|
229
224
|
api,
|
|
230
225
|
source: options.source,
|
|
231
|
-
reconcileSchema: options.reconcileSchema ?? defaults.reconcileSchema,
|
|
232
226
|
alertExposure: options.alertExposure ?? defaults.alertExposure,
|
|
233
227
|
sleep: options.sleep ?? defaultSleep,
|
|
234
228
|
}
|
|
@@ -262,34 +256,6 @@ export const createZeropsControlProvider = (options: ZeropsControlProviderOption
|
|
|
262
256
|
}
|
|
263
257
|
}
|
|
264
258
|
|
|
265
|
-
const reconcileActiveSchema = async (
|
|
266
|
-
input: { environment: ProviderEnvironment; returnOrigins?: readonly string[] },
|
|
267
|
-
signal: AbortSignal,
|
|
268
|
-
): Promise<void> => {
|
|
269
|
-
const artifact = artifactFor(input.environment)
|
|
270
|
-
const schema = approvedSchemaOf(input.environment)
|
|
271
|
-
if (schema === undefined || options.propustkaUrl === undefined) return
|
|
272
|
-
const placement = resolvedEnvironment(input.environment, { requireReady: false })
|
|
273
|
-
const runtimeTarget: ZeropsRuntimeTarget = {
|
|
274
|
-
projectId: placement.projectId,
|
|
275
|
-
serviceId: placement.target.serviceId,
|
|
276
|
-
accessToken: options.accessToken,
|
|
277
|
-
...(options.apiBaseUrl !== undefined ? { apiBaseUrl: options.apiBaseUrl } : {}),
|
|
278
|
-
propustkaUrl: options.propustkaUrl,
|
|
279
|
-
...(options.adminKey !== undefined ? { adminKey: options.adminKey } : {}),
|
|
280
|
-
}
|
|
281
|
-
const reconcileSchema = options.reconcileSchema ?? defaultZeropsCollaborators(runtimeTarget).reconcileSchema
|
|
282
|
-
signal.throwIfAborted()
|
|
283
|
-
await reconcileSchema({
|
|
284
|
-
url: options.propustkaUrl,
|
|
285
|
-
app: appEnvironmentId(artifact.app.id, artifact.app.env),
|
|
286
|
-
schema,
|
|
287
|
-
...(input.returnOrigins === undefined || input.returnOrigins.length === 0 ? {} : { returnOrigins: input.returnOrigins }),
|
|
288
|
-
adminKey: options.adminKey,
|
|
289
|
-
signal,
|
|
290
|
-
})
|
|
291
|
-
}
|
|
292
|
-
|
|
293
259
|
const assertVersionCoordinates = (environment: ProviderEnvironment, appVersionId: string, version: ZeropsAppVersion): void => {
|
|
294
260
|
const serviceId = decodeEnvironment(environment).target.serviceId
|
|
295
261
|
if (version.id !== appVersionId || (version.serviceStackId !== undefined && version.serviceStackId !== serviceId)) {
|
|
@@ -324,9 +290,31 @@ export const createZeropsControlProvider = (options: ZeropsControlProviderOption
|
|
|
324
290
|
return { commitSha: result.commitSha }
|
|
325
291
|
}
|
|
326
292
|
|
|
293
|
+
/** Stop or start the service of a `dev` environment outside a run, and wait for the platform's process. */
|
|
294
|
+
const runningState = async (input: ProviderDevEnvironmentInput, action: 'start' | 'stop'): Promise<void> => {
|
|
295
|
+
if (input.environment.kind !== 'dev') throw new Error('zerops: only a dev environment is stopped and started outside a run')
|
|
296
|
+
const placement = resolvedEnvironment(input.environment, { requireReady: false })
|
|
297
|
+
const serviceId = placement.target.serviceId
|
|
298
|
+
// Idempotent: Control's record of a stopped service can lag behind a start from elsewhere.
|
|
299
|
+
const status = (await api.getService({ serviceId, signal: input.signal })).status
|
|
300
|
+
if (status === (action === 'stop' ? 'STOPPED' : 'ACTIVE')) return
|
|
301
|
+
const process = action === 'stop'
|
|
302
|
+
? await api.stopService({ serviceId, signal: input.signal })
|
|
303
|
+
: await api.startService({ serviceId, signal: input.signal })
|
|
304
|
+
await waitForProcess({
|
|
305
|
+
api,
|
|
306
|
+
processId: process.id,
|
|
307
|
+
sleep: options.sleep ?? defaultSleep,
|
|
308
|
+
signal: input.signal,
|
|
309
|
+
label: `the ${action} of ${input.environment.appId}/${input.environment.env}`,
|
|
310
|
+
})
|
|
311
|
+
}
|
|
312
|
+
|
|
327
313
|
const controlProvider: ControlProvider = {
|
|
328
314
|
id: 'zerops',
|
|
329
315
|
normalizeRegistration,
|
|
316
|
+
// The deploy reads `zerops.yaml` from the repository, so a workspace may not change it (ADR-0049 D6).
|
|
317
|
+
authoring: { protectedFiles: ['zerops.yaml', 'zerops.yml'] },
|
|
330
318
|
source: { binding: 'connection' },
|
|
331
319
|
/**
|
|
332
320
|
* A Zerops artifact IS the compiled manifest, so the declaration is right here and core can refuse
|
|
@@ -349,8 +337,6 @@ export const createZeropsControlProvider = (options: ZeropsControlProviderOption
|
|
|
349
337
|
deploy: async (input: ProviderDeployInput): Promise<ProviderDeployOutcome> => {
|
|
350
338
|
input.signal.throwIfAborted()
|
|
351
339
|
assertAuthoredManagedInputs({ variableNames: Object.keys(input.vars), secretNames: Object.keys(input.secrets) })
|
|
352
|
-
const handed = parseManagedEnvironment(input.managedEnvironment)
|
|
353
|
-
const managedEnvironment = { ...handed.values, ...handed.familyVariables }
|
|
354
340
|
const binding = privateBinding(input.sourceBinding)
|
|
355
341
|
assertEnvironmentOfApp(input.app, input.environment)
|
|
356
342
|
const placement = resolvedEnvironment(input.environment, { requireReady: true })
|
|
@@ -376,16 +362,14 @@ export const createZeropsControlProvider = (options: ZeropsControlProviderOption
|
|
|
376
362
|
...(placement.target.createdBuckets === undefined ? {} : { createdBuckets: placement.target.createdBuckets }),
|
|
377
363
|
...(source === undefined ? {} : { source }),
|
|
378
364
|
...(options.apiBaseUrl !== undefined ? { apiBaseUrl: options.apiBaseUrl } : {}),
|
|
379
|
-
...(options.propustkaUrl !== undefined ? { propustkaUrl: options.propustkaUrl } : {}),
|
|
380
|
-
...(options.adminKey !== undefined ? { adminKey: options.adminKey } : {}),
|
|
381
365
|
}
|
|
382
366
|
const result = await deployRun({
|
|
383
367
|
appId: input.app.id,
|
|
384
368
|
env: input.environment.env,
|
|
385
|
-
...(input.
|
|
369
|
+
...(input.environment.kind === 'dev' && source !== undefined ? { dev: { head: source.commitSha } } : {}),
|
|
386
370
|
secrets: input.secrets,
|
|
387
371
|
vars: input.vars,
|
|
388
|
-
managedEnvironment,
|
|
372
|
+
managedEnvironment: input.managedEnvironment,
|
|
389
373
|
target: runtimeTarget,
|
|
390
374
|
artifact,
|
|
391
375
|
...(input.environment.access === undefined ? {} : { access: input.environment.access }),
|
|
@@ -397,6 +381,10 @@ export const createZeropsControlProvider = (options: ZeropsControlProviderOption
|
|
|
397
381
|
input.signal.throwIfAborted()
|
|
398
382
|
return { state: result.status, ...(result.artifactState === undefined ? {} : { artifactState: result.artifactState }) }
|
|
399
383
|
},
|
|
384
|
+
devEnvironments: {
|
|
385
|
+
stop: (input) => runningState(input, 'stop'),
|
|
386
|
+
start: (input) => runningState(input, 'start'),
|
|
387
|
+
},
|
|
400
388
|
cancel: async (input): Promise<ProviderCancelOutcome> => {
|
|
401
389
|
const signal = input.signal
|
|
402
390
|
signal.throwIfAborted()
|
|
@@ -414,17 +402,8 @@ export const createZeropsControlProvider = (options: ZeropsControlProviderOption
|
|
|
414
402
|
const version = await getVersion({ appVersionId: checkpoint.appVersionId, signal })
|
|
415
403
|
if (version === null) return { state: 'settled', outcome: 'failed' }
|
|
416
404
|
assertVersionCoordinates(input.environment, checkpoint.appVersionId, version)
|
|
417
|
-
// Cancellation never implies rollback: a version that activated first makes the run a success
|
|
418
|
-
|
|
419
|
-
if (version.status === ZEROPS_ACTIVE) {
|
|
420
|
-
try {
|
|
421
|
-
await reconcileActiveSchema(input, signal)
|
|
422
|
-
} catch {
|
|
423
|
-
signal.throwIfAborted()
|
|
424
|
-
return { state: 'pending' }
|
|
425
|
-
}
|
|
426
|
-
return { state: 'settled', outcome: 'succeeded' }
|
|
427
|
-
}
|
|
405
|
+
// Cancellation never implies rollback: a version that activated first makes the run a success.
|
|
406
|
+
if (version.status === ZEROPS_ACTIVE) return { state: 'settled', outcome: 'succeeded' }
|
|
428
407
|
if (version.status !== undefined && ZEROPS_TERMINAL.has(version.status)) return { state: 'settled', outcome: 'failed' }
|
|
429
408
|
await cancelBuildQuietly(checkpoint.appVersionId, signal)
|
|
430
409
|
// A build request that never landed leaves the version UPLOADING for good; the deadline settles it.
|
|
@@ -461,10 +440,7 @@ export const createZeropsControlProvider = (options: ZeropsControlProviderOption
|
|
|
461
440
|
}
|
|
462
441
|
if (version === null) return { state: 'failed' }
|
|
463
442
|
assertVersionCoordinates(input.environment, checkpoint.appVersionId, version)
|
|
464
|
-
if (version.status === ZEROPS_ACTIVE) {
|
|
465
|
-
await reconcileActiveSchema(input, signal)
|
|
466
|
-
return { state: 'succeeded' }
|
|
467
|
-
}
|
|
443
|
+
if (version.status === ZEROPS_ACTIVE) return { state: 'succeeded' }
|
|
468
444
|
if (version.status !== undefined && ZEROPS_TERMINAL.has(version.status)) return { state: 'failed' }
|
|
469
445
|
if (pastDeadline(input.startedAtMs)) {
|
|
470
446
|
await cancelBuildQuietly(checkpoint.appVersionId, signal)
|