@orchestraworks/cli 0.5.8 → 0.7.0
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 +1 -1
- package/dist/cli/api/approval.js +3 -3
- package/dist/cli/commands/outpost/local.js +3 -3
- package/dist/cli/commands/outpost/machine-names.d.ts +17 -0
- package/dist/cli/commands/outpost/machine-names.js +22 -0
- package/dist/cli/commands/outpost/up.js +7 -5
- package/dist/cli/commands/worker/enroll.d.ts +4 -3
- package/dist/cli/commands/worker/enroll.js +4 -3
- package/dist/cli/core/auth.d.ts +11 -1
- package/dist/cli/core/auth.js +21 -4
- package/dist/cli/core/session-body.d.ts +1 -1
- package/dist/cli/core/session-body.js +1 -1
- package/dist/cli/firstRun.js +2 -2
- package/dist/cli/main.js +4 -3
- package/dist/constructs/environment.d.ts +24 -11
- package/dist/constructs/environment.js +76 -12
- package/dist/constructs/secret.d.ts +17 -7
- package/dist/constructs/secret.js +24 -16
- package/dist/core/labels.d.ts +32 -6
- package/dist/core/labels.js +70 -8
- package/dist/engine/diff.js +38 -11
- package/dist/engine/gateway-key-reconcile.d.ts +1 -2
- package/dist/engine/gateway-key-reconcile.js +19 -15
- package/dist/engine/pipeline-reconcile.js +2 -2
- package/dist/engine/pipeline-workflow-reconcile.js +15 -9
- package/dist/engine/reconcile.js +48 -15
- package/dist/engine/refusals.d.ts +0 -5
- package/dist/engine/refusals.js +1 -5
- package/dist/engine/secrets-apply.d.ts +10 -14
- package/dist/engine/secrets-apply.js +12 -17
- package/dist/engine/workflow-reconcile.d.ts +1 -1
- package/dist/generated/cli-commands.json +170 -34
- package/dist/generated/providers.d.ts +40 -0
- package/dist/generated/providers.js +30 -0
- package/docs/REFERENCE.md +9 -7
- package/node_modules/@orchestraworks/client/dist/esm/models/ApiErrorDetail.d.ts +1 -1
- package/node_modules/@orchestraworks/client/dist/esm/models/CreateEnvironmentRequest.d.ts +7 -0
- package/node_modules/@orchestraworks/client/dist/esm/models/CreateEnvironmentRequest.js +3 -0
- package/node_modules/@orchestraworks/client/dist/esm/models/CreateSecretRequest.d.ts +4 -3
- package/node_modules/@orchestraworks/client/dist/esm/models/Environment.d.ts +7 -0
- package/node_modules/@orchestraworks/client/dist/esm/models/Environment.js +3 -0
- package/node_modules/@orchestraworks/client/dist/esm/models/EnvironmentCredential.d.ts +38 -0
- package/node_modules/@orchestraworks/client/dist/esm/models/EnvironmentCredential.js +45 -0
- package/node_modules/@orchestraworks/client/dist/esm/models/EnvironmentProvisionSpec.d.ts +1 -1
- package/node_modules/@orchestraworks/client/dist/esm/models/EnvironmentProvisionSpecRequest.d.ts +1 -1
- package/node_modules/@orchestraworks/client/dist/esm/models/EnvironmentSnapshot.d.ts +1 -1
- package/node_modules/@orchestraworks/client/dist/esm/models/InjectionRecipe.d.ts +6 -0
- package/node_modules/@orchestraworks/client/dist/esm/models/InjectionRecipe.js +2 -0
- package/node_modules/@orchestraworks/client/dist/esm/models/OAuthTokenRequest.d.ts +1 -1
- package/node_modules/@orchestraworks/client/dist/esm/models/Secret.d.ts +1 -7
- package/node_modules/@orchestraworks/client/dist/esm/models/Secret.js +0 -4
- package/node_modules/@orchestraworks/client/dist/esm/models/UpdateEnvironmentRequest.d.ts +7 -0
- package/node_modules/@orchestraworks/client/dist/esm/models/UpdateEnvironmentRequest.js +3 -0
- package/node_modules/@orchestraworks/client/dist/esm/models/UpdateSecretRequest.d.ts +4 -3
- package/node_modules/@orchestraworks/client/dist/esm/models/index.d.ts +1 -0
- package/node_modules/@orchestraworks/client/dist/esm/models/index.js +1 -0
- package/node_modules/@orchestraworks/client/dist/models/ApiErrorDetail.d.ts +1 -1
- package/node_modules/@orchestraworks/client/dist/models/CreateEnvironmentRequest.d.ts +7 -0
- package/node_modules/@orchestraworks/client/dist/models/CreateEnvironmentRequest.js +3 -0
- package/node_modules/@orchestraworks/client/dist/models/CreateSecretRequest.d.ts +4 -3
- package/node_modules/@orchestraworks/client/dist/models/Environment.d.ts +7 -0
- package/node_modules/@orchestraworks/client/dist/models/Environment.js +3 -0
- package/node_modules/@orchestraworks/client/dist/models/EnvironmentCredential.d.ts +38 -0
- package/node_modules/@orchestraworks/client/dist/models/EnvironmentCredential.js +52 -0
- package/node_modules/@orchestraworks/client/dist/models/EnvironmentProvisionSpec.d.ts +1 -1
- package/node_modules/@orchestraworks/client/dist/models/EnvironmentProvisionSpecRequest.d.ts +1 -1
- package/node_modules/@orchestraworks/client/dist/models/EnvironmentSnapshot.d.ts +1 -1
- package/node_modules/@orchestraworks/client/dist/models/InjectionRecipe.d.ts +6 -0
- package/node_modules/@orchestraworks/client/dist/models/InjectionRecipe.js +2 -0
- package/node_modules/@orchestraworks/client/dist/models/OAuthTokenRequest.d.ts +1 -1
- package/node_modules/@orchestraworks/client/dist/models/Secret.d.ts +1 -7
- package/node_modules/@orchestraworks/client/dist/models/Secret.js +0 -4
- package/node_modules/@orchestraworks/client/dist/models/UpdateEnvironmentRequest.d.ts +7 -0
- package/node_modules/@orchestraworks/client/dist/models/UpdateEnvironmentRequest.js +3 -0
- package/node_modules/@orchestraworks/client/dist/models/UpdateSecretRequest.d.ts +4 -3
- package/node_modules/@orchestraworks/client/dist/models/index.d.ts +1 -0
- package/node_modules/@orchestraworks/client/dist/models/index.js +1 -0
- package/node_modules/@orchestraworks/client/package.json +1 -1
- package/package.json +4 -4
- package/skills/orchestra/SKILL.md +132 -18
- package/skills/orchestra-fdk/references/authoring.md +511 -20
- package/skills/orchestra-fdk/references/environment.md +49 -12
- package/skills/orchestra-fdk/references/integrations/code-repo.md +26 -5
- package/skills/orchestra-fdk/references/phases/1-discover.md +1 -1
- package/skills/orchestra-fdk/references/phases/2-plan.md +1 -1
- package/skills/orchestra-fdk/references/troubleshooting.md +3 -2
- package/templates/bug-fix/main.ts +7 -4
- package/templates/engineering-team/lib/environment.ts +6 -3
- package/templates/engineering-team/package.json +1 -1
- package/templates/todo-factory/main.ts +7 -4
- package/templates/todo-factory/package.json +1 -1
package/dist/engine/reconcile.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import { CONNECTOR_SECRET_WIRE_FIELDS, connectorImmutableFields, } from "../constructs/connector.js";
|
|
7
7
|
import { isEnvImportMarker, parseEnvImportMarker } from "../constructs/references.js";
|
|
8
8
|
import { isGatewayKeyRecipe } from "../core/gateway-key-recipe.js";
|
|
9
|
-
import { createLabels, labelsPatch, MANAGED_BY_LABEL_KEY, stampManagedBy } from "../core/labels.js";
|
|
9
|
+
import { createLabels, labelsPatch, MANAGED_BY_LABEL_KEY, oldMarkersMoved, stampManagedBy } from "../core/labels.js";
|
|
10
10
|
import { isRefToken, parseRefToken, refToken } from "../core/tokens.js";
|
|
11
11
|
import { ApplyError, credentialValueWritten, defaultPrint, createTeamResolver, describeTargetOrganization, failing, getBySlugOrUndefined, modelSettingsUnchanged, stampTeam, standbyCapacityUnchanged, subsetDeepEqual, } from "./apply-core.js";
|
|
12
12
|
import { preApprovalLevers, typedAtTerminalRemedy, } from "../cli/core/approval-policy.js";
|
|
@@ -22,7 +22,7 @@ import { applyCeremonyBackedConnection, isCeremonyBackedConnection, } from "./co
|
|
|
22
22
|
import { assertManagedChatConnectionForDesired } from "./connection-readiness.js";
|
|
23
23
|
import { removedConfigurationNotice } from "./connector-configuration.js";
|
|
24
24
|
import { PreflightError, PreflightRefusalError, readConnection, RedactedRefError, reservedProviderSecretIds, resolveSecretRef, validateConnectionImport, validateRefShape, } from "./preflight.js";
|
|
25
|
-
import { allRootSourceLabels, commandLineOccurrencesFor, containsCommandLineRecipe,
|
|
25
|
+
import { allRootSourceLabels, commandLineOccurrencesFor, containsCommandLineRecipe, declaredSecretInjection, decideSecretWrite, metadataInjectionChange, pendingSecretWrite, reconcileInjection, replacesLiveCredentialValue, resolveSecretValueSource, } from "./secrets-apply.js";
|
|
26
26
|
import { collectCommandLineValues, } from "./command-line-values.js";
|
|
27
27
|
// These live in the leaf module `engine/apply-core.ts` so the per-kind reconcile lanes can share them
|
|
28
28
|
// without importing this monolith, which imports THEM — a cycle. Re-exported here so `engine/reconcile`
|
|
@@ -185,7 +185,7 @@ export async function reconcile(plan, apis, opts, appliedOut) {
|
|
|
185
185
|
await applyComputeProvider(resource, apis, outcomes, applied, opts.onComputeProviderKey);
|
|
186
186
|
break;
|
|
187
187
|
case "environment":
|
|
188
|
-
await applyEnvironment(resource, apis, outcomes, applied, reserved, teams);
|
|
188
|
+
await applyEnvironment(resource, apis, outcomes, applied, connections, reserved, teams);
|
|
189
189
|
break;
|
|
190
190
|
case "skill":
|
|
191
191
|
await applySkill(resource, apis, outcomes, applied, teams);
|
|
@@ -376,14 +376,14 @@ async function applySecrets(plan, apis, opts, env, outcomes, applied, teams, gat
|
|
|
376
376
|
? undefined
|
|
377
377
|
: resolveSecretValueSource(resource.valueFrom, env);
|
|
378
378
|
// Diffed against the live recipe so a value-less recipe edit still PATCHes instead of silently no-oping.
|
|
379
|
-
const
|
|
380
|
-
|
|
381
|
-
const
|
|
379
|
+
const injectionChange = metadataInjectionChange(declaredSecretInjection(resource.payload), live?.injection);
|
|
380
|
+
// A marker an apply before the rename stamped moves to the new prefix even when nothing else changes.
|
|
381
|
+
const labelsMove = oldMarkersMoved(live?.labels);
|
|
382
382
|
const decision = decideSecretWrite(resolvedValue, live !== undefined, {
|
|
383
383
|
slug,
|
|
384
384
|
envName,
|
|
385
385
|
injectionChange,
|
|
386
|
-
|
|
386
|
+
...(labelsMove !== undefined ? { labelsChange: { labels: labelsMove } } : {}),
|
|
387
387
|
commandLinePending,
|
|
388
388
|
});
|
|
389
389
|
if (decision.kind === "skip-empty") {
|
|
@@ -399,6 +399,7 @@ async function applySecrets(plan, apis, opts, env, outcomes, applied, teams, gat
|
|
|
399
399
|
value: resolvedValue,
|
|
400
400
|
id: live?.id,
|
|
401
401
|
liveInjection: live?.injection,
|
|
402
|
+
labelsMove,
|
|
402
403
|
replacesLiveValue: replacesLiveCredentialValue(resource.valueFrom, decision.kind === "overwrite" ? "overwrite" : "create"),
|
|
403
404
|
});
|
|
404
405
|
}
|
|
@@ -481,8 +482,7 @@ async function applySecrets(plan, apis, opts, env, outcomes, applied, teams, gat
|
|
|
481
482
|
}
|
|
482
483
|
// Write phase — creates and overwrites, in plan order.
|
|
483
484
|
for (const p of secretPlans) {
|
|
484
|
-
const desiredInjection = p.resource.payload
|
|
485
|
-
const desiredHosts = declaredSecretHosts(p.resource.payload);
|
|
485
|
+
const desiredInjection = declaredSecretInjection(p.resource.payload);
|
|
486
486
|
if (p.decision.kind === "create") {
|
|
487
487
|
const placement = {};
|
|
488
488
|
stampTeam(placement, p.team);
|
|
@@ -498,7 +498,6 @@ async function applySecrets(plan, apis, opts, env, outcomes, applied, teams, gat
|
|
|
498
498
|
...placement,
|
|
499
499
|
// Live is absent, so never a `null` clear here.
|
|
500
500
|
...(desiredInjection !== undefined ? { injection: desiredInjection } : {}),
|
|
501
|
-
...(desiredHosts !== undefined ? { hosts: desiredHosts } : {}),
|
|
502
501
|
};
|
|
503
502
|
const created = await failing(() => apis.secrets.createSecret({ createSecretRequest: body }), { kind: "secret", slug: p.slug, op: "create" }, outcomes);
|
|
504
503
|
p.id = created.id;
|
|
@@ -513,16 +512,16 @@ async function applySecrets(plan, apis, opts, env, outcomes, applied, teams, gat
|
|
|
513
512
|
description: p.resource.payload.description,
|
|
514
513
|
value: p.value,
|
|
515
514
|
...(injection !== undefined ? { injection } : {}),
|
|
516
|
-
...(
|
|
515
|
+
...(p.labelsMove !== undefined ? { labels: p.labelsMove } : {}),
|
|
517
516
|
};
|
|
518
517
|
await failing(() => apis.secrets.updateSecret({ id: p.id, updateSecretRequest: body }), { kind: "secret", slug: p.slug, op: "update" }, outcomes);
|
|
519
518
|
}
|
|
520
519
|
else if (p.decision.kind === "metadata-update") {
|
|
521
|
-
// The secret exists with no fresh value but its recipe or
|
|
522
|
-
//
|
|
520
|
+
// The secret exists with no fresh value but its recipe changed or an old marker moves: a value-less PATCH
|
|
521
|
+
// carrying the recipe and the label move alone.
|
|
523
522
|
const body = {
|
|
524
523
|
...(p.decision.injection !== undefined ? { injection: p.decision.injection } : {}),
|
|
525
|
-
...(p.decision.
|
|
524
|
+
...(p.decision.labels !== undefined ? { labels: p.decision.labels } : {}),
|
|
526
525
|
};
|
|
527
526
|
await failing(() => apis.secrets.updateSecret({ id: p.id, updateSecretRequest: body }), { kind: "secret", slug: p.slug, op: "update" }, outcomes);
|
|
528
527
|
}
|
|
@@ -839,7 +838,26 @@ function connectionExpectFor(imports, ref) {
|
|
|
839
838
|
}
|
|
840
839
|
return { provider, install: Object.keys(install).length > 0 ? install : undefined };
|
|
841
840
|
}
|
|
842
|
-
|
|
841
|
+
/** The prefix an env value carries before a credential reference, which the egress edge reads. */
|
|
842
|
+
const ENV_REFERENCE_PREFIX = "orchestra:";
|
|
843
|
+
const CREDENTIAL_REFERENCE = /^(secret|connection)\/(.+)$/;
|
|
844
|
+
/**
|
|
845
|
+
* `secret/<ref>` or `connection/<ref>` with its ref, a reference token or an import as written, resolved to
|
|
846
|
+
* the live id: the edge and the platform read an exact id, never a slug. Text naming neither is left as it is.
|
|
847
|
+
*/
|
|
848
|
+
async function resolveCredentialReference(text, label, apis, applied, connections) {
|
|
849
|
+
const match = CREDENTIAL_REFERENCE.exec(text);
|
|
850
|
+
if (match === null)
|
|
851
|
+
return text;
|
|
852
|
+
const [, kind, ref] = match;
|
|
853
|
+
if (kind === "connection")
|
|
854
|
+
return `connection/${await connections.resolve(ref)}`;
|
|
855
|
+
if (isRefToken(ref))
|
|
856
|
+
return `secret/${resolveManagedToken(ref, applied)}`;
|
|
857
|
+
validateRefShape(ref, label);
|
|
858
|
+
return `secret/${(await resolveSecretRef(apis, { value: ref, sourceLabel: label })).id}`;
|
|
859
|
+
}
|
|
860
|
+
async function applyEnvironment(resource, apis, outcomes, applied, connections, reserved, teams) {
|
|
843
861
|
const body = clonePayload(resource.payload);
|
|
844
862
|
const team = await teams.desired(body.teamId, { kind: "environment", slug: resource.slug, op: "get" }, outcomes);
|
|
845
863
|
stampTeam(body, team);
|
|
@@ -884,6 +902,21 @@ async function applyEnvironment(resource, apis, outcomes, applied, reserved, tea
|
|
|
884
902
|
reservedProviderSecretIds: await reserved(),
|
|
885
903
|
}, outcomes);
|
|
886
904
|
}
|
|
905
|
+
// Each credential an env value or a default names becomes its id before anything is written.
|
|
906
|
+
const env = (launchSpec.env ?? {});
|
|
907
|
+
for (const [name, value] of Object.entries(env)) {
|
|
908
|
+
if (!value.startsWith(ENV_REFERENCE_PREFIX))
|
|
909
|
+
continue;
|
|
910
|
+
const label = `environment '${envPath}' env '${name}'`;
|
|
911
|
+
env[name] =
|
|
912
|
+
ENV_REFERENCE_PREFIX +
|
|
913
|
+
(await resolveCredentialReference(value.slice(ENV_REFERENCE_PREFIX.length), label, apis, applied, connections));
|
|
914
|
+
}
|
|
915
|
+
const defaults = (body.credentials ?? []);
|
|
916
|
+
for (const [index, entry] of defaults.entries()) {
|
|
917
|
+
const label = `environment '${envPath}' credentials[${index}]`;
|
|
918
|
+
entry.credential = await resolveCredentialReference(String(entry.credential), label, apis, applied, connections);
|
|
919
|
+
}
|
|
887
920
|
// A declared record's token, or an imported slug, becomes the record's id; `null` stays, naming hosted
|
|
888
921
|
// compute.
|
|
889
922
|
const providerRef = launchSpec.computeProviderId;
|
|
@@ -144,10 +144,5 @@ export declare function byokUnsetSourceMessage(slug: string, modelProvider: stri
|
|
|
144
144
|
* apply lane reaches through {@link refusalOf}.
|
|
145
145
|
*/
|
|
146
146
|
export declare function gatewayKeyPairRefusal(keySlug: string, secretSlug: string, pair: LiveGatewayKeyPair, team: DesiredTeam | undefined, pairContext: TeamIdentityRefusal["pairContext"] | undefined): RefusalVerdict | null;
|
|
147
|
-
/**
|
|
148
|
-
* Lives here rather than in the gateway-key lane because the classifier's message names it and this module
|
|
149
|
-
* must stay a leaf; the lane re-exports it.
|
|
150
|
-
*/
|
|
151
|
-
export declare const PENDING_GATEWAY_KEY_TOKEN_LABEL_KEY = "sfdk.pendingGatewayKeyToken";
|
|
152
147
|
/** The named refusal for a mint that succeeded but whose paired-Secret token write did not. */
|
|
153
148
|
export declare function pendingGatewayKeyTokenRotationMessage(slug: string, secretSlug: string): string;
|
package/dist/engine/refusals.js
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
// nothing rather than guessing. No verdict can carry a credential: the classifiers read source RECIPES.
|
|
13
13
|
import { connectorImmutableFields } from "../constructs/connector.js";
|
|
14
14
|
import { isGatewayKeyRecipe } from "../core/gateway-key-recipe.js";
|
|
15
|
+
import { PENDING_GATEWAY_KEY_TOKEN_LABEL_KEY } from "../core/labels.js";
|
|
15
16
|
import { ApplyError, classifyTeamIdentity, subsetDeepEqual, teamIdentityConflict, } from "./apply-core.js";
|
|
16
17
|
import { isPartiallySuppliedRecipe, missingRootEnvNames, pendingCredentialWrite, } from "./secrets-apply.js";
|
|
17
18
|
import { managedChatConnectionRefusalMessage } from "./connection-readiness.js";
|
|
@@ -266,11 +267,6 @@ function pairedSecretAbsentMessage(slug, secretSlug) {
|
|
|
266
267
|
return (`gateway key '${slug}': the key already exists but its paired secret '${secretSlug}' does not, so ` +
|
|
267
268
|
`there is no token to write and none can be recovered. ${gatewayKeyRotationRemedy(slug)}`);
|
|
268
269
|
}
|
|
269
|
-
/**
|
|
270
|
-
* Lives here rather than in the gateway-key lane because the classifier's message names it and this module
|
|
271
|
-
* must stay a leaf; the lane re-exports it.
|
|
272
|
-
*/
|
|
273
|
-
export const PENDING_GATEWAY_KEY_TOKEN_LABEL_KEY = "sfdk.pendingGatewayKeyToken";
|
|
274
270
|
/** The named refusal for a mint that succeeded but whose paired-Secret token write did not. */
|
|
275
271
|
export function pendingGatewayKeyTokenRotationMessage(slug, secretSlug) {
|
|
276
272
|
return (`gateway key '${slug}': its paired secret '${secretSlug}' still carries the pending marker ` +
|
|
@@ -129,21 +129,17 @@ export declare function metadataInjectionChange(desired: InjectionRecipe | undef
|
|
|
129
129
|
injection: InjectionRecipe | null;
|
|
130
130
|
} | undefined;
|
|
131
131
|
/**
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
* `undefined` when the plan states no hosts at all (a plan written before the field) or they already match.
|
|
132
|
+
* A declared secret's recipe as the plan carries it, its hosts inside it. A plan written while hosts sat beside the
|
|
133
|
+
* recipe has them moved in, so it applies as it did; with no recipe they were never presentable and are dropped.
|
|
135
134
|
*/
|
|
136
|
-
export declare function
|
|
137
|
-
hosts: string[];
|
|
138
|
-
} | undefined;
|
|
139
|
-
/** A declared secret's hosts as the plan carries them; `undefined` for a plan written before the field. */
|
|
140
|
-
export declare function declaredSecretHosts(payload: unknown): string[] | undefined;
|
|
135
|
+
export declare function declaredSecretInjection(payload: unknown): InjectionRecipe | undefined;
|
|
141
136
|
/**
|
|
142
137
|
* The write kinds carry value-free identifiers for the confirmation prompt, never the value itself.
|
|
143
138
|
* - `overwrite` — values are never readable, so any supplied value overwrites.
|
|
144
139
|
* - `noop-resolve` — resolve the id and write nothing, which protects the live credential from an
|
|
145
140
|
* empty overwrite.
|
|
146
|
-
* - `metadata-update` — a recipe
|
|
141
|
+
* - `metadata-update` — a recipe edit, its hosts included, changes no secret VALUE, so it must not be dropped as
|
|
142
|
+
* a noop.
|
|
147
143
|
* - `skip-empty` — the reconcile engine turns this into the named preflight error.
|
|
148
144
|
*/
|
|
149
145
|
export type SecretDecision = {
|
|
@@ -159,13 +155,13 @@ export type SecretDecision = {
|
|
|
159
155
|
} | {
|
|
160
156
|
kind: "metadata-update";
|
|
161
157
|
injection?: InjectionRecipe | null;
|
|
162
|
-
|
|
158
|
+
labels?: Record<string, string | null>;
|
|
163
159
|
} | {
|
|
164
160
|
kind: "skip-empty";
|
|
165
161
|
};
|
|
166
162
|
/**
|
|
167
|
-
* `meta.injectionChange` and `meta.
|
|
168
|
-
*
|
|
163
|
+
* `meta.injectionChange` and `meta.labelsChange` steer only the no-value-plus-exists branch, since a fresh value
|
|
164
|
+
* already writes the recipe and the label move through the create/overwrite body.
|
|
169
165
|
*
|
|
170
166
|
* `meta.commandLinePending` is the value-free branch, and it is load-bearing: a `cli:`-backed recipe has no
|
|
171
167
|
* bytes yet when this runs, because the collection pass deliberately happens AFTER the confirmation this
|
|
@@ -179,8 +175,8 @@ export declare function decideSecretWrite(resolvedValue: string | undefined, exi
|
|
|
179
175
|
injectionChange?: {
|
|
180
176
|
injection: InjectionRecipe | null;
|
|
181
177
|
};
|
|
182
|
-
|
|
183
|
-
|
|
178
|
+
labelsChange?: {
|
|
179
|
+
labels: Record<string, string | null>;
|
|
184
180
|
};
|
|
185
181
|
commandLinePending?: boolean;
|
|
186
182
|
}): SecretDecision;
|
|
@@ -306,25 +306,20 @@ export function metadataInjectionChange(desired, live) {
|
|
|
306
306
|
return live !== undefined ? { injection: null } : undefined;
|
|
307
307
|
}
|
|
308
308
|
/**
|
|
309
|
-
*
|
|
310
|
-
*
|
|
311
|
-
* `undefined` when the plan states no hosts at all (a plan written before the field) or they already match.
|
|
309
|
+
* A declared secret's recipe as the plan carries it, its hosts inside it. A plan written while hosts sat beside the
|
|
310
|
+
* recipe has them moved in, so it applies as it did; with no recipe they were never presentable and are dropped.
|
|
312
311
|
*/
|
|
313
|
-
export function
|
|
314
|
-
|
|
312
|
+
export function declaredSecretInjection(payload) {
|
|
313
|
+
const { injection, hosts } = payload;
|
|
314
|
+
if (injection === undefined)
|
|
315
315
|
return undefined;
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
return
|
|
319
|
-
}
|
|
320
|
-
/** A declared secret's hosts as the plan carries them; `undefined` for a plan written before the field. */
|
|
321
|
-
export function declaredSecretHosts(payload) {
|
|
322
|
-
const hosts = payload.hosts;
|
|
323
|
-
return Array.isArray(hosts) ? hosts : undefined;
|
|
316
|
+
if (injection.hosts !== undefined || !Array.isArray(hosts))
|
|
317
|
+
return injection;
|
|
318
|
+
return { ...injection, hosts: [...hosts] };
|
|
324
319
|
}
|
|
325
320
|
/**
|
|
326
|
-
* `meta.injectionChange` and `meta.
|
|
327
|
-
*
|
|
321
|
+
* `meta.injectionChange` and `meta.labelsChange` steer only the no-value-plus-exists branch, since a fresh value
|
|
322
|
+
* already writes the recipe and the label move through the create/overwrite body.
|
|
328
323
|
*
|
|
329
324
|
* `meta.commandLinePending` is the value-free branch, and it is load-bearing: a `cli:`-backed recipe has no
|
|
330
325
|
* bytes yet when this runs, because the collection pass deliberately happens AFTER the confirmation this
|
|
@@ -346,8 +341,8 @@ export function decideSecretWrite(resolvedValue, exists, meta) {
|
|
|
346
341
|
if (!exists) {
|
|
347
342
|
return { kind: "skip-empty" };
|
|
348
343
|
}
|
|
349
|
-
if (meta.injectionChange !== undefined || meta.
|
|
350
|
-
return { kind: "metadata-update", ...meta.injectionChange, ...meta.
|
|
344
|
+
if (meta.injectionChange !== undefined || meta.labelsChange !== undefined) {
|
|
345
|
+
return { kind: "metadata-update", ...meta.injectionChange, ...meta.labelsChange };
|
|
351
346
|
}
|
|
352
347
|
return { kind: "noop-resolve" };
|
|
353
348
|
}
|
|
@@ -77,7 +77,7 @@ export declare function resolveWorkflow(payload: WorkflowPayload, resolvers: Wor
|
|
|
77
77
|
export declare function workflowChanges(desired: ResolvedWorkflow, live: LiveWorkflow): WorkflowFieldChange[];
|
|
78
78
|
export interface ReconcileWorkflowsOptions {
|
|
79
79
|
resolvers: WorkflowResolvers;
|
|
80
|
-
/** The factory whose
|
|
80
|
+
/** The factory whose managed-by stamp marks the entries apply pins. */
|
|
81
81
|
factory: string;
|
|
82
82
|
/** Preview only: every write is fenced. */
|
|
83
83
|
dryRun?: boolean;
|
|
@@ -22819,6 +22819,26 @@
|
|
|
22819
22819
|
}
|
|
22820
22820
|
}
|
|
22821
22821
|
},
|
|
22822
|
+
"credentials": {
|
|
22823
|
+
"schema": {
|
|
22824
|
+
"kind": "array",
|
|
22825
|
+
"items": {
|
|
22826
|
+
"kind": "object",
|
|
22827
|
+
"fields": {
|
|
22828
|
+
"credential": {
|
|
22829
|
+
"schema": {
|
|
22830
|
+
"kind": "scalar"
|
|
22831
|
+
}
|
|
22832
|
+
},
|
|
22833
|
+
"replace": {
|
|
22834
|
+
"schema": {
|
|
22835
|
+
"kind": "scalar"
|
|
22836
|
+
}
|
|
22837
|
+
}
|
|
22838
|
+
}
|
|
22839
|
+
}
|
|
22840
|
+
}
|
|
22841
|
+
},
|
|
22822
22842
|
"kind": {
|
|
22823
22843
|
"schema": {
|
|
22824
22844
|
"kind": "scalar"
|
|
@@ -23188,6 +23208,26 @@
|
|
|
23188
23208
|
}
|
|
23189
23209
|
}
|
|
23190
23210
|
},
|
|
23211
|
+
"credentials": {
|
|
23212
|
+
"schema": {
|
|
23213
|
+
"kind": "array",
|
|
23214
|
+
"items": {
|
|
23215
|
+
"kind": "object",
|
|
23216
|
+
"fields": {
|
|
23217
|
+
"credential": {
|
|
23218
|
+
"schema": {
|
|
23219
|
+
"kind": "scalar"
|
|
23220
|
+
}
|
|
23221
|
+
},
|
|
23222
|
+
"replace": {
|
|
23223
|
+
"schema": {
|
|
23224
|
+
"kind": "scalar"
|
|
23225
|
+
}
|
|
23226
|
+
}
|
|
23227
|
+
}
|
|
23228
|
+
}
|
|
23229
|
+
}
|
|
23230
|
+
},
|
|
23191
23231
|
"kind": {
|
|
23192
23232
|
"schema": {
|
|
23193
23233
|
"kind": "scalar"
|
|
@@ -23614,6 +23654,26 @@
|
|
|
23614
23654
|
}
|
|
23615
23655
|
}
|
|
23616
23656
|
},
|
|
23657
|
+
"credentials": {
|
|
23658
|
+
"schema": {
|
|
23659
|
+
"kind": "array",
|
|
23660
|
+
"items": {
|
|
23661
|
+
"kind": "object",
|
|
23662
|
+
"fields": {
|
|
23663
|
+
"credential": {
|
|
23664
|
+
"schema": {
|
|
23665
|
+
"kind": "scalar"
|
|
23666
|
+
}
|
|
23667
|
+
},
|
|
23668
|
+
"replace": {
|
|
23669
|
+
"schema": {
|
|
23670
|
+
"kind": "scalar"
|
|
23671
|
+
}
|
|
23672
|
+
}
|
|
23673
|
+
}
|
|
23674
|
+
}
|
|
23675
|
+
}
|
|
23676
|
+
},
|
|
23617
23677
|
"kind": {
|
|
23618
23678
|
"schema": {
|
|
23619
23679
|
"kind": "scalar"
|
|
@@ -24075,6 +24135,26 @@
|
|
|
24075
24135
|
}
|
|
24076
24136
|
}
|
|
24077
24137
|
},
|
|
24138
|
+
"credentials": {
|
|
24139
|
+
"schema": {
|
|
24140
|
+
"kind": "array",
|
|
24141
|
+
"items": {
|
|
24142
|
+
"kind": "object",
|
|
24143
|
+
"fields": {
|
|
24144
|
+
"credential": {
|
|
24145
|
+
"schema": {
|
|
24146
|
+
"kind": "scalar"
|
|
24147
|
+
}
|
|
24148
|
+
},
|
|
24149
|
+
"replace": {
|
|
24150
|
+
"schema": {
|
|
24151
|
+
"kind": "scalar"
|
|
24152
|
+
}
|
|
24153
|
+
}
|
|
24154
|
+
}
|
|
24155
|
+
}
|
|
24156
|
+
}
|
|
24157
|
+
},
|
|
24078
24158
|
"kind": {
|
|
24079
24159
|
"schema": {
|
|
24080
24160
|
"kind": "scalar"
|
|
@@ -24503,6 +24583,26 @@
|
|
|
24503
24583
|
}
|
|
24504
24584
|
}
|
|
24505
24585
|
},
|
|
24586
|
+
"credentials": {
|
|
24587
|
+
"schema": {
|
|
24588
|
+
"kind": "array",
|
|
24589
|
+
"items": {
|
|
24590
|
+
"kind": "object",
|
|
24591
|
+
"fields": {
|
|
24592
|
+
"credential": {
|
|
24593
|
+
"schema": {
|
|
24594
|
+
"kind": "scalar"
|
|
24595
|
+
}
|
|
24596
|
+
},
|
|
24597
|
+
"replace": {
|
|
24598
|
+
"schema": {
|
|
24599
|
+
"kind": "scalar"
|
|
24600
|
+
}
|
|
24601
|
+
}
|
|
24602
|
+
}
|
|
24603
|
+
}
|
|
24604
|
+
}
|
|
24605
|
+
},
|
|
24506
24606
|
"provisionSpec": {
|
|
24507
24607
|
"schema": {
|
|
24508
24608
|
"kind": "object",
|
|
@@ -24862,6 +24962,26 @@
|
|
|
24862
24962
|
}
|
|
24863
24963
|
}
|
|
24864
24964
|
},
|
|
24965
|
+
"credentials": {
|
|
24966
|
+
"schema": {
|
|
24967
|
+
"kind": "array",
|
|
24968
|
+
"items": {
|
|
24969
|
+
"kind": "object",
|
|
24970
|
+
"fields": {
|
|
24971
|
+
"credential": {
|
|
24972
|
+
"schema": {
|
|
24973
|
+
"kind": "scalar"
|
|
24974
|
+
}
|
|
24975
|
+
},
|
|
24976
|
+
"replace": {
|
|
24977
|
+
"schema": {
|
|
24978
|
+
"kind": "scalar"
|
|
24979
|
+
}
|
|
24980
|
+
}
|
|
24981
|
+
}
|
|
24982
|
+
}
|
|
24983
|
+
}
|
|
24984
|
+
},
|
|
24865
24985
|
"kind": {
|
|
24866
24986
|
"schema": {
|
|
24867
24987
|
"kind": "scalar"
|
|
@@ -46431,7 +46551,7 @@
|
|
|
46431
46551
|
"required": true,
|
|
46432
46552
|
"repeatable": false,
|
|
46433
46553
|
"credential": true,
|
|
46434
|
-
"description": "Secret value. This is write-only and is never returned by management APIs."
|
|
46554
|
+
"description": "Secret value. This is write-only and is never returned by management APIs. For git over HTTPS, store base64 of <user>:<token> as the value, such as the output of printf 'x-access-token:%s' \"$TOKEN\" | base64 | tr -d '\\n' for a GitHub token, and present it as Authorization: Basic ${secret}."
|
|
46435
46555
|
},
|
|
46436
46556
|
{
|
|
46437
46557
|
"name": "expires-at",
|
|
@@ -46531,6 +46651,14 @@
|
|
|
46531
46651
|
"kind": "scalar"
|
|
46532
46652
|
}
|
|
46533
46653
|
}
|
|
46654
|
+
},
|
|
46655
|
+
"hosts": {
|
|
46656
|
+
"schema": {
|
|
46657
|
+
"kind": "array",
|
|
46658
|
+
"items": {
|
|
46659
|
+
"kind": "scalar"
|
|
46660
|
+
}
|
|
46661
|
+
}
|
|
46534
46662
|
}
|
|
46535
46663
|
}
|
|
46536
46664
|
}
|
|
@@ -46640,18 +46768,18 @@
|
|
|
46640
46768
|
"kind": "scalar"
|
|
46641
46769
|
}
|
|
46642
46770
|
}
|
|
46771
|
+
},
|
|
46772
|
+
"hosts": {
|
|
46773
|
+
"schema": {
|
|
46774
|
+
"kind": "array",
|
|
46775
|
+
"items": {
|
|
46776
|
+
"kind": "scalar"
|
|
46777
|
+
}
|
|
46778
|
+
}
|
|
46643
46779
|
}
|
|
46644
46780
|
}
|
|
46645
46781
|
}
|
|
46646
46782
|
},
|
|
46647
|
-
"hosts": {
|
|
46648
|
-
"schema": {
|
|
46649
|
-
"kind": "array",
|
|
46650
|
-
"items": {
|
|
46651
|
-
"kind": "scalar"
|
|
46652
|
-
}
|
|
46653
|
-
}
|
|
46654
|
-
},
|
|
46655
46783
|
"usableBy": {
|
|
46656
46784
|
"schema": {
|
|
46657
46785
|
"kind": "array",
|
|
@@ -47095,18 +47223,18 @@
|
|
|
47095
47223
|
"kind": "scalar"
|
|
47096
47224
|
}
|
|
47097
47225
|
}
|
|
47226
|
+
},
|
|
47227
|
+
"hosts": {
|
|
47228
|
+
"schema": {
|
|
47229
|
+
"kind": "array",
|
|
47230
|
+
"items": {
|
|
47231
|
+
"kind": "scalar"
|
|
47232
|
+
}
|
|
47233
|
+
}
|
|
47098
47234
|
}
|
|
47099
47235
|
}
|
|
47100
47236
|
}
|
|
47101
47237
|
},
|
|
47102
|
-
"hosts": {
|
|
47103
|
-
"schema": {
|
|
47104
|
-
"kind": "array",
|
|
47105
|
-
"items": {
|
|
47106
|
-
"kind": "scalar"
|
|
47107
|
-
}
|
|
47108
|
-
}
|
|
47109
|
-
},
|
|
47110
47238
|
"usableBy": {
|
|
47111
47239
|
"schema": {
|
|
47112
47240
|
"kind": "array",
|
|
@@ -47571,18 +47699,18 @@
|
|
|
47571
47699
|
"kind": "scalar"
|
|
47572
47700
|
}
|
|
47573
47701
|
}
|
|
47702
|
+
},
|
|
47703
|
+
"hosts": {
|
|
47704
|
+
"schema": {
|
|
47705
|
+
"kind": "array",
|
|
47706
|
+
"items": {
|
|
47707
|
+
"kind": "scalar"
|
|
47708
|
+
}
|
|
47709
|
+
}
|
|
47574
47710
|
}
|
|
47575
47711
|
}
|
|
47576
47712
|
}
|
|
47577
47713
|
},
|
|
47578
|
-
"hosts": {
|
|
47579
|
-
"schema": {
|
|
47580
|
-
"kind": "array",
|
|
47581
|
-
"items": {
|
|
47582
|
-
"kind": "scalar"
|
|
47583
|
-
}
|
|
47584
|
-
}
|
|
47585
|
-
},
|
|
47586
47714
|
"usableBy": {
|
|
47587
47715
|
"schema": {
|
|
47588
47716
|
"kind": "array",
|
|
@@ -47968,7 +48096,7 @@
|
|
|
47968
48096
|
"required": false,
|
|
47969
48097
|
"repeatable": false,
|
|
47970
48098
|
"credential": true,
|
|
47971
|
-
"description": "Secret value. This is write-only and is never returned by management APIs."
|
|
48099
|
+
"description": "Secret value. This is write-only and is never returned by management APIs. For git over HTTPS, store base64 of <user>:<token> as the value, such as the output of printf 'x-access-token:%s' \"$TOKEN\" | base64 | tr -d '\\n' for a GitHub token, and present it as Authorization: Basic ${secret}."
|
|
47972
48100
|
},
|
|
47973
48101
|
{
|
|
47974
48102
|
"name": "expires-at",
|
|
@@ -48045,6 +48173,14 @@
|
|
|
48045
48173
|
"kind": "scalar"
|
|
48046
48174
|
}
|
|
48047
48175
|
}
|
|
48176
|
+
},
|
|
48177
|
+
"hosts": {
|
|
48178
|
+
"schema": {
|
|
48179
|
+
"kind": "array",
|
|
48180
|
+
"items": {
|
|
48181
|
+
"kind": "scalar"
|
|
48182
|
+
}
|
|
48183
|
+
}
|
|
48048
48184
|
}
|
|
48049
48185
|
}
|
|
48050
48186
|
}
|
|
@@ -48154,18 +48290,18 @@
|
|
|
48154
48290
|
"kind": "scalar"
|
|
48155
48291
|
}
|
|
48156
48292
|
}
|
|
48293
|
+
},
|
|
48294
|
+
"hosts": {
|
|
48295
|
+
"schema": {
|
|
48296
|
+
"kind": "array",
|
|
48297
|
+
"items": {
|
|
48298
|
+
"kind": "scalar"
|
|
48299
|
+
}
|
|
48300
|
+
}
|
|
48157
48301
|
}
|
|
48158
48302
|
}
|
|
48159
48303
|
}
|
|
48160
48304
|
},
|
|
48161
|
-
"hosts": {
|
|
48162
|
-
"schema": {
|
|
48163
|
-
"kind": "array",
|
|
48164
|
-
"items": {
|
|
48165
|
-
"kind": "scalar"
|
|
48166
|
-
}
|
|
48167
|
-
}
|
|
48168
|
-
},
|
|
48169
48305
|
"usableBy": {
|
|
48170
48306
|
"schema": {
|
|
48171
48307
|
"kind": "array",
|