@starci/hfs 4.7.21 → 4.7.22
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/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 4.7.22 - 2026-10-22
|
|
4
|
+
- Fixed: the bundled runtime carries `modules/schemas/provision-operation.schema.yaml`; 4.7.21 left it out, so `starci app check` and `starci app lint` failed with ENOENT in every app whose stack declaration has an `operations` block. The composition reads both schemas through `new URL(..., import.meta.url)`, the form the runtime copy follows. Spec: `src/provision-operation-schema-bundle.spec.mjs`.
|
|
5
|
+
|
|
3
6
|
## 4.7.21 - 2026-10-22
|
|
4
7
|
- Fixed: the release gate's Sonar read retries a network error or HTTP 5xx up to 5 times with backoff inside its 600 s wait; a 4xx and every gate status keep their verdict. Spec: `src/sonar-quality-gate.spec.mjs`.
|
|
5
8
|
- Fixed: `starci app db dump` archives its parts with tar run inside the scratch directory and relative names only (no `-C`, no absolute path): GNU tar, first on PATH under Git Bash on Windows, read the absolute drive-letter archive path as a remote host and every backup failed with `DB_BACKUP_TOOL_FAILED`. Spec: `src/db-dump-archive.spec.mjs`.
|
package/package.json
CHANGED
|
@@ -76,14 +76,14 @@ pins:
|
|
|
76
76
|
source: packages/test-world/package.json
|
|
77
77
|
why: 'the shared e2e library of every back end (R47, R48), a devDependency of every back end: the warm stack behind toxiproxy, the network-edge fakes, the Nest boot, the typed useTestWorld handle, useSandbox for contract specs and the outage lock. Kafka is real own infra (the one digest-pinned apache/kafka KRaft image, a broker listener and proxy per slot, slot-prefixed topics, consumer groups and client ids) and Postgres is schema-per-context (a schema and a login role per context in a shared database). Each worker has its own data slot (<ns>_w<k>) with its own databases, Keycloak realm, leased Redis DB, bucket/collection/topic prefixes, fakes host, toxiproxy proxies and outage lock; a run provisions min(jest workers, workers cap, default 2) slots, and state file protocol 2 pairs exactly with @starci/jest-preset (TEST_WORLD_PAIR_MISMATCH otherwise). A modules world boots real peer apps beside its modules, world.apps.<name>.during(fn) is the outage of a peer app, w.keycloak.clientSecret(client) answers the run-generated secret of a confidential realm client, world.keycloak.events/sessions read the realm user events and live sessions, world.infra.postgresql.connection(name) takes one database connection down while the others serve, and world.resolve and scope.resolve take any Nest token. Every path a declaration names (`stack`, seeds, the realm, Dockerfiles) resolves from the app root (the directory of hfs.json); the globalSetup registers the path aliases as TypeScript resolves them. Its CLI main is exported at ./cli for starci app stack.'
|
|
78
78
|
'@starci/cli':
|
|
79
|
-
version: 1.7.
|
|
79
|
+
version: 1.7.22
|
|
80
80
|
group: starci
|
|
81
81
|
install: registry
|
|
82
82
|
side: both
|
|
83
83
|
source: packages/cli/package.json
|
|
84
84
|
why: 'the only StarCi command package; product repositories install it for starci app, while @starci/hfs remains its pinned transitive implementation.'
|
|
85
85
|
'@starci/hfs':
|
|
86
|
-
version: 4.7.
|
|
86
|
+
version: 4.7.22
|
|
87
87
|
group: starci
|
|
88
88
|
install: registry
|
|
89
89
|
side: both
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
$schema: https://json-schema.org/draft/2020-12/schema
|
|
2
|
+
$id: urn:starci:provision-operation:1
|
|
3
|
+
title: Target-bound provider operations
|
|
4
|
+
description: Public target and custody references for executable provider adapters; values never enter this declaration.
|
|
5
|
+
type: object
|
|
6
|
+
additionalProperties: false
|
|
7
|
+
required: [targets]
|
|
8
|
+
properties:
|
|
9
|
+
targets:
|
|
10
|
+
type: object
|
|
11
|
+
minProperties: 1
|
|
12
|
+
additionalProperties: {$ref: '#/$defs/target'}
|
|
13
|
+
$defs:
|
|
14
|
+
goalGrants:
|
|
15
|
+
type: object
|
|
16
|
+
additionalProperties: false
|
|
17
|
+
required: [schema, grants]
|
|
18
|
+
properties:
|
|
19
|
+
schema: {const: 'starci/provision-grants@1'}
|
|
20
|
+
grants:
|
|
21
|
+
type: array
|
|
22
|
+
items:
|
|
23
|
+
type: object
|
|
24
|
+
additionalProperties: false
|
|
25
|
+
required: [op, operation, digest]
|
|
26
|
+
properties:
|
|
27
|
+
op: {type: string, pattern: '^[a-z][a-z0-9-]*(\.[a-z][a-z0-9-]*)+$'}
|
|
28
|
+
operation: {type: string, pattern: '^[a-zA-Z0-9][a-zA-Z0-9-]{0,127}$'}
|
|
29
|
+
digest: {type: string, pattern: '^[a-f0-9]{64}$'}
|
|
30
|
+
credential:
|
|
31
|
+
oneOf:
|
|
32
|
+
- {$ref: '#/$defs/serviceCredential'}
|
|
33
|
+
- {$ref: '#/$defs/hostCredential'}
|
|
34
|
+
serviceCredential:
|
|
35
|
+
$ref: application-stacks.schema.yaml#/$defs/serviceCredential
|
|
36
|
+
hostCredential:
|
|
37
|
+
description: >-
|
|
38
|
+
A fixed host bridge for the admin role, never a value. sonar-selfhost-admin is the native self-hosted Sonar administrator;
|
|
39
|
+
sonar-runtime-secret-env is the variable `env` of the runtime's untracked secret.env (the reader `starci gate sonar up` uses),
|
|
40
|
+
for a SonarCloud target only.
|
|
41
|
+
oneOf:
|
|
42
|
+
- type: object
|
|
43
|
+
additionalProperties: false
|
|
44
|
+
required: [id, hostConnection]
|
|
45
|
+
properties:
|
|
46
|
+
id: {const: admin}
|
|
47
|
+
hostConnection: {const: sonar-selfhost-admin}
|
|
48
|
+
- type: object
|
|
49
|
+
additionalProperties: false
|
|
50
|
+
required: [id, hostConnection, env]
|
|
51
|
+
properties:
|
|
52
|
+
id: {const: admin}
|
|
53
|
+
hostConnection: {const: sonar-runtime-secret-env}
|
|
54
|
+
env: {type: string, pattern: '^[A-Z][A-Z0-9_]{0,63}$'}
|
|
55
|
+
purpose: {type: string, minLength: 1}
|
|
56
|
+
target:
|
|
57
|
+
type: object
|
|
58
|
+
additionalProperties: false
|
|
59
|
+
required: [provider, context, resource, credentials]
|
|
60
|
+
oneOf:
|
|
61
|
+
- required: [origin]
|
|
62
|
+
properties:
|
|
63
|
+
provider: {enum: [supabase-cloud, supabase-auth, sonar-server, sonar-community, sonar-cloud, app, github, ghcr]}
|
|
64
|
+
endpoint: false
|
|
65
|
+
- required: [endpoint]
|
|
66
|
+
properties:
|
|
67
|
+
provider: {const: app-stack}
|
|
68
|
+
origin: false
|
|
69
|
+
endpoint: {$ref: '#/$defs/swarmEndpoint'}
|
|
70
|
+
- required: [endpoint]
|
|
71
|
+
properties:
|
|
72
|
+
provider: {const: app-db}
|
|
73
|
+
origin: false
|
|
74
|
+
endpoint: {$ref: '#/$defs/databaseEndpoint'}
|
|
75
|
+
oneOf:
|
|
76
|
+
- properties:
|
|
77
|
+
context: {const: local}
|
|
78
|
+
endpoint:
|
|
79
|
+
properties:
|
|
80
|
+
mode: {const: local}
|
|
81
|
+
- properties:
|
|
82
|
+
endpoint:
|
|
83
|
+
properties:
|
|
84
|
+
mode: {enum: [linked, url-env]}
|
|
85
|
+
properties:
|
|
86
|
+
provider:
|
|
87
|
+
enum: [supabase-cloud, supabase-auth, sonar-server, sonar-community, sonar-cloud, app, github, ghcr, app-stack, app-db]
|
|
88
|
+
context:
|
|
89
|
+
enum: [local, development, staging, production]
|
|
90
|
+
origin:
|
|
91
|
+
type: string
|
|
92
|
+
pattern: '^https?://[^\s]+$'
|
|
93
|
+
description: Auth-free origin; the resolver permits HTTP only for an explicitly local loopback target.
|
|
94
|
+
endpoint:
|
|
95
|
+
type: object
|
|
96
|
+
description: Closed native endpoint selected by app-stack or app-db; public declaration checks precede custody and the effective private endpoint is compared before network access.
|
|
97
|
+
resource:
|
|
98
|
+
type: object
|
|
99
|
+
description: Adapter-owned public configuration; each adapter refuses fields outside its action contract.
|
|
100
|
+
credentials:
|
|
101
|
+
type: array
|
|
102
|
+
items: {$ref: '#/$defs/credential'}
|
|
103
|
+
description: Named roles using the existing service credential contract; ids become the execution role map.
|
|
104
|
+
optionalCredentials:
|
|
105
|
+
type: array
|
|
106
|
+
uniqueItems: true
|
|
107
|
+
items: {type: string, pattern: '^[a-z][a-z0-9-]*$'}
|
|
108
|
+
description: Declared roles whose absence may be inspected without substituting another credential.
|
|
109
|
+
destination:
|
|
110
|
+
$ref: '#/$defs/credential'
|
|
111
|
+
actions:
|
|
112
|
+
type: array
|
|
113
|
+
minItems: 1
|
|
114
|
+
uniqueItems: true
|
|
115
|
+
items: {type: string, pattern: '^[a-z][a-z0-9-]*(\.[a-z][a-z0-9-]*)+$'}
|
|
116
|
+
description: Exact action ids allowed for this target; the catalog and execution owner enforce the selected action.
|
|
117
|
+
swarmEndpoint:
|
|
118
|
+
type: object
|
|
119
|
+
additionalProperties: false
|
|
120
|
+
required: [kind, environment, stack, host, user, port]
|
|
121
|
+
properties:
|
|
122
|
+
kind: {const: docker-swarm}
|
|
123
|
+
environment: {type: string, pattern: '^[a-z][a-z0-9-]*$'}
|
|
124
|
+
stack: {type: string, pattern: '^[a-z][a-z0-9-]*$'}
|
|
125
|
+
host: {type: string, pattern: '^[a-zA-Z0-9][a-zA-Z0-9.-]*$'}
|
|
126
|
+
user: {type: string, pattern: '^[a-zA-Z0-9_][a-zA-Z0-9_.-]*$'}
|
|
127
|
+
port: {const: 22}
|
|
128
|
+
databaseEndpoint:
|
|
129
|
+
type: object
|
|
130
|
+
additionalProperties: false
|
|
131
|
+
required: [kind, mode, environment]
|
|
132
|
+
oneOf:
|
|
133
|
+
- required: [localProject, port]
|
|
134
|
+
properties:
|
|
135
|
+
mode: {const: local}
|
|
136
|
+
projectRef: false
|
|
137
|
+
urlEnv: false
|
|
138
|
+
host: false
|
|
139
|
+
database: false
|
|
140
|
+
user: false
|
|
141
|
+
- required: [projectRef]
|
|
142
|
+
properties:
|
|
143
|
+
mode: {const: linked}
|
|
144
|
+
localProject: false
|
|
145
|
+
port: false
|
|
146
|
+
urlEnv: false
|
|
147
|
+
host: false
|
|
148
|
+
database: false
|
|
149
|
+
user: false
|
|
150
|
+
- required: [urlEnv, host, port, database, user]
|
|
151
|
+
properties:
|
|
152
|
+
mode: {const: url-env}
|
|
153
|
+
localProject: false
|
|
154
|
+
projectRef: false
|
|
155
|
+
properties:
|
|
156
|
+
kind: {const: supabase-db}
|
|
157
|
+
mode: {enum: [local, linked, url-env]}
|
|
158
|
+
environment: {type: string, pattern: '^[a-z][a-z0-9-]*$'}
|
|
159
|
+
localProject: {type: string, pattern: '^[a-zA-Z0-9_][a-zA-Z0-9_.-]*$'}
|
|
160
|
+
projectRef: {type: string, pattern: '^[a-z0-9]{20}$'}
|
|
161
|
+
urlEnv: {type: string, pattern: '^[A-Z][A-Z0-9_]*$'}
|
|
162
|
+
host: {type: string, pattern: '^[a-zA-Z0-9][a-zA-Z0-9.-]*$'}
|
|
163
|
+
port: {type: integer, minimum: 1, maximum: 65535}
|
|
164
|
+
database: {type: string, pattern: '^[a-zA-Z0-9_][a-zA-Z0-9_.-]*$'}
|
|
165
|
+
user: {type: string, pattern: '^[a-zA-Z0-9_][a-zA-Z0-9_.-]*$'}
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
// The schema of a stack declaration's `operations` block, composed once for its two readers: the provision target owner and the
|
|
2
2
|
// stacks gate. provision-operation.schema.yaml refers to the service credential of application-stacks.schema.yaml; the composition
|
|
3
3
|
// inlines that definition so the self-contained walker of json-schema.mjs resolves every reference.
|
|
4
|
+
// Both schemas are read through `new URL(<literal>, import.meta.url)`: that is the form sync-runtime follows, so the copy
|
|
5
|
+
// bundled in @starci/hfs carries them beside this module (a skillRoot join left provision-operation.schema.yaml out of it).
|
|
4
6
|
import fs from 'node:fs';
|
|
5
|
-
import path from 'node:path';
|
|
6
7
|
import { parseYaml } from '../../engine/yaml.mjs';
|
|
7
|
-
import { skillRoot } from '../../engine/runtime-root.mjs';
|
|
8
8
|
|
|
9
9
|
/** The `$ref` application-stacks.schema.yaml uses for its `operations` block. */
|
|
10
10
|
export const PROVISION_OPERATION_SCHEMA_REF = 'provision-operation.schema.yaml';
|
|
11
11
|
|
|
12
12
|
/** The composed `operations` schema, read from this runtime's modules/schemas. */
|
|
13
13
|
export function provisionOperationSchema() {
|
|
14
|
-
const schema = parseYaml(fs.readFileSync(
|
|
15
|
-
const stacks = parseYaml(fs.readFileSync(
|
|
14
|
+
const schema = parseYaml(fs.readFileSync(new URL('../../modules/schemas/provision-operation.schema.yaml', import.meta.url), 'utf8'));
|
|
15
|
+
const stacks = parseYaml(fs.readFileSync(new URL('../../modules/schemas/application-stacks.schema.yaml', import.meta.url), 'utf8'));
|
|
16
16
|
return { ...schema, $defs: { ...schema.$defs, serviceCredential: stacks.$defs.serviceCredential } };
|
|
17
17
|
}
|