@supacloud/cli 0.84.0 → 0.86.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 +26 -5
- package/dist/index.js +393 -72
- package/dist/shared/context.d.ts +1 -0
- package/dist/shared/tools/app-tools.d.ts +3 -1
- package/dist/shared/tools/application-schemas.d.ts +34 -0
- package/dist/shared/tools/application-tools.d.ts +2 -1
- package/dist/shared/tools/deploy-tools.d.ts +6 -0
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -310,6 +310,26 @@ legacy `.env` fallback. Core URL, credential, and project-ref values are not
|
|
|
310
310
|
filled by mixing sources. If `SUPACLOUD_ENV` is set without a complete process
|
|
311
311
|
context, it strictly selects `.env.supacloud.<value>`.
|
|
312
312
|
|
|
313
|
+
For one-command deployments, declare public build variables explicitly in the
|
|
314
|
+
target configuration:
|
|
315
|
+
|
|
316
|
+
```json
|
|
317
|
+
{
|
|
318
|
+
"targets": {
|
|
319
|
+
"web": {
|
|
320
|
+
"type": "frontend",
|
|
321
|
+
"root": "apps/web",
|
|
322
|
+
"id": "web",
|
|
323
|
+
"buildEnv": ["VITE_API_URL", "VITE_SUPABASE_ANON_KEY"]
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
`buildEnv` is an allowlist. The selected profile values are injected only into
|
|
330
|
+
the local build command; values are never printed, undeclared values are not
|
|
331
|
+
passed through, and platform credentials or runtime secrets are rejected.
|
|
332
|
+
|
|
313
333
|
The two credential scopes are separate. Management-backed remote commands use
|
|
314
334
|
only `SUPACLOUD_API_URL` + `SUPACLOUD_API_TOKEN`. An application profile using
|
|
315
335
|
`SUPABASE_URL` + `SUPABASE_SERVICE_ROLE_KEY` can be auto-linked for `status`,
|
|
@@ -884,11 +904,12 @@ whether the body is empty and the configured header names. Update receipts bind
|
|
|
884
904
|
delete receipts return the matched revision as `deleted_updated_at`.
|
|
885
905
|
|
|
886
906
|
For secret writes, `--from-env` accepts a comma-separated list of environment
|
|
887
|
-
variable names. The CLI reads each non-empty value from
|
|
888
|
-
|
|
889
|
-
printed. Names must be unique
|
|
890
|
-
up to 256 characters).
|
|
891
|
-
|
|
907
|
+
variable names. The CLI reads each non-empty value from the currently selected
|
|
908
|
+
profile source, such as `.env.supacloud.test` selected by `--env test`; command
|
|
909
|
+
arguments contain names only and values are never printed. Names must be unique
|
|
910
|
+
shell-style identifiers (`[A-Za-z_][A-Za-z0-9_]*`, up to 256 characters).
|
|
911
|
+
Missing or empty values fail before any HTTP request. Do not combine
|
|
912
|
+
`--from-env` with the compatibility `--secrets` input.
|
|
892
913
|
|
|
893
914
|
Branch promotion is migration-first. `branch promotion_plan` prints pending
|
|
894
915
|
versions, names, statement counts, and checksums without echoing SQL into terminal
|
package/dist/index.js
CHANGED
|
@@ -9144,6 +9144,7 @@ function resolveSupaCloudContext(env = process.env, cwd = process.cwd(), selecti
|
|
|
9144
9144
|
credentialScope: core.credentialScope,
|
|
9145
9145
|
source: source.kind,
|
|
9146
9146
|
sourcePath: source.path,
|
|
9147
|
+
environmentVariables: source.values,
|
|
9147
9148
|
insecureTls
|
|
9148
9149
|
};
|
|
9149
9150
|
}
|
|
@@ -9153,7 +9154,7 @@ var ACTION_POLICY = {
|
|
|
9153
9154
|
deploy: { write: ["deploy"] },
|
|
9154
9155
|
applications: {
|
|
9155
9156
|
read: ["list_releases", "get_release", "get_runtime", "get_deployment_evidence", "get_configuration", "get_release_transfer_plan", "get_promotion_plan", "get_promotion_status", "get_rollback_snapshot", "get_history", "get_deploy_plan", "logs", "get_preview_plan", "list_previews", "get_preview"],
|
|
9156
|
-
write: ["upload_release", "put_configuration", "transfer_release", "promote_application", "reconcile_promotion", "create_preview", "reconcile_preview", "cleanup_preview", "activate_release", "deploy_release", "rollback_release", "reconcile_activation", "retire_activation"]
|
|
9157
|
+
write: ["upload_release", "put_configuration", "release_application", "transfer_release", "promote_application", "reconcile_promotion", "create_preview", "reconcile_preview", "cleanup_preview", "activate_release", "deploy_release", "rollback_release", "reconcile_activation", "retire_activation"]
|
|
9157
9158
|
},
|
|
9158
9159
|
project: {
|
|
9159
9160
|
read: ["get", "endpoints", "health", "logs", "api_keys", "settings", "tasks", "task_detail", "task_stats", "dlq", "background_settings"],
|
|
@@ -9249,7 +9250,7 @@ var ACTION_POLICY = {
|
|
|
9249
9250
|
app: {
|
|
9250
9251
|
local: ["init", "generate", "dev", "watch", "verify-plan", "compile", "check", "graph", "explain", "export-tools", "context", "doctor", "fix", "plan", "build"],
|
|
9251
9252
|
read: ["status", "logs", "transfer-plan", "promote-plan", "rollback-plan", "history", "deploy-plan", "diff", "promote-status", "preview-plan", "previews", "preview-list", "preview-status"],
|
|
9252
|
-
write: ["upload", "configure", "transfer", "promote", "promote-reconcile", "deploy", "rollback", "reconcile", "retire", "preview", "preview-create", "preview-reconcile", "preview-cleanup"]
|
|
9253
|
+
write: ["release", "upload", "configure", "transfer", "promote", "promote-reconcile", "deploy", "rollback", "reconcile", "retire", "preview", "preview-create", "preview-reconcile", "preview-cleanup"]
|
|
9253
9254
|
},
|
|
9254
9255
|
db: {
|
|
9255
9256
|
local: ["context", "lint", "explain", "diff", "role_sql"],
|
|
@@ -10477,6 +10478,37 @@ function parseApplicationDeployPlan(value) {
|
|
|
10477
10478
|
throw new Error("Invalid application deploy plan action");
|
|
10478
10479
|
return value;
|
|
10479
10480
|
}
|
|
10481
|
+
// node_modules/@supacloud/delivery/src/application-release-operation.ts
|
|
10482
|
+
var closed3 = { additionalProperties: false };
|
|
10483
|
+
var nullableActivation = Union([ApplicationActivationIdSchema, Null()]);
|
|
10484
|
+
var ApplicationReleaseRequestSchema = _Object_({
|
|
10485
|
+
release_id: ApplicationReleaseIdSchema,
|
|
10486
|
+
configuration_id: Optional(ApplicationConfigurationIdSchema),
|
|
10487
|
+
configuration_write: Optional(ApplicationConfigurationWriteSchema),
|
|
10488
|
+
activation_id: Optional(ApplicationActivationIdSchema),
|
|
10489
|
+
expected_activation_id: Optional(nullableActivation),
|
|
10490
|
+
expected_plan_sha256: Optional(ApplicationReleaseIdSchema)
|
|
10491
|
+
}, closed3);
|
|
10492
|
+
var ApplicationReleaseResultSchema = _Object_({
|
|
10493
|
+
schema: Literal("supacloud.application-release.v1"),
|
|
10494
|
+
project_ref: String2({ pattern: "^[a-z0-9-]{1,20}$" }),
|
|
10495
|
+
application_id: ApplicationIdSchema,
|
|
10496
|
+
environment_id: ApplicationIdSchema,
|
|
10497
|
+
release_id: ApplicationReleaseIdSchema,
|
|
10498
|
+
configuration_id: ApplicationConfigurationIdSchema,
|
|
10499
|
+
activation_id: ApplicationActivationIdSchema,
|
|
10500
|
+
expected_activation_id: nullableActivation,
|
|
10501
|
+
plan_sha256: ApplicationReleaseIdSchema,
|
|
10502
|
+
action: Union([Literal("activate"), Literal("no-op")]),
|
|
10503
|
+
replayed: Boolean2(),
|
|
10504
|
+
execution_performed: Boolean2()
|
|
10505
|
+
}, closed3);
|
|
10506
|
+
function parseApplicationReleaseResult(value) {
|
|
10507
|
+
if (!Check2(ApplicationReleaseResultSchema, value)) {
|
|
10508
|
+
throw new Error("Invalid application release result");
|
|
10509
|
+
}
|
|
10510
|
+
return structuredClone(value);
|
|
10511
|
+
}
|
|
10480
10512
|
// node_modules/@supacloud/delivery/src/application-history.ts
|
|
10481
10513
|
var scope = {
|
|
10482
10514
|
project_ref: String2({ pattern: "^[a-z0-9-]{1,20}$" }),
|
|
@@ -10561,7 +10593,7 @@ var phaseStatus = Union([
|
|
|
10561
10593
|
Literal("failed"),
|
|
10562
10594
|
Literal("cleaned")
|
|
10563
10595
|
]);
|
|
10564
|
-
var
|
|
10596
|
+
var closed4 = { additionalProperties: false };
|
|
10565
10597
|
var ApplicationPreviewReceiptSchema = _Object_({
|
|
10566
10598
|
schema: Literal("supacloud.application-preview.v1"),
|
|
10567
10599
|
preview_id: String2({ pattern: "^[a-f0-9-]{8,64}$" }),
|
|
@@ -10581,46 +10613,46 @@ var ApplicationPreviewReceiptSchema = _Object_({
|
|
|
10581
10613
|
Literal("cleaned")
|
|
10582
10614
|
]),
|
|
10583
10615
|
resources: _Object_({
|
|
10584
|
-
build_artifact: _Object_({ status: phaseStatus, release_id: ApplicationReleaseIdSchema },
|
|
10616
|
+
build_artifact: _Object_({ status: phaseStatus, release_id: ApplicationReleaseIdSchema }, closed4),
|
|
10585
10617
|
database_branch: _Object_({
|
|
10586
10618
|
status: phaseStatus,
|
|
10587
10619
|
branch_ref: String2({ pattern: "^[A-Za-z0-9_-]{1,20}$" }),
|
|
10588
10620
|
data_mode: Union([Literal("schema_only"), Literal("full_clone")])
|
|
10589
|
-
},
|
|
10621
|
+
}, closed4),
|
|
10590
10622
|
queue_namespace: _Object_({
|
|
10591
10623
|
status: phaseStatus,
|
|
10592
10624
|
namespace: String2({ minLength: 1, maxLength: 128 })
|
|
10593
|
-
},
|
|
10625
|
+
}, closed4),
|
|
10594
10626
|
storage_namespace: _Object_({
|
|
10595
10627
|
status: phaseStatus,
|
|
10596
10628
|
namespace: String2({ minLength: 1, maxLength: 128 })
|
|
10597
|
-
},
|
|
10629
|
+
}, closed4),
|
|
10598
10630
|
test_secret: _Object_({
|
|
10599
10631
|
status: phaseStatus,
|
|
10600
10632
|
name: String2({ minLength: 1, maxLength: 128 }),
|
|
10601
10633
|
value_issued: Literal(false)
|
|
10602
|
-
},
|
|
10634
|
+
}, closed4),
|
|
10603
10635
|
configuration_revision: _Object_({
|
|
10604
10636
|
status: phaseStatus,
|
|
10605
10637
|
configuration_id: Union([ApplicationConfigurationIdSchema, Null()])
|
|
10606
|
-
},
|
|
10638
|
+
}, closed4),
|
|
10607
10639
|
application_activation: _Object_({
|
|
10608
10640
|
status: phaseStatus,
|
|
10609
10641
|
activation_id: Union([ApplicationActivationIdSchema, Null()])
|
|
10610
|
-
},
|
|
10642
|
+
}, closed4),
|
|
10611
10643
|
smoke_test: _Object_({
|
|
10612
10644
|
status: phaseStatus,
|
|
10613
10645
|
checks: _Array_(String2({ minLength: 1, maxLength: 64 }), { maxItems: 32 }),
|
|
10614
10646
|
passed: _Array_(String2({ minLength: 1, maxLength: 64 }), { maxItems: 32 }),
|
|
10615
10647
|
failed: _Array_(String2({ minLength: 1, maxLength: 64 }), { maxItems: 32 })
|
|
10616
|
-
},
|
|
10617
|
-
},
|
|
10648
|
+
}, closed4)
|
|
10649
|
+
}, closed4),
|
|
10618
10650
|
cleanup: _Object_({
|
|
10619
10651
|
required: Boolean2(),
|
|
10620
10652
|
completed: Boolean2(),
|
|
10621
10653
|
error: Union([String2({ minLength: 1, maxLength: 128 }), Null()])
|
|
10622
|
-
},
|
|
10623
|
-
},
|
|
10654
|
+
}, closed4)
|
|
10655
|
+
}, closed4);
|
|
10624
10656
|
function applicationPreviewBranchRef(previewId) {
|
|
10625
10657
|
if (!/^[a-f0-9-]{8,64}$/.test(previewId))
|
|
10626
10658
|
throw new Error("Invalid preview ID");
|
|
@@ -10673,7 +10705,7 @@ function parseApplicationReleaseTransferResult(candidate) {
|
|
|
10673
10705
|
return candidate;
|
|
10674
10706
|
}
|
|
10675
10707
|
// node_modules/@supacloud/delivery/src/deployment-evidence.ts
|
|
10676
|
-
var
|
|
10708
|
+
var closed5 = { additionalProperties: false };
|
|
10677
10709
|
var sha256 = String2({ pattern: "^[a-f0-9]{64}$" });
|
|
10678
10710
|
var isoDate = String2({ minLength: 20, maxLength: 40 });
|
|
10679
10711
|
var status = Union([
|
|
@@ -10700,19 +10732,19 @@ var DatabaseProviderSchema = _Object_({
|
|
|
10700
10732
|
Literal("not-proven"),
|
|
10701
10733
|
Literal("failed")
|
|
10702
10734
|
])
|
|
10703
|
-
},
|
|
10735
|
+
}, closed5),
|
|
10704
10736
|
backup: _Object_({
|
|
10705
10737
|
status,
|
|
10706
10738
|
latest_success_at: Union([isoDate, Null()]),
|
|
10707
10739
|
freshness_seconds: Union([Integer({ minimum: 0 }), Null()])
|
|
10708
|
-
},
|
|
10740
|
+
}, closed5),
|
|
10709
10741
|
recovery: _Object_({
|
|
10710
10742
|
status,
|
|
10711
10743
|
drill_id: Union([String2({ minLength: 1, maxLength: 128 }), Null()]),
|
|
10712
10744
|
rpo_seconds: Union([Integer({ minimum: 0 }), Null()]),
|
|
10713
10745
|
rto_seconds: Union([Integer({ minimum: 0 }), Null()])
|
|
10714
|
-
},
|
|
10715
|
-
},
|
|
10746
|
+
}, closed5)
|
|
10747
|
+
}, closed5);
|
|
10716
10748
|
var componentName = Union([
|
|
10717
10749
|
Literal("management-api"),
|
|
10718
10750
|
Literal("web-console"),
|
|
@@ -10730,7 +10762,7 @@ var DeploymentComponentEvidenceSchema = _Object_({
|
|
|
10730
10762
|
status,
|
|
10731
10763
|
health_check: Union([String2({ minLength: 1, maxLength: 256 }), Null()]),
|
|
10732
10764
|
checked_at: Union([isoDate, Null()])
|
|
10733
|
-
},
|
|
10765
|
+
}, closed5);
|
|
10734
10766
|
var DeploymentEvidenceSchema = _Object_({
|
|
10735
10767
|
schema: Literal(DEPLOYMENT_EVIDENCE_SCHEMA),
|
|
10736
10768
|
status: evidenceStatus,
|
|
@@ -10739,33 +10771,33 @@ var DeploymentEvidenceSchema = _Object_({
|
|
|
10739
10771
|
project_ref: String2({ pattern: "^[a-z0-9-]{1,20}$" }),
|
|
10740
10772
|
application_id: ApplicationIdSchema,
|
|
10741
10773
|
environment_id: ApplicationIdSchema
|
|
10742
|
-
},
|
|
10774
|
+
}, closed5),
|
|
10743
10775
|
source: _Object_({
|
|
10744
10776
|
commit_sha: Union([String2({ pattern: "^[0-9a-f]{7,64}$" }), Null()]),
|
|
10745
10777
|
manifest_sha256: sha256,
|
|
10746
10778
|
contract_schema: Union([String2({ minLength: 1, maxLength: 128 }), Null()]),
|
|
10747
10779
|
environment_binding_version: Union([sha256, Null()])
|
|
10748
|
-
},
|
|
10780
|
+
}, closed5),
|
|
10749
10781
|
database: DatabaseProviderSchema,
|
|
10750
10782
|
components: _Array_(DeploymentComponentEvidenceSchema, { minItems: 1, maxItems: 32 }),
|
|
10751
10783
|
activation: _Object_({
|
|
10752
10784
|
release_id: ApplicationReleaseIdSchema,
|
|
10753
10785
|
configuration_id: ApplicationConfigurationIdSchema,
|
|
10754
10786
|
activation_id: ApplicationConfigurationIdSchema
|
|
10755
|
-
},
|
|
10787
|
+
}, closed5),
|
|
10756
10788
|
health: _Object_({
|
|
10757
10789
|
status,
|
|
10758
10790
|
checked_at: Union([isoDate, Null()]),
|
|
10759
10791
|
authenticated_smoke: status
|
|
10760
|
-
},
|
|
10792
|
+
}, closed5),
|
|
10761
10793
|
rollback: _Object_({
|
|
10762
10794
|
release_id: Union([ApplicationReleaseIdSchema, Null()]),
|
|
10763
10795
|
configuration_id: Union([ApplicationConfigurationIdSchema, Null()]),
|
|
10764
10796
|
status: Union([Literal("ready"), Literal("not-ready"), Literal("unknown")]),
|
|
10765
10797
|
result: Union([status, Null()])
|
|
10766
|
-
},
|
|
10798
|
+
}, closed5),
|
|
10767
10799
|
notes: _Array_(String2({ minLength: 1, maxLength: 512 }), { maxItems: 32 })
|
|
10768
|
-
},
|
|
10800
|
+
}, closed5);
|
|
10769
10801
|
function isIsoDate(value) {
|
|
10770
10802
|
return Number.isFinite(Date.parse(value)) && new Date(value).toISOString() === value;
|
|
10771
10803
|
}
|
|
@@ -10798,13 +10830,13 @@ function parseDeploymentEvidence(value) {
|
|
|
10798
10830
|
return structuredClone(value);
|
|
10799
10831
|
}
|
|
10800
10832
|
// node_modules/@supacloud/delivery/src/application-promotion.ts
|
|
10801
|
-
var
|
|
10833
|
+
var closed6 = { additionalProperties: false };
|
|
10802
10834
|
var projectRef2 = String2({ pattern: "^[a-z0-9-]{1,20}$" });
|
|
10803
10835
|
var sha2562 = ApplicationReleaseIdSchema;
|
|
10804
|
-
var
|
|
10836
|
+
var nullableActivation2 = Union([ApplicationActivationIdSchema, Null()]);
|
|
10805
10837
|
var nullableDigest = Union([sha2562, Null()]);
|
|
10806
10838
|
var observation = {
|
|
10807
|
-
activation_id:
|
|
10839
|
+
activation_id: nullableActivation2,
|
|
10808
10840
|
receipt_confirmed: Boolean2(),
|
|
10809
10841
|
ready: Boolean2(),
|
|
10810
10842
|
smoke_verified: Boolean2(),
|
|
@@ -10835,7 +10867,7 @@ var ApplicationPromotionPlanSchema = _Object_({
|
|
|
10835
10867
|
environment_id: ApplicationIdSchema,
|
|
10836
10868
|
release_id: sha2562,
|
|
10837
10869
|
...observation
|
|
10838
|
-
},
|
|
10870
|
+
}, closed6),
|
|
10839
10871
|
target: _Object_({
|
|
10840
10872
|
candidate_release_id: sha2562,
|
|
10841
10873
|
current_release_id: Union([sha2562, Null()]),
|
|
@@ -10843,18 +10875,18 @@ var ApplicationPromotionPlanSchema = _Object_({
|
|
|
10843
10875
|
configuration_id: Union([ApplicationConfigurationIdSchema, Null()]),
|
|
10844
10876
|
configuration: Union([ApplicationConfigurationViewSchema, Null()]),
|
|
10845
10877
|
...observation
|
|
10846
|
-
},
|
|
10878
|
+
}, closed6),
|
|
10847
10879
|
migrations: _Object_({
|
|
10848
10880
|
ledger_digest: sha2562,
|
|
10849
10881
|
ledger_compatible: Boolean2(),
|
|
10850
10882
|
project_migrations_applied: Boolean2(),
|
|
10851
10883
|
pending_versions: _Array_(String2({ pattern: "^\\d{1,20}$" }), { maxItems: 4096, uniqueItems: true }),
|
|
10852
10884
|
operator_provisioning_required: Boolean2()
|
|
10853
|
-
},
|
|
10885
|
+
}, closed6),
|
|
10854
10886
|
backup: _Object_({
|
|
10855
10887
|
required: Boolean2(),
|
|
10856
10888
|
confirmed: Literal(false)
|
|
10857
|
-
},
|
|
10889
|
+
}, closed6),
|
|
10858
10890
|
action: Union([Literal("promote"), Literal("no-op"), Literal("blocked")]),
|
|
10859
10891
|
blockers: _Array_(Enum([...blocker]), {
|
|
10860
10892
|
maxItems: blocker.length,
|
|
@@ -10863,7 +10895,7 @@ var ApplicationPromotionPlanSchema = _Object_({
|
|
|
10863
10895
|
steps: _Array_(String2({ minLength: 1, maxLength: 64 }), { maxItems: 8, uniqueItems: true }),
|
|
10864
10896
|
execution_performed: Literal(false),
|
|
10865
10897
|
data_recovery: Literal("separate-required")
|
|
10866
|
-
},
|
|
10898
|
+
}, closed6);
|
|
10867
10899
|
function applicationPromotionPlanDigest(value) {
|
|
10868
10900
|
return digest(canonical(value));
|
|
10869
10901
|
}
|
|
@@ -15832,7 +15864,7 @@ Actions: list, upsert, delete`, {
|
|
|
15832
15864
|
action: withDescription(stringEnum(["list", "upsert", "delete"]), "Action"),
|
|
15833
15865
|
ref: withDescription(String2(), "Project ref"),
|
|
15834
15866
|
secrets: withDescription(secretsSchema, "[upsert] Secret list as JSON array or KEY=VALUE,KEY2=VALUE2"),
|
|
15835
|
-
"from-env": withDescription(environmentSecretNamesSchema, "[upsert] Comma-separated environment variable names; values are read from
|
|
15867
|
+
"from-env": withDescription(environmentSecretNamesSchema, "[upsert] Comma-separated environment variable names; values are read from the selected CLI environment"),
|
|
15836
15868
|
name: optional(String2(), "[delete] Secret name to delete")
|
|
15837
15869
|
}, async (args) => {
|
|
15838
15870
|
const { action, ref, secrets, name } = args;
|
|
@@ -16810,6 +16842,7 @@ var ApplicationActivationRetirementResultSchema2 = ApplicationActivationRetireme
|
|
|
16810
16842
|
var ApplicationRollbackSnapshotSchema2 = ApplicationRollbackSnapshotSchema;
|
|
16811
16843
|
var ApplicationActivationHistoryCursorSchema2 = ApplicationActivationHistoryCursorSchema;
|
|
16812
16844
|
var ApplicationPromotionPlanSchema2 = ApplicationPromotionPlanSchema;
|
|
16845
|
+
var ApplicationReleaseRequestSchema2 = ApplicationReleaseRequestSchema;
|
|
16813
16846
|
|
|
16814
16847
|
// src/shared/mutation-protocol.ts
|
|
16815
16848
|
import { createHash as createHash6 } from "node:crypto";
|
|
@@ -17049,7 +17082,7 @@ async function fetchMutationStatus(http, ref, mutationId) {
|
|
|
17049
17082
|
}
|
|
17050
17083
|
|
|
17051
17084
|
// src/shared/tools/application-workflow-schemas.ts
|
|
17052
|
-
var
|
|
17085
|
+
var closed7 = { additionalProperties: false };
|
|
17053
17086
|
var ref5 = String2({ pattern: "^[A-Za-z0-9_-]{1,20}$" });
|
|
17054
17087
|
var uuid = ApplicationActivationIdSchema2;
|
|
17055
17088
|
var nullableUuid = Union([uuid, Null()]);
|
|
@@ -17063,7 +17096,7 @@ var ApplicationPromotionResultSchema = _Object_({
|
|
|
17063
17096
|
plan_sha256: ApplicationReleaseIdSchema2,
|
|
17064
17097
|
action: Literal("promote"),
|
|
17065
17098
|
replayed: Boolean2()
|
|
17066
|
-
},
|
|
17099
|
+
}, closed7);
|
|
17067
17100
|
var ApplicationPromotionStatusSchema = _Object_({
|
|
17068
17101
|
...scope2,
|
|
17069
17102
|
mutation: Unknown(),
|
|
@@ -17082,8 +17115,8 @@ var ApplicationPromotionStatusSchema = _Object_({
|
|
|
17082
17115
|
configuration_id: Union([ApplicationConfigurationIdSchema2, Null()]),
|
|
17083
17116
|
backup_id: Union([String2({ pattern: "^logical-full_[a-z0-9-]{1,20}_[a-f0-9]{32}$" }), Null()]),
|
|
17084
17117
|
data_recovery: Literal("separate-required")
|
|
17085
|
-
},
|
|
17086
|
-
},
|
|
17118
|
+
}, closed7)
|
|
17119
|
+
}, closed7);
|
|
17087
17120
|
var phase = Union([Literal("pending"), Literal("ready"), Literal("failed"), Literal("cleaned")]);
|
|
17088
17121
|
var previewId = String2({ pattern: "^[a-f0-9-]{8,64}$" });
|
|
17089
17122
|
var name = String2({ minLength: 1, maxLength: 256 });
|
|
@@ -17102,35 +17135,35 @@ var ApplicationPreviewReceiptSchema2 = _Object_({
|
|
|
17102
17135
|
Literal("cleaned")
|
|
17103
17136
|
]),
|
|
17104
17137
|
resources: _Object_({
|
|
17105
|
-
build_artifact: _Object_({ status: phase, release_id: ApplicationReleaseIdSchema2 },
|
|
17138
|
+
build_artifact: _Object_({ status: phase, release_id: ApplicationReleaseIdSchema2 }, closed7),
|
|
17106
17139
|
database_branch: _Object_({
|
|
17107
17140
|
status: phase,
|
|
17108
17141
|
branch_ref: ref5,
|
|
17109
17142
|
data_mode: Union([Literal("schema_only"), Literal("full_clone")])
|
|
17110
|
-
},
|
|
17111
|
-
queue_namespace: _Object_({ status: phase, namespace: name },
|
|
17112
|
-
storage_namespace: _Object_({ status: phase, namespace: name },
|
|
17113
|
-
test_secret: _Object_({ status: phase, name, value_issued: Literal(false) },
|
|
17114
|
-
configuration_revision: _Object_({ status: phase, configuration_id: Union([ApplicationConfigurationIdSchema2, Null()]) },
|
|
17115
|
-
application_activation: _Object_({ status: phase, activation_id: nullableUuid },
|
|
17116
|
-
smoke_test: _Object_({ status: phase, checks, passed: checks, failed: checks },
|
|
17117
|
-
},
|
|
17143
|
+
}, closed7),
|
|
17144
|
+
queue_namespace: _Object_({ status: phase, namespace: name }, closed7),
|
|
17145
|
+
storage_namespace: _Object_({ status: phase, namespace: name }, closed7),
|
|
17146
|
+
test_secret: _Object_({ status: phase, name, value_issued: Literal(false) }, closed7),
|
|
17147
|
+
configuration_revision: _Object_({ status: phase, configuration_id: Union([ApplicationConfigurationIdSchema2, Null()]) }, closed7),
|
|
17148
|
+
application_activation: _Object_({ status: phase, activation_id: nullableUuid }, closed7),
|
|
17149
|
+
smoke_test: _Object_({ status: phase, checks, passed: checks, failed: checks }, closed7)
|
|
17150
|
+
}, closed7),
|
|
17118
17151
|
cleanup: _Object_({
|
|
17119
17152
|
required: Boolean2(),
|
|
17120
17153
|
completed: Boolean2(),
|
|
17121
17154
|
error: Union([String2({ pattern: "^[A-Z][A-Z0-9_]{0,63}$" }), Null()])
|
|
17122
|
-
},
|
|
17155
|
+
}, closed7),
|
|
17123
17156
|
branch_name: Optional(String2({ minLength: 1, maxLength: 80 })),
|
|
17124
17157
|
queue_name: Optional(name),
|
|
17125
17158
|
test_secret_name: Optional(name),
|
|
17126
17159
|
source_configuration_id: Optional(Union([ApplicationConfigurationIdSchema2, Null()])),
|
|
17127
17160
|
created_at: Optional(timestamp2),
|
|
17128
17161
|
updated_at: Optional(timestamp2)
|
|
17129
|
-
},
|
|
17162
|
+
}, closed7);
|
|
17130
17163
|
var previewListSchema = _Object_({
|
|
17131
17164
|
...scope2,
|
|
17132
17165
|
previews: _Array_(ApplicationPreviewReceiptSchema2, { maxItems: 1000 })
|
|
17133
|
-
},
|
|
17166
|
+
}, closed7);
|
|
17134
17167
|
function assertScope(value, identity) {
|
|
17135
17168
|
if (value.project_ref !== identity.project_ref || value.application_id !== identity.application_id || value.environment_id !== identity.environment_id)
|
|
17136
17169
|
throw new Error("Application workflow scope mismatch");
|
|
@@ -17597,6 +17630,7 @@ var APPLICATION_TOOL_SCHEMA = {
|
|
|
17597
17630
|
"put_configuration",
|
|
17598
17631
|
"get_deploy_plan",
|
|
17599
17632
|
"deploy_release",
|
|
17633
|
+
"release_application",
|
|
17600
17634
|
"get_release_transfer_plan",
|
|
17601
17635
|
"transfer_release",
|
|
17602
17636
|
"get_promotion_plan",
|
|
@@ -17624,6 +17658,7 @@ var APPLICATION_TOOL_SCHEMA = {
|
|
|
17624
17658
|
activation_id: optional(ApplicationActivationIdSchema2, "[deploy_release/activate_release/reconcile_activation/retire_activation/rollback_release/get_history] Stable activation ID; generated for automatic deployment/rollback if omitted"),
|
|
17625
17659
|
expected_activation_id: optional(Union([ApplicationActivationIdSchema2, Null(), Literal("absent")]), "[deploy_release/activate_release/rollback_release] Current activation ID, or absent for first activation; selected from verified plan for automatic deployment"),
|
|
17626
17660
|
configuration_path: optional(String2(), "[put_configuration] Local configuration write JSON including revision and expected revision"),
|
|
17661
|
+
configuration_write: optional(Unknown(), "[release_application] Parsed immutable configuration write"),
|
|
17627
17662
|
manifest_path: optional(String2(), "[upload_release] Local delivery.manifest.json"),
|
|
17628
17663
|
release_id: optional(ApplicationReleaseIdSchema2, "[get_release/get_deploy_plan/deploy_release/activate_release/reconcile_activation/rollback_release] Immutable application release ID; platform selects previous for default rollback"),
|
|
17629
17664
|
source_ref: optional(String2({ pattern: "^[A-Za-z0-9_-]{1,20}$" }), "[get_release_transfer_plan/transfer_release] Source project ref"),
|
|
@@ -17983,6 +18018,61 @@ function registerApplicationTools(server, http) {
|
|
|
17983
18018
|
const observed = await readDeployPlan(http, args, project);
|
|
17984
18019
|
return observed.failure ?? releaseControlSuccess(operation, { ...observed.identity, plan: observed.plan });
|
|
17985
18020
|
}
|
|
18021
|
+
if (action === "release_application") {
|
|
18022
|
+
const environmentId = text(args, "environment_id");
|
|
18023
|
+
const releaseId = text(args, "release_id");
|
|
18024
|
+
if (!Check2(ApplicationIdSchema2, environmentId) || !Check2(ApplicationReleaseIdSchema2, releaseId)) {
|
|
18025
|
+
throw new Error("Invalid application release identity");
|
|
18026
|
+
}
|
|
18027
|
+
const configurationId = args["configuration_id"];
|
|
18028
|
+
const activationId = args["activation_id"];
|
|
18029
|
+
const expectedActivationId = args["expected_activation_id"];
|
|
18030
|
+
if (configurationId !== undefined && !Check2(ApplicationConfigurationIdSchema2, configurationId)) {
|
|
18031
|
+
throw new Error("Invalid application configuration ID");
|
|
18032
|
+
}
|
|
18033
|
+
if (activationId !== undefined && !Check2(ApplicationActivationIdSchema2, activationId)) {
|
|
18034
|
+
throw new Error("Invalid application activation ID");
|
|
18035
|
+
}
|
|
18036
|
+
if (expectedActivationId !== undefined && expectedActivationId !== null && expectedActivationId !== "absent" && !Check2(ApplicationActivationIdSchema2, expectedActivationId)) {
|
|
18037
|
+
throw new Error("Invalid expected activation ID");
|
|
18038
|
+
}
|
|
18039
|
+
const configurationWrite = args["configuration_write"];
|
|
18040
|
+
const parsedConfigurationWrite = configurationWrite === undefined ? undefined : parseApplicationConfigurationWrite(configurationWrite);
|
|
18041
|
+
const requestedConfigurationId = configurationId ?? parsedConfigurationWrite?.configuration_id;
|
|
18042
|
+
const body = {
|
|
18043
|
+
release_id: releaseId,
|
|
18044
|
+
...configurationId === undefined ? {} : { configuration_id: configurationId },
|
|
18045
|
+
...configurationWrite === undefined ? {} : { configuration_write: configurationWrite },
|
|
18046
|
+
...activationId === undefined ? {} : { activation_id: activationId },
|
|
18047
|
+
...expectedActivationId === undefined ? {} : {
|
|
18048
|
+
expected_activation_id: expectedActivationId === "absent" ? null : expectedActivationId
|
|
18049
|
+
}
|
|
18050
|
+
};
|
|
18051
|
+
if (!Check2(ApplicationReleaseRequestSchema2, body)) {
|
|
18052
|
+
throw new Error("Invalid application release request");
|
|
18053
|
+
}
|
|
18054
|
+
const result = await http.post(`/v1/projects/${project}/applications/${encodeURIComponent(id)}/environments/${encodeURIComponent(environmentId)}/release`, body, { timeoutMs: 120000, maxJsonBytes: 65536, responseTimeoutMs: 30000 });
|
|
18055
|
+
const identity = {
|
|
18056
|
+
project_ref: ref,
|
|
18057
|
+
application_id: id,
|
|
18058
|
+
environment_id: environmentId,
|
|
18059
|
+
release_id: releaseId,
|
|
18060
|
+
...configurationId === undefined ? {} : { configuration_id: configurationId },
|
|
18061
|
+
...activationId === undefined ? {} : { activation_id: activationId }
|
|
18062
|
+
};
|
|
18063
|
+
if (!result.ok)
|
|
18064
|
+
return releaseControlMutationFailure(operation, result, identity);
|
|
18065
|
+
try {
|
|
18066
|
+
if (result.status !== 200)
|
|
18067
|
+
throw new Error;
|
|
18068
|
+
const release = parseApplicationReleaseResult(result.data);
|
|
18069
|
+
if (release.project_ref !== ref || release.application_id !== id || release.environment_id !== environmentId || release.release_id !== releaseId || requestedConfigurationId !== undefined && release.configuration_id !== requestedConfigurationId || activationId !== undefined && release.activation_id !== activationId)
|
|
18070
|
+
throw new Error;
|
|
18071
|
+
return releaseControlSuccess(operation, release);
|
|
18072
|
+
} catch {
|
|
18073
|
+
return releaseControlFailure(operation, "OUTCOME_UNKNOWN", result.status, identity);
|
|
18074
|
+
}
|
|
18075
|
+
}
|
|
17986
18076
|
if (action === "deploy_release")
|
|
17987
18077
|
return deployAction(http, args, project);
|
|
17988
18078
|
if (action === "rollback_release" || action === "get_rollback_snapshot") {
|
|
@@ -21016,7 +21106,7 @@ var starter_metadata_default = {
|
|
|
21016
21106
|
}
|
|
21017
21107
|
},
|
|
21018
21108
|
elysia: {
|
|
21019
|
-
version: "0.29.
|
|
21109
|
+
version: "0.29.1"
|
|
21020
21110
|
},
|
|
21021
21111
|
commands: {
|
|
21022
21112
|
version: "0.9.1"
|
|
@@ -24419,14 +24509,14 @@ var REMOTE_APP_ACTIONS = {
|
|
|
24419
24509
|
"preview-reconcile": "reconcile_preview"
|
|
24420
24510
|
};
|
|
24421
24511
|
var REMOTE_APP_DESCRIPTIONS = {
|
|
24422
|
-
ref: "[upload/configure/transfer-plan/transfer/promote-plan/diff/promote/promote-status/promote-reconcile/preview-plan/preview/previews/preview-list/preview-create/preview-status/preview-reconcile/preview-cleanup/deploy/deploy-plan/status/rollback/rollback-plan/history/reconcile/retire] Project ref (defaults to context)",
|
|
24423
|
-
id: "[upload/configure/transfer-plan/transfer/promote-plan/diff/promote/promote-status/promote-reconcile/preview-plan/preview/previews/preview-list/preview-create/preview-status/preview-reconcile/preview-cleanup/deploy/deploy-plan/status/rollback/rollback-plan/history/reconcile/retire] Application ID",
|
|
24424
|
-
environment_id: "[configure/promote-plan/diff/promote/promote-status/promote-reconcile/preview-plan/preview/previews/preview-list/preview-create/preview-status/preview-reconcile/preview-cleanup/deploy/deploy-plan/status/rollback/rollback-plan/history/reconcile/retire] Target environment ID",
|
|
24425
|
-
configuration_id: "[promote-plan/diff/promote/preview-plan/preview/preview-create/deploy/deploy-plan/rollback] Immutable target configuration revision",
|
|
24512
|
+
ref: "[release/upload/configure/transfer-plan/transfer/promote-plan/diff/promote/promote-status/promote-reconcile/preview-plan/preview/previews/preview-list/preview-create/preview-status/preview-reconcile/preview-cleanup/deploy/deploy-plan/status/rollback/rollback-plan/history/reconcile/retire] Project ref (defaults to context)",
|
|
24513
|
+
id: "[release/upload/configure/transfer-plan/transfer/promote-plan/diff/promote/promote-status/promote-reconcile/preview-plan/preview/previews/preview-list/preview-create/preview-status/preview-reconcile/preview-cleanup/deploy/deploy-plan/status/rollback/rollback-plan/history/reconcile/retire] Application ID",
|
|
24514
|
+
environment_id: "[release/configure/promote-plan/diff/promote/promote-status/promote-reconcile/preview-plan/preview/previews/preview-list/preview-create/preview-status/preview-reconcile/preview-cleanup/deploy/deploy-plan/status/rollback/rollback-plan/history/reconcile/retire] Target environment ID",
|
|
24515
|
+
configuration_id: "[release/promote-plan/diff/promote/preview-plan/preview/preview-create/deploy/deploy-plan/rollback] Immutable target configuration revision",
|
|
24426
24516
|
activation_id: "[deploy/rollback/reconcile/retire] Required explicit activation ID",
|
|
24427
24517
|
expected_activation_id: "[deploy/rollback] Required current activation ID, or absent for first activation",
|
|
24428
|
-
configuration_path: "[configure] Configuration write JSON including revision and expected revision",
|
|
24429
|
-
manifest_path: "[upload] Local delivery.manifest.json",
|
|
24518
|
+
configuration_path: "[release/configure] Configuration write JSON including revision and expected revision",
|
|
24519
|
+
manifest_path: "[release/upload] Local delivery.manifest.json",
|
|
24430
24520
|
release_id: "[preview-plan/preview/preview-create/deploy/deploy-plan/diff/rollback/reconcile] Required immutable application release ID",
|
|
24431
24521
|
source_ref: "[transfer-plan/transfer/promote-plan/diff/promote] Source project ref",
|
|
24432
24522
|
source_release_id: "[transfer-plan/transfer/promote-plan/diff/promote] Source immutable release ID",
|
|
@@ -25340,6 +25430,171 @@ async function runDelivery(args) {
|
|
|
25340
25430
|
const result = await buildDeliveryProject(options, loaded.delivery);
|
|
25341
25431
|
return textResult(JSON.stringify(result, null, 2), !result.ok);
|
|
25342
25432
|
}
|
|
25433
|
+
function resultObject(result) {
|
|
25434
|
+
try {
|
|
25435
|
+
const value = JSON.parse(result.content[0]?.text ?? "");
|
|
25436
|
+
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : undefined;
|
|
25437
|
+
} catch {
|
|
25438
|
+
return;
|
|
25439
|
+
}
|
|
25440
|
+
}
|
|
25441
|
+
function resultErrorCode(result, fallback) {
|
|
25442
|
+
const payload = resultObject(result);
|
|
25443
|
+
const error = payload?.error;
|
|
25444
|
+
const errorRecord = error !== null && typeof error === "object" && !Array.isArray(error) ? error : undefined;
|
|
25445
|
+
return typeof errorRecord?.code === "string" ? errorRecord.code : fallback;
|
|
25446
|
+
}
|
|
25447
|
+
function releasePhaseFailure(phase, result, completed) {
|
|
25448
|
+
const phaseResult = resultObject(result);
|
|
25449
|
+
const upload = completed.upload !== null && typeof completed.upload === "object" && !Array.isArray(completed.upload) ? completed.upload : undefined;
|
|
25450
|
+
const configure = completed.configure !== null && typeof completed.configure === "object" && !Array.isArray(completed.configure) ? completed.configure : undefined;
|
|
25451
|
+
const releaseId = typeof upload?.release_id === "string" ? upload.release_id : undefined;
|
|
25452
|
+
const configurationId = typeof configure?.configuration_id === "string" ? configure.configuration_id : undefined;
|
|
25453
|
+
const payload = {
|
|
25454
|
+
schema: RELEASE_CONTROL_RESPONSE_SCHEMA,
|
|
25455
|
+
ok: false,
|
|
25456
|
+
operation: "applications.release",
|
|
25457
|
+
phase,
|
|
25458
|
+
phases: completed,
|
|
25459
|
+
error: { code: resultErrorCode(result, phase === "build" ? "BUILD_FAILED" : "PHASE_FAILED") },
|
|
25460
|
+
...releaseId === undefined ? {} : { release_id: releaseId },
|
|
25461
|
+
...configurationId === undefined ? {} : { configuration_id: configurationId },
|
|
25462
|
+
...phaseResult === undefined ? {} : { phase_result: phaseResult }
|
|
25463
|
+
};
|
|
25464
|
+
if (phaseResult?.activation_id !== undefined)
|
|
25465
|
+
payload.activation_id = phaseResult.activation_id;
|
|
25466
|
+
if (phaseResult?.expected_activation_id !== undefined) {
|
|
25467
|
+
payload.expected_activation_id = phaseResult.expected_activation_id;
|
|
25468
|
+
}
|
|
25469
|
+
return textResult(JSON.stringify(payload, null, 2), true);
|
|
25470
|
+
}
|
|
25471
|
+
function releaseField(payload, container, field) {
|
|
25472
|
+
const value = payload?.[container];
|
|
25473
|
+
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
25474
|
+
return;
|
|
25475
|
+
const record = value;
|
|
25476
|
+
return typeof record[field] === "string" ? record[field] : undefined;
|
|
25477
|
+
}
|
|
25478
|
+
async function runAppRelease(request, options, delegate) {
|
|
25479
|
+
const ref = request.ref ?? options.projectRef;
|
|
25480
|
+
const id = request.id?.trim();
|
|
25481
|
+
const environmentId = request.environment_id?.trim();
|
|
25482
|
+
if (!ref || !id || !environmentId) {
|
|
25483
|
+
throw new Error("app release requires --ref, --id and --environment_id (ref may come from context)");
|
|
25484
|
+
}
|
|
25485
|
+
if (!Check2(ApplicationIdSchema2, id) || !Check2(ApplicationIdSchema2, environmentId)) {
|
|
25486
|
+
throw new Error("app release requires valid --id and --environment_id");
|
|
25487
|
+
}
|
|
25488
|
+
if (request.configuration_id !== undefined && !Check2(ApplicationConfigurationIdSchema2, request.configuration_id)) {
|
|
25489
|
+
throw new Error("app release requires a valid --configuration_id");
|
|
25490
|
+
}
|
|
25491
|
+
if (request.configuration_path !== undefined && request.configuration_id !== undefined) {
|
|
25492
|
+
throw new Error("app release accepts either --configuration_path or --configuration_id, not both");
|
|
25493
|
+
}
|
|
25494
|
+
if (request.configuration_path === undefined && request.configuration_id === undefined) {
|
|
25495
|
+
throw new Error("app release requires --configuration_path or --configuration_id");
|
|
25496
|
+
}
|
|
25497
|
+
if (request.activation_id !== undefined || request.expected_activation_id !== undefined) {
|
|
25498
|
+
throw new Error("app release generates one activation identity; use app deploy for an exact retry");
|
|
25499
|
+
}
|
|
25500
|
+
const root = resolve17(request.root || process.cwd());
|
|
25501
|
+
const completed = {};
|
|
25502
|
+
let manifestPath;
|
|
25503
|
+
let buildReceipt;
|
|
25504
|
+
if (request.skip_build === true) {
|
|
25505
|
+
if (request.manifest_path === undefined) {
|
|
25506
|
+
throw new Error("app release --skip_build requires --manifest_path");
|
|
25507
|
+
}
|
|
25508
|
+
manifestPath = resolve17(root, request.manifest_path);
|
|
25509
|
+
completed.build = { skipped: true, manifest_path: manifestPath };
|
|
25510
|
+
} else {
|
|
25511
|
+
const built = await runDelivery({ ...request, action: "build", root, format: "json" });
|
|
25512
|
+
buildReceipt = resultObject(built);
|
|
25513
|
+
if (built.isError || !buildReceipt?.ok || buildReceipt.manifest === null || buildReceipt.manifest === undefined) {
|
|
25514
|
+
return releasePhaseFailure("build", built, completed);
|
|
25515
|
+
}
|
|
25516
|
+
const loaded = await loadSupacloudConfig(root);
|
|
25517
|
+
const resolved = resolveSupacloudConfig(loaded, root);
|
|
25518
|
+
manifestPath = join13(resolved.outDir, "delivery", "delivery.manifest.json");
|
|
25519
|
+
completed.build = {
|
|
25520
|
+
ok: true,
|
|
25521
|
+
manifest_path: manifestPath,
|
|
25522
|
+
written: Array.isArray(buildReceipt.written) ? buildReceipt.written.length : 0
|
|
25523
|
+
};
|
|
25524
|
+
}
|
|
25525
|
+
const uploadArgs = {
|
|
25526
|
+
action: "upload_release",
|
|
25527
|
+
ref,
|
|
25528
|
+
id,
|
|
25529
|
+
manifest_path: manifestPath
|
|
25530
|
+
};
|
|
25531
|
+
validateToolArguments(APPLICATION_TOOL_SCHEMA, uploadArgs);
|
|
25532
|
+
const uploaded = await delegate(uploadArgs);
|
|
25533
|
+
const uploadReceipt = resultObject(uploaded);
|
|
25534
|
+
if (uploaded.isError || !uploadReceipt?.ok) {
|
|
25535
|
+
return releasePhaseFailure("upload", uploaded, completed);
|
|
25536
|
+
}
|
|
25537
|
+
const releaseId = releaseField(uploadReceipt, "release", "release_id");
|
|
25538
|
+
if (!releaseId)
|
|
25539
|
+
return releasePhaseFailure("upload", releaseControlFailure("applications.upload_release", "INVALID_RESPONSE", null, { project_ref: ref, application_id: id }), completed);
|
|
25540
|
+
completed.upload = { ok: true, release_id: releaseId };
|
|
25541
|
+
let configurationId = request.configuration_id;
|
|
25542
|
+
let configurationWrite;
|
|
25543
|
+
const activationId = crypto.randomUUID();
|
|
25544
|
+
if (request.configuration_path !== undefined) {
|
|
25545
|
+
const configurationPath = resolve17(root, request.configuration_path);
|
|
25546
|
+
try {
|
|
25547
|
+
configurationWrite = parseApplicationConfigurationWrite(await Bun.file(configurationPath).json());
|
|
25548
|
+
configurationId = configurationWrite.configuration_id;
|
|
25549
|
+
} catch {
|
|
25550
|
+
return releasePhaseFailure("configure", releaseControlFailure("applications.release_application", "INVALID_RESPONSE", null, { project_ref: ref, application_id: id, environment_id: environmentId }), completed);
|
|
25551
|
+
}
|
|
25552
|
+
completed.configure = { delegated: true, configuration_id: configurationId };
|
|
25553
|
+
} else {
|
|
25554
|
+
completed.configure = { delegated: true, configuration_id: configurationId };
|
|
25555
|
+
}
|
|
25556
|
+
const deployArgs = {
|
|
25557
|
+
action: "release_application",
|
|
25558
|
+
ref,
|
|
25559
|
+
id,
|
|
25560
|
+
environment_id: environmentId,
|
|
25561
|
+
release_id: releaseId,
|
|
25562
|
+
configuration_id: configurationId,
|
|
25563
|
+
activation_id: activationId,
|
|
25564
|
+
...configurationWrite === undefined ? {} : { configuration_write: configurationWrite }
|
|
25565
|
+
};
|
|
25566
|
+
validateToolArguments(APPLICATION_TOOL_SCHEMA, deployArgs);
|
|
25567
|
+
const deployed = await delegate(deployArgs);
|
|
25568
|
+
const deployReceipt = resultObject(deployed);
|
|
25569
|
+
if (deployed.isError || !deployReceipt?.ok) {
|
|
25570
|
+
return releasePhaseFailure("deploy", deployed, completed);
|
|
25571
|
+
}
|
|
25572
|
+
completed.deploy = deployReceipt;
|
|
25573
|
+
const result = {
|
|
25574
|
+
schema: RELEASE_CONTROL_RESPONSE_SCHEMA,
|
|
25575
|
+
ok: true,
|
|
25576
|
+
operation: "applications.release",
|
|
25577
|
+
project_ref: ref,
|
|
25578
|
+
application_id: id,
|
|
25579
|
+
environment_id: environmentId,
|
|
25580
|
+
release_id: releaseId,
|
|
25581
|
+
configuration_id: configurationId,
|
|
25582
|
+
manifest_path: manifestPath,
|
|
25583
|
+
build: buildReceipt ? completed.build : { skipped: true, manifest_path: manifestPath },
|
|
25584
|
+
phases: completed,
|
|
25585
|
+
no_op: deployReceipt.action === "no-op" || deployReceipt.no_op === true,
|
|
25586
|
+
execution_performed: deployReceipt.execution_performed === true,
|
|
25587
|
+
...typeof deployReceipt.activation_id === "string" ? { activation_id: deployReceipt.activation_id } : {}
|
|
25588
|
+
};
|
|
25589
|
+
return request.format === "json" || request.json === true ? textResult(JSON.stringify(result, null, 2)) : textResult([
|
|
25590
|
+
`${ref}/${id}/${environmentId}: ${result.no_op ? "no-op" : "released"}`,
|
|
25591
|
+
`Release: ${releaseId}`,
|
|
25592
|
+
`Configuration: ${configurationId}`,
|
|
25593
|
+
`Activation: ${result.activation_id ?? "not performed"}`,
|
|
25594
|
+
`Build: ${request.skip_build ? "skipped" : "completed"}`
|
|
25595
|
+
].join(`
|
|
25596
|
+
`));
|
|
25597
|
+
}
|
|
25343
25598
|
function formatReleaseTransfer(result) {
|
|
25344
25599
|
if (result.isError)
|
|
25345
25600
|
return result;
|
|
@@ -25610,7 +25865,7 @@ async function runAppTool(request, options = {}) {
|
|
|
25610
25865
|
if (request.database_url !== undefined && request.action !== "dev" && request.action !== "watch") {
|
|
25611
25866
|
throw new ScaffoldError("SCAFFOLD_OPTION_INVALID", "--database-url applies only to app dev --profile integration");
|
|
25612
25867
|
}
|
|
25613
|
-
if (request.json !== undefined && !Object.hasOwn(REMOTE_APP_ACTIONS, request.action) && request.action !== "promote")
|
|
25868
|
+
if (request.json !== undefined && !Object.hasOwn(REMOTE_APP_ACTIONS, request.action) && request.action !== "promote" && request.action !== "release")
|
|
25614
25869
|
throw new Error("--json applies only to remote app actions");
|
|
25615
25870
|
if (request.json && request.format === "text")
|
|
25616
25871
|
throw new Error("--json and --format text cannot be combined");
|
|
@@ -25620,6 +25875,12 @@ async function runAppTool(request, options = {}) {
|
|
|
25620
25875
|
return textResult("App remote actions require a Management API context.", true);
|
|
25621
25876
|
return runPromotion(request, options, delegate);
|
|
25622
25877
|
}
|
|
25878
|
+
if (request.action === "release") {
|
|
25879
|
+
const delegate = options.getApplications?.();
|
|
25880
|
+
if (!delegate)
|
|
25881
|
+
return textResult("App remote actions require a Management API context.", true);
|
|
25882
|
+
return runAppRelease(request, options, delegate);
|
|
25883
|
+
}
|
|
25623
25884
|
if (Object.hasOwn(REMOTE_APP_ACTIONS, request.action)) {
|
|
25624
25885
|
const delegate = options.getApplications?.();
|
|
25625
25886
|
if (!delegate)
|
|
@@ -25716,6 +25977,7 @@ function registerAppTools(server, options = {}) {
|
|
|
25716
25977
|
"fix",
|
|
25717
25978
|
"plan",
|
|
25718
25979
|
"build",
|
|
25980
|
+
"release",
|
|
25719
25981
|
"upload",
|
|
25720
25982
|
"configure",
|
|
25721
25983
|
"transfer-plan",
|
|
@@ -25753,11 +26015,11 @@ function registerAppTools(server, options = {}) {
|
|
|
25753
26015
|
"dry-run": optional(Boolean2(), "[generate] CLI alias of dry_run"),
|
|
25754
26016
|
register_in: optional(String2(), "[generate] Existing parent module file for module/resource; uses the compiler AST editor"),
|
|
25755
26017
|
"register-in": optional(String2(), "[generate] CLI alias of register_in"),
|
|
25756
|
-
root: optional(String2(), "[dev/plan/build/compile/check] Project directory containing supacloud.config.ts (default: current directory)"),
|
|
26018
|
+
root: optional(String2(), "[dev/plan/build/release/compile/check] Project directory containing supacloud.config.ts (default: current directory)"),
|
|
25757
26019
|
include: optional(String2(), "[dev/compile/check] Comma-separated glob patterns for source files"),
|
|
25758
26020
|
out_dir: optional(String2(), "[dev/compile/plan/build/export-tools] Output directory (default: configured outDir)"),
|
|
25759
26021
|
strict: optional(Boolean2(), "[dev/compile/check] Promote warnings to errors"),
|
|
25760
|
-
format: optional(stringEnum(["text", "json"]), "[dev/generate/compile/check/plan/deploy-plan/diff/history/promote-plan/graph/export-tools] Output format (default: text)"),
|
|
26022
|
+
format: optional(stringEnum(["text", "json"]), "[dev/generate/compile/check/plan/release/deploy-plan/diff/history/promote-plan/graph/export-tools] Output format (default: text)"),
|
|
25761
26023
|
json: optional(Boolean2(), "[history/transfer-plan/transfer/promote-plan] Preserve or return the full machine-readable receipt"),
|
|
25762
26024
|
profile: optional(stringEnum(["fast", "integration"]), "[dev] Run dev or dev:integration; integration verifies an explicit loopback database"),
|
|
25763
26025
|
once: optional(Boolean2(), "[dev] Validate and report once without watching"),
|
|
@@ -25766,7 +26028,8 @@ function registerAppTools(server, options = {}) {
|
|
|
25766
26028
|
"database-url": optional(String2(), "[dev] CLI alias of database_url"),
|
|
25767
26029
|
target: optional(String2(), "[explain/context/verify-plan] Provider class name / token name / command name / job name / module name"),
|
|
25768
26030
|
fix: optional(String2(), "[fix] Path to a DiagnosticFix JSON file produced by `doctor --format json`"),
|
|
25769
|
-
write: optional(Boolean2(), "[fix] Write the fix to disk (default: preview only)")
|
|
26031
|
+
write: optional(Boolean2(), "[fix] Write the fix to disk (default: preview only)"),
|
|
26032
|
+
skip_build: optional(Boolean2(), "[release] Reuse --manifest_path instead of running the local delivery build")
|
|
25770
26033
|
}, (request) => runAppTool(request, options));
|
|
25771
26034
|
}
|
|
25772
26035
|
var APP_ALIAS_ACTIONS = ["generate", "compile", "check", "graph", "explain", "context", "doctor", "fix"];
|
|
@@ -27675,6 +27938,14 @@ import { createHash as createHash9 } from "node:crypto";
|
|
|
27675
27938
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
27676
27939
|
import { basename as basename8, dirname as dirname11, join as join17, relative as relative10, resolve as resolve22, sep as sep5 } from "node:path";
|
|
27677
27940
|
var MAX_SOURCE_BYTES = 256 * 1024 * 1024;
|
|
27941
|
+
var PUBLIC_BUILD_ENV_PREFIXES = ["PUBLIC_", "VITE_", "NEXT_PUBLIC_", "NUXT_PUBLIC_", "ASTRO_PUBLIC_"];
|
|
27942
|
+
var SENSITIVE_BUILD_ENV = /(?:^|_)(?:PASSWORD|PASS|SECRET|TOKEN|KEY|CREDENTIAL|AUTHORIZATION|COOKIE|SESSION)(?:_|$)|(?:DATABASE_URL|DATABASE_URI|CONNECTION_STRING|DSN|PRIVATE_KEY)/i;
|
|
27943
|
+
function isPublicBuildEnv(name) {
|
|
27944
|
+
return PUBLIC_BUILD_ENV_PREFIXES.some((prefix) => name.startsWith(prefix));
|
|
27945
|
+
}
|
|
27946
|
+
function isProtectedBuildEnv(name) {
|
|
27947
|
+
return name.startsWith("SUPACLOUD_") || name === "SUPABASE_SERVICE_ROLE_KEY" || name === "SUPABASE_ACCESS_TOKEN" || name === "MANAGEMENT_API_URL" || name === "MANAGEMENT_API_TOKEN";
|
|
27948
|
+
}
|
|
27678
27949
|
var deployToolSchema = {
|
|
27679
27950
|
ref: optional(String2(), "Project ref (defaults to the linked project)"),
|
|
27680
27951
|
target: optional(String2(), "Named deploy target from supacloud.json"),
|
|
@@ -27745,6 +28016,26 @@ function optionalBoolean(value, field) {
|
|
|
27745
28016
|
throw new Error(`supacloud.json ${field} must be a boolean`);
|
|
27746
28017
|
return value;
|
|
27747
28018
|
}
|
|
28019
|
+
function optionalStringArray(value, field) {
|
|
28020
|
+
if (value === undefined)
|
|
28021
|
+
return;
|
|
28022
|
+
if (!Array.isArray(value) || value.some((item) => typeof item !== "string" || !item.trim())) {
|
|
28023
|
+
throw new Error(`supacloud.json ${field} must be an array of non-empty strings`);
|
|
28024
|
+
}
|
|
28025
|
+
return value.map((item) => item.trim()).map((name) => {
|
|
28026
|
+
if (!/^[A-Z_][A-Z0-9_]*$/.test(name)) {
|
|
28027
|
+
throw new Error(`supacloud.json ${field} must contain uppercase environment variable names`);
|
|
28028
|
+
}
|
|
28029
|
+
const isPublic = isPublicBuildEnv(name);
|
|
28030
|
+
if (SENSITIVE_BUILD_ENV.test(name) && !isPublic) {
|
|
28031
|
+
throw new Error(`supacloud.json ${field} cannot include sensitive variable '${name}'; use runtime secrets instead`);
|
|
28032
|
+
}
|
|
28033
|
+
if (isProtectedBuildEnv(name)) {
|
|
28034
|
+
throw new Error(`supacloud.json ${field} cannot include platform credential '${name}'`);
|
|
28035
|
+
}
|
|
28036
|
+
return name;
|
|
28037
|
+
});
|
|
28038
|
+
}
|
|
27748
28039
|
function deployTargetConfig(candidate, name) {
|
|
27749
28040
|
const value = record4(candidate);
|
|
27750
28041
|
if (!value || value.type !== "frontend" && value.type !== "edge_function") {
|
|
@@ -27761,6 +28052,7 @@ function deployTargetConfig(candidate, name) {
|
|
|
27761
28052
|
slug: optionalText(value.slug, `targets.${name}.slug`),
|
|
27762
28053
|
buildCommand: optionalText(value.buildCommand, `targets.${name}.buildCommand`),
|
|
27763
28054
|
outputDirectory: optionalText(value.outputDirectory, `targets.${name}.outputDirectory`),
|
|
28055
|
+
buildEnv: optionalStringArray(value.buildEnv, `targets.${name}.buildEnv`),
|
|
27764
28056
|
bundleDirectory: optionalText(value.bundleDirectory, `targets.${name}.bundleDirectory`),
|
|
27765
28057
|
entrypoint: optionalText(value.entrypoint, `targets.${name}.entrypoint`),
|
|
27766
28058
|
verifyJwt: optionalBoolean(value.verifyJwt, `targets.${name}.verifyJwt`),
|
|
@@ -27786,7 +28078,8 @@ async function readDeployConfig(configRoot) {
|
|
|
27786
28078
|
id: optionalText(frontend.id, "frontend.id"),
|
|
27787
28079
|
root: optionalText(frontend.root, "frontend.root"),
|
|
27788
28080
|
buildCommand: optionalText(frontend.buildCommand, "frontend.buildCommand"),
|
|
27789
|
-
outputDirectory: optionalText(frontend.outputDirectory, "frontend.outputDirectory")
|
|
28081
|
+
outputDirectory: optionalText(frontend.outputDirectory, "frontend.outputDirectory"),
|
|
28082
|
+
buildEnv: optionalStringArray(frontend.buildEnv, "frontend.buildEnv")
|
|
27790
28083
|
} : undefined
|
|
27791
28084
|
};
|
|
27792
28085
|
}
|
|
@@ -27857,7 +28150,8 @@ function selectTarget(configRoot, invocationDirectory, config, requestedName) {
|
|
|
27857
28150
|
root: config.frontend?.root,
|
|
27858
28151
|
id: config.frontend?.id,
|
|
27859
28152
|
buildCommand: config.frontend?.buildCommand,
|
|
27860
|
-
outputDirectory: config.frontend?.outputDirectory
|
|
28153
|
+
outputDirectory: config.frontend?.outputDirectory,
|
|
28154
|
+
buildEnv: config.frontend?.buildEnv
|
|
27861
28155
|
}]];
|
|
27862
28156
|
if (targets.length === 0)
|
|
27863
28157
|
throw new Error("supacloud.json defines no deploy targets");
|
|
@@ -27905,10 +28199,28 @@ function resolveInsideProject(projectDirectory, candidate, allowRoot = false) {
|
|
|
27905
28199
|
}
|
|
27906
28200
|
return resolved;
|
|
27907
28201
|
}
|
|
27908
|
-
|
|
28202
|
+
function createBuildEnvironment(names, environmentVariables) {
|
|
28203
|
+
const selectedNames = [...new Set(names || [])].sort();
|
|
28204
|
+
const selectedNameSet = new Set(selectedNames);
|
|
28205
|
+
const values = environmentVariables ?? process.env;
|
|
28206
|
+
const env = Object.fromEntries(Object.entries(process.env).filter(([name]) => !isProtectedBuildEnv(name) && (!isPublicBuildEnv(name) || selectedNameSet.has(name)) && (!SENSITIVE_BUILD_ENV.test(name) || isPublicBuildEnv(name))));
|
|
28207
|
+
const missing = selectedNames.filter((name) => !values[name]?.trim());
|
|
28208
|
+
for (const name of selectedNames) {
|
|
28209
|
+
const value = values[name];
|
|
28210
|
+
if (value !== undefined)
|
|
28211
|
+
env[name] = value;
|
|
28212
|
+
}
|
|
28213
|
+
return { env, names: selectedNames, missing };
|
|
28214
|
+
}
|
|
28215
|
+
function assertBuildEnvironment(build, skipBuild) {
|
|
28216
|
+
if (!skipBuild && build.missing.length > 0) {
|
|
28217
|
+
throw new Error(`Missing build environment variables: ${build.missing.join(", ")}`);
|
|
28218
|
+
}
|
|
28219
|
+
}
|
|
28220
|
+
async function runBuild(command, cwd, environment, json) {
|
|
27909
28221
|
const child = Bun.spawn(["sh", "-c", command], {
|
|
27910
28222
|
cwd,
|
|
27911
|
-
env:
|
|
28223
|
+
env: environment,
|
|
27912
28224
|
stdio: ["inherit", json ? 2 : "inherit", "inherit"]
|
|
27913
28225
|
});
|
|
27914
28226
|
const exitCode = await child.exited;
|
|
@@ -28036,6 +28348,7 @@ function registerDeployTools(server, http, options = {}) {
|
|
|
28036
28348
|
throw new Error(`Deploy target '${target.name}' root is not a regular directory: ${projectDirectory}`);
|
|
28037
28349
|
}
|
|
28038
28350
|
const requestedId = String(args.id || target.config.id || "").trim() || undefined;
|
|
28351
|
+
const build = createBuildEnvironment(target.config.buildEnv, options.environmentVariables);
|
|
28039
28352
|
const report = phaseReporter(args.json === true);
|
|
28040
28353
|
report("inspect", `${target.name} (${projectRef})`);
|
|
28041
28354
|
if (target.config.type === "edge_function") {
|
|
@@ -28073,14 +28386,17 @@ function registerDeployTools(server, http, options = {}) {
|
|
|
28073
28386
|
project_ref: projectRef,
|
|
28074
28387
|
slug,
|
|
28075
28388
|
build_command: args.skip_build === true ? null : buildCommand,
|
|
28389
|
+
build_env: build.names,
|
|
28390
|
+
missing_build_env: build.missing,
|
|
28076
28391
|
bundle_directory: bundleDirectory,
|
|
28077
28392
|
expected_active_version: activeVersion,
|
|
28078
28393
|
expected_activation_id: activationId
|
|
28079
28394
|
}, null, 2) }] };
|
|
28080
28395
|
}
|
|
28396
|
+
assertBuildEnvironment(build, args.skip_build === true);
|
|
28081
28397
|
if (args.skip_build !== true) {
|
|
28082
28398
|
report("build", buildCommand);
|
|
28083
|
-
await runBuild(buildCommand, projectDirectory, args.json === true);
|
|
28399
|
+
await runBuild(buildCommand, projectDirectory, build.env, args.json === true);
|
|
28084
28400
|
} else {
|
|
28085
28401
|
report("build", "skipped");
|
|
28086
28402
|
}
|
|
@@ -28130,12 +28446,15 @@ function registerDeployTools(server, http, options = {}) {
|
|
|
28130
28446
|
project_ref: projectRef,
|
|
28131
28447
|
deployment_id: selected.id,
|
|
28132
28448
|
build_command: args.skip_build === true ? null : buildCommand,
|
|
28449
|
+
build_env: build.names,
|
|
28450
|
+
missing_build_env: build.missing,
|
|
28133
28451
|
output_directory: outputDirectory
|
|
28134
28452
|
}, null, 2) }] };
|
|
28135
28453
|
}
|
|
28454
|
+
assertBuildEnvironment(build, args.skip_build === true);
|
|
28136
28455
|
if (args.skip_build !== true) {
|
|
28137
28456
|
report("build", buildCommand);
|
|
28138
|
-
await runBuild(buildCommand, projectDirectory, args.json === true);
|
|
28457
|
+
await runBuild(buildCommand, projectDirectory, build.env, args.json === true);
|
|
28139
28458
|
} else {
|
|
28140
28459
|
report("build", "skipped");
|
|
28141
28460
|
}
|
|
@@ -28523,7 +28842,7 @@ function registerRemoteDevTools(server, options = {}) {
|
|
|
28523
28842
|
// package.json
|
|
28524
28843
|
var package_default = {
|
|
28525
28844
|
name: "@supacloud/cli",
|
|
28526
|
-
version: "0.
|
|
28845
|
+
version: "0.86.0",
|
|
28527
28846
|
description: "Project-scoped CLI for SupaCloud users",
|
|
28528
28847
|
type: "module",
|
|
28529
28848
|
main: "./dist/index.js",
|
|
@@ -28576,13 +28895,13 @@ var package_default = {
|
|
|
28576
28895
|
},
|
|
28577
28896
|
dependencies: {
|
|
28578
28897
|
"@supacloud/compiler": "^0.43.0",
|
|
28579
|
-
"@supacloud/delivery": "0.
|
|
28898
|
+
"@supacloud/delivery": "0.14.0",
|
|
28580
28899
|
"@supacloud/db": "0.16.0",
|
|
28581
28900
|
typebox: "1.3.34"
|
|
28582
28901
|
},
|
|
28583
28902
|
overrides: {
|
|
28584
28903
|
"@supacloud/contracts": "0.8.0",
|
|
28585
|
-
"@supacloud/delivery": "0.
|
|
28904
|
+
"@supacloud/delivery": "0.14.0",
|
|
28586
28905
|
"@graphql-tools/utils": "^12.0.3"
|
|
28587
28906
|
},
|
|
28588
28907
|
devDependencies: {
|
|
@@ -28842,6 +29161,7 @@ EXAMPLES
|
|
|
28842
29161
|
${preferredCommand} app compile --root .
|
|
28843
29162
|
${preferredCommand} app plan --root . --format json
|
|
28844
29163
|
${preferredCommand} app build --root .
|
|
29164
|
+
${preferredCommand} --env test app release --id orders --environment_id test --configuration_path configuration.json
|
|
28845
29165
|
${preferredCommand} app upload --ref abc123 --id orders --manifest_path generated/delivery/delivery.manifest.json
|
|
28846
29166
|
${preferredCommand} app configure --ref abc123 --id orders --environment_id test --configuration_path configuration.json
|
|
28847
29167
|
${preferredCommand} app deploy-plan --ref abc123 --id orders --environment_id test --release_id <sha256> --configuration_id <uuid>
|
|
@@ -29110,7 +29430,7 @@ function createCliTools(context, confirmProduction) {
|
|
|
29110
29430
|
assign(captureTools((server) => registerAuthTools(server, http)));
|
|
29111
29431
|
assign(captureTools((server) => registerOAuthClientTools(server, http)));
|
|
29112
29432
|
assign(captureTools((server) => registerStorageTools(server, http)));
|
|
29113
|
-
const advancedTools = captureTools((server) => registerAdvancedTools(server, http,
|
|
29433
|
+
const advancedTools = captureTools((server) => registerAdvancedTools(server, http, context.environmentVariables, {
|
|
29114
29434
|
readOnly: context.readOnly
|
|
29115
29435
|
}));
|
|
29116
29436
|
assign(advancedTools);
|
|
@@ -29134,6 +29454,7 @@ function createCliTools(context, confirmProduction) {
|
|
|
29134
29454
|
environment: context.environment,
|
|
29135
29455
|
projectRef: context.projectRef || undefined,
|
|
29136
29456
|
cwd: process.cwd(),
|
|
29457
|
+
environmentVariables: context.environmentVariables,
|
|
29137
29458
|
edgeFunctionDeploy: advancedTools.edge_functions?.callback
|
|
29138
29459
|
})));
|
|
29139
29460
|
assign(captureTools((server) => registerGatewayTools(server, http, {
|
package/dist/shared/context.d.ts
CHANGED
|
@@ -21,6 +21,7 @@ export interface ResolvedContext {
|
|
|
21
21
|
credentialScope: ContextCredentialScope;
|
|
22
22
|
source: ContextSourceKind;
|
|
23
23
|
sourcePath: string | null;
|
|
24
|
+
environmentVariables: Readonly<Record<string, string>>;
|
|
24
25
|
insecureTls: boolean;
|
|
25
26
|
}
|
|
26
27
|
export declare function resolveSupaCloudContext(env?: NodeJS.ProcessEnv, cwd?: string, selection?: ContextSelection): ResolvedContext;
|
|
@@ -36,7 +36,7 @@ export interface AppToolOptions {
|
|
|
36
36
|
onDevProgress?: (result: ToolResult) => void;
|
|
37
37
|
}
|
|
38
38
|
export interface AppToolArguments {
|
|
39
|
-
action: "init" | "generate" | "dev" | "watch" | "verify-plan" | "compile" | "check" | "graph" | "explain" | "export-tools" | "context" | "doctor" | "fix" | "plan" | "build" | "promote" | keyof typeof REMOTE_APP_ACTIONS;
|
|
39
|
+
action: "init" | "generate" | "dev" | "watch" | "verify-plan" | "compile" | "check" | "graph" | "explain" | "export-tools" | "context" | "doctor" | "fix" | "plan" | "build" | "release" | "promote" | keyof typeof REMOTE_APP_ACTIONS;
|
|
40
40
|
ref?: string;
|
|
41
41
|
id?: string;
|
|
42
42
|
environment_id?: string;
|
|
@@ -45,6 +45,8 @@ export interface AppToolArguments {
|
|
|
45
45
|
expected_activation_id?: string | null;
|
|
46
46
|
configuration_path?: string;
|
|
47
47
|
manifest_path?: string;
|
|
48
|
+
/** `app release`: reuse an existing configuration revision instead of writing configuration_path. */
|
|
49
|
+
skip_build?: boolean;
|
|
48
50
|
release_id?: string;
|
|
49
51
|
source_ref?: string;
|
|
50
52
|
source_release_id?: string;
|
|
@@ -152,3 +152,37 @@ export declare const ApplicationPromotionPlanSchema: import("typebox").TObject<{
|
|
|
152
152
|
execution_performed: import("typebox").TLiteral<false>;
|
|
153
153
|
data_recovery: import("typebox").TLiteral<"separate-required">;
|
|
154
154
|
}>;
|
|
155
|
+
export declare const ApplicationReleaseRequestSchema: import("typebox").TObject<{
|
|
156
|
+
release_id: import("typebox").TString;
|
|
157
|
+
configuration_id: import("typebox").TOptional<import("typebox").TString>;
|
|
158
|
+
configuration_write: import("typebox").TOptional<import("typebox").TObject<{
|
|
159
|
+
configuration_id: import("typebox").TString;
|
|
160
|
+
expected_configuration_id: import("typebox").TUnion<[import("typebox").TString, import("typebox").TNull]>;
|
|
161
|
+
configuration: import("typebox").TObject<{
|
|
162
|
+
bun_version: import("typebox").TString;
|
|
163
|
+
targets: import("typebox").TArray<import("typebox").TObject<{
|
|
164
|
+
name: import("typebox").TString;
|
|
165
|
+
kind: import("typebox").TUnion<[import("typebox").TLiteral<"http">, import("typebox").TLiteral<"worker">]>;
|
|
166
|
+
hosts: import("typebox").TArray<import("typebox").TString>;
|
|
167
|
+
environment: import("typebox").TRecord<"^.*$", import("typebox").TString>;
|
|
168
|
+
}>>;
|
|
169
|
+
}>;
|
|
170
|
+
}>>;
|
|
171
|
+
activation_id: import("typebox").TOptional<import("typebox").TString>;
|
|
172
|
+
expected_activation_id: import("typebox").TOptional<import("typebox").TUnion<[import("typebox").TString, import("typebox").TNull]>>;
|
|
173
|
+
expected_plan_sha256: import("typebox").TOptional<import("typebox").TString>;
|
|
174
|
+
}>;
|
|
175
|
+
export declare const ApplicationReleaseResultSchema: import("typebox").TObject<{
|
|
176
|
+
schema: import("typebox").TLiteral<"supacloud.application-release.v1">;
|
|
177
|
+
project_ref: import("typebox").TString;
|
|
178
|
+
application_id: import("typebox").TString;
|
|
179
|
+
environment_id: import("typebox").TString;
|
|
180
|
+
release_id: import("typebox").TString;
|
|
181
|
+
configuration_id: import("typebox").TString;
|
|
182
|
+
activation_id: import("typebox").TString;
|
|
183
|
+
expected_activation_id: import("typebox").TUnion<[import("typebox").TString, import("typebox").TNull]>;
|
|
184
|
+
plan_sha256: import("typebox").TString;
|
|
185
|
+
action: import("typebox").TUnion<[import("typebox").TLiteral<"activate">, import("typebox").TLiteral<"no-op">]>;
|
|
186
|
+
replayed: import("typebox").TBoolean;
|
|
187
|
+
execution_performed: import("typebox").TBoolean;
|
|
188
|
+
}>;
|
|
@@ -9,7 +9,7 @@ export declare const APPLICATION_TOOL_SCHEMA: {
|
|
|
9
9
|
ttl_seconds: Type.TOptional<Type.TInteger>;
|
|
10
10
|
wait: Type.TOptional<Type.TBoolean>;
|
|
11
11
|
timeout_seconds: Type.TOptional<Type.TInteger>;
|
|
12
|
-
action: Type.TEnum<("list_releases" | "get_release" | "upload_release" | "activate_release" | "logs" | "get_runtime" | "get_deployment_evidence" | "get_configuration" | "get_release_transfer_plan" | "get_promotion_plan" | "get_promotion_status" | "get_rollback_snapshot" | "get_history" | "get_deploy_plan" | "get_preview_plan" | "list_previews" | "get_preview" | "put_configuration" | "transfer_release" | "promote_application" | "reconcile_promotion" | "create_preview" | "reconcile_preview" | "cleanup_preview" | "deploy_release" | "rollback_release" | "reconcile_activation" | "retire_activation")[]>;
|
|
12
|
+
action: Type.TEnum<("list_releases" | "get_release" | "upload_release" | "activate_release" | "logs" | "get_runtime" | "get_deployment_evidence" | "get_configuration" | "get_release_transfer_plan" | "get_promotion_plan" | "get_promotion_status" | "get_rollback_snapshot" | "get_history" | "get_deploy_plan" | "get_preview_plan" | "list_previews" | "get_preview" | "put_configuration" | "release_application" | "transfer_release" | "promote_application" | "reconcile_promotion" | "create_preview" | "reconcile_preview" | "cleanup_preview" | "deploy_release" | "rollback_release" | "reconcile_activation" | "retire_activation")[]>;
|
|
13
13
|
ref: Type.TString;
|
|
14
14
|
id: Type.TString;
|
|
15
15
|
environment_id: Type.TOptional<Type.TString>;
|
|
@@ -17,6 +17,7 @@ export declare const APPLICATION_TOOL_SCHEMA: {
|
|
|
17
17
|
activation_id: Type.TOptional<Type.TString>;
|
|
18
18
|
expected_activation_id: Type.TOptional<Type.TUnion<[Type.TString, Type.TNull, Type.TLiteral<"absent">]>>;
|
|
19
19
|
configuration_path: Type.TOptional<Type.TString>;
|
|
20
|
+
configuration_write: Type.TOptional<Type.TUnknown>;
|
|
20
21
|
manifest_path: Type.TOptional<Type.TString>;
|
|
21
22
|
release_id: Type.TOptional<Type.TString>;
|
|
22
23
|
source_ref: Type.TOptional<Type.TString>;
|
|
@@ -5,6 +5,7 @@ interface DeployToolOptions {
|
|
|
5
5
|
projectRef?: string;
|
|
6
6
|
environment?: string | null;
|
|
7
7
|
cwd?: string;
|
|
8
|
+
environmentVariables?: Readonly<Record<string, string>>;
|
|
8
9
|
edgeFunctionDeploy?: (args: Record<string, unknown>) => Promise<ToolResponse>;
|
|
9
10
|
}
|
|
10
11
|
interface ToolResponse {
|
|
@@ -28,6 +29,11 @@ export declare const deployToolSchema: {
|
|
|
28
29
|
json: Type.TOptional<Type.TBoolean>;
|
|
29
30
|
};
|
|
30
31
|
export declare function findDeployConfigRoot(startDirectory: string): Promise<string>;
|
|
32
|
+
export declare function createBuildEnvironment(names: string[] | undefined, environmentVariables: Readonly<Record<string, string>> | undefined): {
|
|
33
|
+
env: NodeJS.ProcessEnv;
|
|
34
|
+
names: string[];
|
|
35
|
+
missing: string[];
|
|
36
|
+
};
|
|
31
37
|
export declare function createFrontendArchive(outputDirectory: string): Promise<{
|
|
32
38
|
archivePath: string;
|
|
33
39
|
sha256: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@supacloud/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.86.0",
|
|
4
4
|
"description": "Project-scoped CLI for SupaCloud users",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -53,13 +53,13 @@
|
|
|
53
53
|
},
|
|
54
54
|
"dependencies": {
|
|
55
55
|
"@supacloud/compiler": "^0.43.0",
|
|
56
|
-
"@supacloud/delivery": "0.
|
|
56
|
+
"@supacloud/delivery": "0.14.0",
|
|
57
57
|
"@supacloud/db": "0.16.0",
|
|
58
58
|
"typebox": "1.3.34"
|
|
59
59
|
},
|
|
60
60
|
"overrides": {
|
|
61
61
|
"@supacloud/contracts": "0.8.0",
|
|
62
|
-
"@supacloud/delivery": "0.
|
|
62
|
+
"@supacloud/delivery": "0.14.0",
|
|
63
63
|
"@graphql-tools/utils": "^12.0.3"
|
|
64
64
|
},
|
|
65
65
|
"devDependencies": {
|