@groundfloorcloud/cli 0.1.8 → 0.1.9
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 +18 -8
- package/dist/index.js +195 -12
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -63,8 +63,10 @@ Do not create an App just to run a function, job, schedule, or service
|
|
|
63
63
|
(Deployment). Use `gf deploy`. Bind `--app-id` only when the coderunner should
|
|
64
64
|
be a helper of an existing product App.
|
|
65
65
|
|
|
66
|
-
**
|
|
67
|
-
|
|
66
|
+
**App authentication is optional.** Team **write** can create Coderunners
|
|
67
|
+
when mode is None. For Vault and Files from the workload, attach an M2M
|
|
68
|
+
client (Administer → M2M tokens) and use `gf m2m token` — not a Dataplane
|
|
69
|
+
key. `gf coderunner vault-token` is deprecated.
|
|
68
70
|
|
|
69
71
|
### Workload types
|
|
70
72
|
|
|
@@ -104,11 +106,16 @@ port 8080). Add `"scripts": { "start": "node index.js" }` and bind
|
|
|
104
106
|
eval "$(gf env)"
|
|
105
107
|
export PORT=8080
|
|
106
108
|
npm start
|
|
109
|
+
# files/secrets / operator Vault (builder token):
|
|
107
110
|
curl -sS -H "Authorization: Bearer $(gf token)" \
|
|
111
|
+
"$CONTROLPLANE_URL/v1/workspaces/$GROUNDFLOOR_WORKSPACE_ID/files"
|
|
112
|
+
# M2M (Coderunner / CI — not gf token):
|
|
113
|
+
curl -sS -H "Authorization: Bearer $(gf m2m token)" \
|
|
108
114
|
"$CONTROLPLANE_URL/v1/workspaces/$GROUNDFLOOR_WORKSPACE_ID/vault/collections"
|
|
109
115
|
```
|
|
110
116
|
|
|
111
|
-
Then `gf deploy` the same tree. Do not zip `.env` files.
|
|
117
|
+
Then `gf deploy` the same tree. Do not zip `.env` files. `gf token` is the
|
|
118
|
+
wrong identity for testing Coderunner Vault/Files as the workload.
|
|
112
119
|
|
|
113
120
|
### `groundfloor.json`
|
|
114
121
|
|
|
@@ -132,7 +139,7 @@ Then `gf deploy` the same tree. Do not zip `.env` files.
|
|
|
132
139
|
| `-p, --path <dir>` | Directory to package (default: cwd). |
|
|
133
140
|
| `--git <url>` / `--ref <ref>` | Clone and deploy a remote repo. |
|
|
134
141
|
| `--subdir <dir>` | Package a subdirectory of the source. |
|
|
135
|
-
| `--runtime <r>` | `
|
|
142
|
+
| `--runtime <r>` | Language slug from `GET …/coderunners/languages` (`node`, `python`, `go`, `dotnet`, `dotnet-script`, …). |
|
|
136
143
|
| `--workload-type <t>` | `function` \| `service` (Deployment) \| `job` \| `schedule`. Service requires a Dockerfile. |
|
|
137
144
|
| `--schedule <cron>` | Cron for `schedule` workloads (or `groundfloor.json` `schedule`). |
|
|
138
145
|
| `--cpu` / `--memory` | Resource requests, e.g. `250m` / `256Mi`. |
|
|
@@ -163,10 +170,11 @@ gf apps publish --path release.zip
|
|
|
163
170
|
`APP_ID` / `groundfloor.manifest.json` `appId` to the slug.
|
|
164
171
|
|
|
165
172
|
`gf apps publish` uploads **only** `release.zip` from `npm run release`.
|
|
166
|
-
It flattens a Vite `dist/assets/` layout when needed,
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
173
|
+
It flattens a Vite `dist/assets/` layout when needed, rewrites `./assets/`
|
|
174
|
+
imports in `remoteEntry.js`, then **rejects** a zip that is only
|
|
175
|
+
`remoteEntry.js` (missing `__federation_*.js` / CSS) or whose federation
|
|
176
|
+
`name` does not match `federationRemoteName(slug)`. A lone `.js` file is
|
|
177
|
+
also rejected. Pass an app id/slug, or set `appId` in
|
|
170
178
|
`groundfloor.manifest.json` next to the zip.
|
|
171
179
|
|
|
172
180
|
Wrap an existing **service** coderunner as a product:
|
|
@@ -215,6 +223,8 @@ gf apps get <id|slug>
|
|
|
215
223
|
| `gf coderunner logs -c <id\|slug>` | Process Log (stdout/stderr). Also printed automatically on `gf deploy` failure. |
|
|
216
224
|
| `gf coderunner cancel-deployment -c <id\|slug>` | Delete the current (or `--deployment-id`) deployment. |
|
|
217
225
|
| `gf coderunner run -c <id\|slug> [--payload '{}']` | Invoke a deployed function or job. |
|
|
226
|
+
| `gf m2m token` | Print a short Control Plane JWT from M2M client_id + secret. Not `gf token`. |
|
|
227
|
+
| `gf coderunner vault-token` | **Deprecated.** Use `gf m2m token`. |
|
|
218
228
|
| `gf deploy` | Package code and deploy as a coderunner. |
|
|
219
229
|
| `gf domains ls\|add\|rm\|verify -c <id\|slug>` | Custom domains for a service. |
|
|
220
230
|
| `gf secrets ls\|get\|set\|rm` | Workspace secrets. |
|
package/dist/index.js
CHANGED
|
@@ -526,11 +526,31 @@ var CpError = class extends Error {
|
|
|
526
526
|
}
|
|
527
527
|
status;
|
|
528
528
|
};
|
|
529
|
+
function formatCpErrorDetail(detail, fallback) {
|
|
530
|
+
if (typeof detail === "string" && detail.trim()) return detail.trim();
|
|
531
|
+
if (detail && typeof detail === "object") {
|
|
532
|
+
const obj = detail;
|
|
533
|
+
if (typeof obj.message === "string" && obj.message.trim()) {
|
|
534
|
+
return obj.message.trim();
|
|
535
|
+
}
|
|
536
|
+
if (typeof obj.detail === "string" && obj.detail.trim()) {
|
|
537
|
+
return obj.detail.trim();
|
|
538
|
+
}
|
|
539
|
+
try {
|
|
540
|
+
return JSON.stringify(detail);
|
|
541
|
+
} catch {
|
|
542
|
+
return fallback;
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
return fallback;
|
|
546
|
+
}
|
|
529
547
|
async function parseError(res) {
|
|
530
548
|
let detail = res.statusText;
|
|
531
549
|
try {
|
|
532
550
|
const body = await res.json();
|
|
533
|
-
if (body?.detail
|
|
551
|
+
if (body?.detail !== void 0) {
|
|
552
|
+
detail = formatCpErrorDetail(body.detail, res.statusText);
|
|
553
|
+
}
|
|
534
554
|
} catch {
|
|
535
555
|
}
|
|
536
556
|
return `${res.status} ${detail}`;
|
|
@@ -640,6 +660,13 @@ async function listCoderunners(apiUrl, workspaceId) {
|
|
|
640
660
|
if (Array.isArray(data)) return data;
|
|
641
661
|
return data.coderunners ?? [];
|
|
642
662
|
}
|
|
663
|
+
async function listCoderunnerLanguages(apiUrl, workspaceId) {
|
|
664
|
+
const data = await cpGet(
|
|
665
|
+
apiUrl,
|
|
666
|
+
`/v1/workspaces/${encodeURIComponent(workspaceId)}/coderunners/languages`
|
|
667
|
+
);
|
|
668
|
+
return data.languages ?? [];
|
|
669
|
+
}
|
|
643
670
|
function createCoderunner(apiUrl, workspaceId, payload) {
|
|
644
671
|
return cpPostJson(
|
|
645
672
|
apiUrl,
|
|
@@ -915,6 +942,33 @@ function provisionDataplane(apiUrl, workspaceId) {
|
|
|
915
942
|
{}
|
|
916
943
|
);
|
|
917
944
|
}
|
|
945
|
+
async function mintM2mToken(apiUrl, workspaceId, clientId, clientSecret) {
|
|
946
|
+
const res = await fetch(
|
|
947
|
+
`${apiUrl}${wsPath(workspaceId, "/m2m/token")}`,
|
|
948
|
+
{
|
|
949
|
+
method: "POST",
|
|
950
|
+
headers: {
|
|
951
|
+
Accept: "application/json",
|
|
952
|
+
"Content-Type": "application/json"
|
|
953
|
+
},
|
|
954
|
+
body: JSON.stringify({
|
|
955
|
+
client_id: clientId,
|
|
956
|
+
client_secret: clientSecret
|
|
957
|
+
})
|
|
958
|
+
}
|
|
959
|
+
);
|
|
960
|
+
if (!res.ok) {
|
|
961
|
+
throw new CpError(res.status, await parseError(res));
|
|
962
|
+
}
|
|
963
|
+
return await res.json();
|
|
964
|
+
}
|
|
965
|
+
function mintCoderunnerVaultToken(apiUrl, workspaceId, coderunnerId) {
|
|
966
|
+
return cpPostJson(
|
|
967
|
+
apiUrl,
|
|
968
|
+
`${wsPath(workspaceId, `/coderunners/${encodeURIComponent(coderunnerId)}/vault-token`)}`,
|
|
969
|
+
{}
|
|
970
|
+
);
|
|
971
|
+
}
|
|
918
972
|
|
|
919
973
|
// src/commands/whoami.ts
|
|
920
974
|
async function whoamiCommand() {
|
|
@@ -1043,6 +1097,74 @@ async function resolveCoderunnerId(apiUrl, workspaceId, idOrSlug) {
|
|
|
1043
1097
|
return match.id;
|
|
1044
1098
|
}
|
|
1045
1099
|
|
|
1100
|
+
// src/commands/vault-token.ts
|
|
1101
|
+
async function vaultTokenCommand(opts) {
|
|
1102
|
+
const cfg = await resolveConfig({ workspaceId: opts.workspace });
|
|
1103
|
+
if (!cfg.workspaceId) {
|
|
1104
|
+
throw new Error(
|
|
1105
|
+
"No workspace selected. Run `gf workspaces use <id>` or pass --workspace <id>."
|
|
1106
|
+
);
|
|
1107
|
+
}
|
|
1108
|
+
const coderunnerId = await resolveCoderunnerId(
|
|
1109
|
+
cfg.apiUrl,
|
|
1110
|
+
cfg.workspaceId,
|
|
1111
|
+
opts.coderunner
|
|
1112
|
+
);
|
|
1113
|
+
const data = await mintCoderunnerVaultToken(
|
|
1114
|
+
cfg.apiUrl,
|
|
1115
|
+
cfg.workspaceId,
|
|
1116
|
+
coderunnerId
|
|
1117
|
+
);
|
|
1118
|
+
process.stderr.write(
|
|
1119
|
+
"gf coderunner vault-token is deprecated. Attach an M2M client and use gf m2m token.\n"
|
|
1120
|
+
);
|
|
1121
|
+
if (opts.json) {
|
|
1122
|
+
process.stdout.write(`${JSON.stringify(data, null, 2)}
|
|
1123
|
+
`);
|
|
1124
|
+
return;
|
|
1125
|
+
}
|
|
1126
|
+
process.stderr.write(
|
|
1127
|
+
`expires_in=${data.expires_in}s identity=${data.workload_identity_id}
|
|
1128
|
+
`
|
|
1129
|
+
);
|
|
1130
|
+
process.stdout.write(`${data.token}
|
|
1131
|
+
`);
|
|
1132
|
+
}
|
|
1133
|
+
|
|
1134
|
+
// src/commands/m2m-token.ts
|
|
1135
|
+
async function m2mTokenCommand(opts) {
|
|
1136
|
+
const cfg = await resolveConfig({ workspaceId: opts.workspace });
|
|
1137
|
+
if (!cfg.workspaceId) {
|
|
1138
|
+
throw new Error(
|
|
1139
|
+
"No workspace selected. Run `gf workspaces use <id>` or pass --workspace <id>."
|
|
1140
|
+
);
|
|
1141
|
+
}
|
|
1142
|
+
const clientId = opts.clientId ?? process.env.GROUNDFLOOR_M2M_CLIENT_ID ?? "";
|
|
1143
|
+
const clientSecret = opts.clientSecret ?? process.env.GROUNDFLOOR_M2M_CLIENT_SECRET ?? "";
|
|
1144
|
+
if (!clientId || !clientSecret) {
|
|
1145
|
+
throw new Error(
|
|
1146
|
+
"Set GROUNDFLOOR_M2M_CLIENT_ID and GROUNDFLOOR_M2M_CLIENT_SECRET, or pass --client-id and --client-secret."
|
|
1147
|
+
);
|
|
1148
|
+
}
|
|
1149
|
+
const data = await mintM2mToken(
|
|
1150
|
+
cfg.apiUrl,
|
|
1151
|
+
cfg.workspaceId,
|
|
1152
|
+
clientId,
|
|
1153
|
+
clientSecret
|
|
1154
|
+
);
|
|
1155
|
+
if (opts.json) {
|
|
1156
|
+
process.stdout.write(`${JSON.stringify(data, null, 2)}
|
|
1157
|
+
`);
|
|
1158
|
+
return;
|
|
1159
|
+
}
|
|
1160
|
+
process.stderr.write(
|
|
1161
|
+
`expires_in=${data.expires_in}s client=${data.m2m_client_id}
|
|
1162
|
+
`
|
|
1163
|
+
);
|
|
1164
|
+
process.stdout.write(`${data.access_token}
|
|
1165
|
+
`);
|
|
1166
|
+
}
|
|
1167
|
+
|
|
1046
1168
|
// src/commands/cancel-deployment.ts
|
|
1047
1169
|
async function cancelDeploymentCommand(opts) {
|
|
1048
1170
|
const cfg = await resolveConfig({ workspaceId: opts.workspace });
|
|
@@ -1509,7 +1631,13 @@ function formatDeployTarget(input) {
|
|
|
1509
1631
|
}
|
|
1510
1632
|
|
|
1511
1633
|
// src/commands/deploy.ts
|
|
1512
|
-
var
|
|
1634
|
+
var FALLBACK_RUNTIMES = /* @__PURE__ */ new Set([
|
|
1635
|
+
"python",
|
|
1636
|
+
"node",
|
|
1637
|
+
"go",
|
|
1638
|
+
"dotnet",
|
|
1639
|
+
"dotnet-script"
|
|
1640
|
+
]);
|
|
1513
1641
|
var WORKLOAD_TYPES = /* @__PURE__ */ new Set(["function", "service", "job", "schedule"]);
|
|
1514
1642
|
var VERSION_POLL_INTERVAL_MS = 2e3;
|
|
1515
1643
|
var VERSION_POLL_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
@@ -1580,9 +1708,17 @@ async function deployCommand(opts) {
|
|
|
1580
1708
|
log(`Packaged ${pkg.fileCount} file(s), ${sizeKb} KB`);
|
|
1581
1709
|
const detected = await detectRuntime(pkg.sourceDir);
|
|
1582
1710
|
const runtime = opts.runtime ?? manifest.runtime ?? detected ?? "python";
|
|
1583
|
-
|
|
1711
|
+
let allowedRuntimes = FALLBACK_RUNTIMES;
|
|
1712
|
+
try {
|
|
1713
|
+
const catalog = await listCoderunnerLanguages(cfg.apiUrl, ws);
|
|
1714
|
+
if (catalog.length > 0) {
|
|
1715
|
+
allowedRuntimes = new Set(catalog.map((item) => item.runtime));
|
|
1716
|
+
}
|
|
1717
|
+
} catch {
|
|
1718
|
+
}
|
|
1719
|
+
if (!allowedRuntimes.has(runtime)) {
|
|
1584
1720
|
throw new Error(
|
|
1585
|
-
`Invalid runtime "${runtime}" (expected: ${[...
|
|
1721
|
+
`Invalid runtime "${runtime}" (expected: ${[...allowedRuntimes].join(", ")}).`
|
|
1586
1722
|
);
|
|
1587
1723
|
}
|
|
1588
1724
|
const workloadType = opts.workloadType ?? manifest.workloadType ?? manifest.workload_type ?? "function";
|
|
@@ -2102,6 +2238,10 @@ import path6 from "path";
|
|
|
2102
2238
|
import AdmZip2 from "adm-zip";
|
|
2103
2239
|
var REMOTE_ENTRY = "remoteEntry.js";
|
|
2104
2240
|
var FLATTEN_SUFFIXES = [".js", ".mjs", ".cjs", ".css", ".map", ".wasm"];
|
|
2241
|
+
var IMPORT_ASSETS = /(__federation_import|import)\((['"])\.\/assets\//g;
|
|
2242
|
+
function rewriteRemoteEntryAssetPrefix(source) {
|
|
2243
|
+
return source.replace(IMPORT_ASSETS, "$1($2./");
|
|
2244
|
+
}
|
|
2105
2245
|
function normalizeZipEntryName(filename) {
|
|
2106
2246
|
return filename.replace(/\\/g, "/").replace(/^\/+/, "");
|
|
2107
2247
|
}
|
|
@@ -2172,15 +2312,31 @@ function flattenFederatedReleaseZip(bytes) {
|
|
|
2172
2312
|
}
|
|
2173
2313
|
const plan = flattenFederatedBundlePlan(rels);
|
|
2174
2314
|
const keys = Object.keys(plan);
|
|
2175
|
-
if (keys.length
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2315
|
+
if (keys.length > 0) {
|
|
2316
|
+
for (const dest of keys) {
|
|
2317
|
+
const src = plan[dest];
|
|
2318
|
+
const source = byNorm.get(src);
|
|
2319
|
+
if (!source) continue;
|
|
2320
|
+
zip.addFile(dest, source.getData());
|
|
2321
|
+
}
|
|
2181
2322
|
}
|
|
2323
|
+
rewriteRemoteEntryInZip(zip);
|
|
2182
2324
|
return zip.toBuffer();
|
|
2183
2325
|
}
|
|
2326
|
+
function rewriteRemoteEntryInZip(zip) {
|
|
2327
|
+
const names = zip.getEntries().filter((entry) => !entry.isDirectory).map((entry) => normalizeZipEntryName(entry.entryName));
|
|
2328
|
+
const entryRel = chooseRemoteEntry(names);
|
|
2329
|
+
if (!entryRel) return;
|
|
2330
|
+
const zipEntry = zip.getEntries().find((item) => {
|
|
2331
|
+
if (item.isDirectory) return false;
|
|
2332
|
+
return normalizeZipEntryName(item.entryName) === entryRel;
|
|
2333
|
+
});
|
|
2334
|
+
if (!zipEntry) return;
|
|
2335
|
+
const before = zipEntry.getData().toString("utf8");
|
|
2336
|
+
const after = rewriteRemoteEntryAssetPrefix(before);
|
|
2337
|
+
if (after === before) return;
|
|
2338
|
+
zip.updateFile(zipEntry.entryName, Buffer.from(after, "utf8"));
|
|
2339
|
+
}
|
|
2184
2340
|
function federatedReleaseZipHint(slug) {
|
|
2185
2341
|
return `Run \`npm run release\` in a kit from \`gf apps init\`, then publish that zip (do not zip Vite dist/ or upload only remoteEntry.js). ${initThenPublishHint(slug)}`;
|
|
2186
2342
|
}
|
|
@@ -2195,7 +2351,7 @@ function initThenPublishHint(slug) {
|
|
|
2195
2351
|
function extractReferencedSiblings(remoteEntrySource) {
|
|
2196
2352
|
const names = /* @__PURE__ */ new Set();
|
|
2197
2353
|
for (const match of remoteEntrySource.matchAll(
|
|
2198
|
-
/["']\.\/([^"'/]+\.(?:js|mjs|cjs|css))["']/g
|
|
2354
|
+
/["']\.\/(?:assets\/)?([^"'/]+\.(?:js|mjs|cjs|css))["']/g
|
|
2199
2355
|
)) {
|
|
2200
2356
|
if (match[1] !== REMOTE_ENTRY) names.add(match[1]);
|
|
2201
2357
|
}
|
|
@@ -2867,6 +3023,22 @@ program.command("login").description(
|
|
|
2867
3023
|
program.command("logout").description("Clear the cached session").action(() => run(() => logoutCommand()));
|
|
2868
3024
|
program.command("whoami").description("Show the current identity and verify the Control Plane session").action(() => run(() => whoamiCommand()));
|
|
2869
3025
|
program.command("token").description("Print a valid (auto-refreshed) access token to stdout").action(() => run(() => tokenCommand()));
|
|
3026
|
+
var m2m = program.command("m2m").description("Machine tokens (client_id + secret \u2192 short Control Plane JWT)");
|
|
3027
|
+
m2m.command("token").description(
|
|
3028
|
+
"Exchange GROUNDFLOOR_M2M_CLIENT_ID + SECRET for a short CP JWT (not gf token)"
|
|
3029
|
+
).option("-w, --workspace <id>", "Workspace id override").option("--client-id <id>", "M2M client_id (else GROUNDFLOOR_M2M_CLIENT_ID)").option(
|
|
3030
|
+
"--client-secret <secret>",
|
|
3031
|
+
"M2M secret (else GROUNDFLOOR_M2M_CLIENT_SECRET)"
|
|
3032
|
+
).option("--json", "Output the full token response as JSON").action(
|
|
3033
|
+
(opts) => run(
|
|
3034
|
+
() => m2mTokenCommand({
|
|
3035
|
+
workspace: opts.workspace,
|
|
3036
|
+
clientId: opts.clientId,
|
|
3037
|
+
clientSecret: opts.clientSecret,
|
|
3038
|
+
json: opts.json
|
|
3039
|
+
})
|
|
3040
|
+
)
|
|
3041
|
+
);
|
|
2870
3042
|
program.command("env").description('Print shell exports for `eval "$(gf env)"`').action(() => run(() => envCommand()));
|
|
2871
3043
|
var environments = program.command("environments").alias("envs").description("List workspace environments");
|
|
2872
3044
|
environments.command("list", { isDefault: true }).alias("ls").description("List environments in the default (or --workspace) workspace").option("-w, --workspace <id>", "Workspace id override").option("--json", "Output raw JSON").action((opts) => run(() => environmentsListCommand(opts)));
|
|
@@ -2909,6 +3081,17 @@ coderunner.command("run").description("Invoke a deployed function/job (smoke run
|
|
|
2909
3081
|
})
|
|
2910
3082
|
)
|
|
2911
3083
|
);
|
|
3084
|
+
coderunner.command("vault-token").description(
|
|
3085
|
+
"Deprecated: use gf m2m token. D-067 Data Vault JWT for a bound Coderunner"
|
|
3086
|
+
).requiredOption("-c, --coderunner <id|slug>", "Coderunner id or slug").option("-w, --workspace <id>", "Workspace id override").option("--json", "Output the full token response as JSON").action(
|
|
3087
|
+
(opts) => run(
|
|
3088
|
+
() => vaultTokenCommand({
|
|
3089
|
+
workspace: opts.workspace,
|
|
3090
|
+
coderunner: opts.coderunner,
|
|
3091
|
+
json: opts.json
|
|
3092
|
+
})
|
|
3093
|
+
)
|
|
3094
|
+
);
|
|
2912
3095
|
var domains = program.command("domains").description("Manage custom domains (CNAME) for a coderunner service");
|
|
2913
3096
|
domains.command("add <domain>").description("Add a custom domain and print the DNS records to create").requiredOption("-c, --coderunner <id|slug>", "Target coderunner id or slug").option("-w, --workspace <id>", "Workspace id override").option("--json", "Output raw JSON").action((domain, opts) => run(() => domainsAddCommand(domain, opts)));
|
|
2914
3097
|
domains.command("ls").alias("list").description("List custom domains for a coderunner service").requiredOption("-c, --coderunner <id|slug>", "Target coderunner id or slug").option("-w, --workspace <id>", "Workspace id override").option("--json", "Output raw JSON").action((opts) => run(() => domainsListCommand(opts)));
|
|
@@ -2990,7 +3173,7 @@ program.command("deploy").description(
|
|
|
2990
3173
|
).option("-w, --workspace <id>", "Workspace id override").option("--api-url <url>", "Control Plane base URL").option(
|
|
2991
3174
|
"-c, --coderunner <id>",
|
|
2992
3175
|
"Deploy into an existing coderunner id (skip find/create)"
|
|
2993
|
-
).option("-n, --name <name>", "Coderunner name (default: folder or repo name)").option("-p, --path <dir>", "Local directory to package (default: cwd)").option("--git <url>", "Clone and deploy a remote git/bitbucket repo").option("--ref <ref>", "Branch/tag/commit for --git").option("--subdir <dir>", "Subdirectory within the source to package").option("--runtime <runtime>", "
|
|
3176
|
+
).option("-n, --name <name>", "Coderunner name (default: folder or repo name)").option("-p, --path <dir>", "Local directory to package (default: cwd)").option("--git <url>", "Clone and deploy a remote git/bitbucket repo").option("--ref <ref>", "Branch/tag/commit for --git").option("--subdir <dir>", "Subdirectory within the source to package").option("--runtime <runtime>", "Language slug from Code Runner (node, python, go, \u2026)").option(
|
|
2994
3177
|
"--workload-type <type>",
|
|
2995
3178
|
"function | service | job | schedule"
|
|
2996
3179
|
).option(
|
package/package.json
CHANGED