firebase-tools 13.7.2 → 13.7.4
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/lib/api.js +10 -8
- package/lib/apphosting/app.js +92 -0
- package/lib/apphosting/config.js +76 -10
- package/lib/apphosting/constants.js +2 -2
- package/lib/apphosting/githubConnections.js +2 -2
- package/lib/apphosting/index.js +36 -27
- package/lib/apphosting/repo.js +2 -2
- package/lib/apphosting/secrets/dialogs.js +15 -14
- package/lib/apphosting/secrets/index.js +7 -1
- package/lib/commands/apphosting-backends-create.js +5 -3
- package/lib/commands/apphosting-backends-delete.js +7 -17
- package/lib/commands/apphosting-backends-get.js +8 -8
- package/lib/commands/apphosting-backends-list.js +4 -5
- package/lib/commands/apphosting-builds-create.js +32 -0
- package/lib/commands/apphosting-builds-get.js +18 -0
- package/lib/commands/apphosting-rollouts-create.js +26 -0
- package/lib/commands/apphosting-rollouts-list.js +21 -0
- package/lib/commands/apphosting-secrets-access.js +1 -1
- package/lib/commands/apphosting-secrets-grantaccess.js +7 -7
- package/lib/commands/apphosting-secrets-set.js +10 -59
- package/lib/commands/functions-secrets-set.js +1 -17
- package/lib/commands/index.js +8 -0
- package/lib/deploy/functions/runtimes/discovery/index.js +3 -3
- package/lib/deploy/functions/runtimes/{supported.js → supported/index.js} +26 -81
- package/lib/deploy/functions/runtimes/supported/types.js +74 -0
- package/lib/emulator/downloadableEmulators.js +15 -5
- package/lib/extensions/emulator/specHelper.js +3 -3
- package/lib/extensions/extensionsApi.js +2 -2
- package/lib/extensions/localHelper.js +3 -3
- package/lib/frameworks/flutter/index.js +2 -2
- package/lib/frameworks/next/index.js +3 -3
- package/lib/frameworks/next/utils.js +1 -0
- package/lib/functions/python.js +4 -3
- package/lib/gcp/apphosting.js +6 -1
- package/lib/gcp/devConnect.js +1 -1
- package/lib/init/features/hosting/github.js +4 -5
- package/lib/utils.js +17 -0
- package/package.json +3 -3
- package/templates/init/functions/typescript/_eslintrc +1 -0
|
@@ -7,30 +7,30 @@ const error_1 = require("../error");
|
|
|
7
7
|
const utils_1 = require("../utils");
|
|
8
8
|
const apphosting = require("../gcp/apphosting");
|
|
9
9
|
const apphosting_backends_list_1 = require("./apphosting-backends-list");
|
|
10
|
-
exports.command = new command_1.Command("apphosting:backends:get <
|
|
11
|
-
.description("
|
|
12
|
-
.option("-l, --location <location>", "
|
|
10
|
+
exports.command = new command_1.Command("apphosting:backends:get <backend>")
|
|
11
|
+
.description("print info about a Firebase App Hosting backend")
|
|
12
|
+
.option("-l, --location <location>", "backend location", "-")
|
|
13
13
|
.before(apphosting.ensureApiEnabled)
|
|
14
|
-
.action(async (
|
|
14
|
+
.action(async (backend, options) => {
|
|
15
15
|
const projectId = (0, projectUtils_1.needProjectId)(options);
|
|
16
16
|
const location = options.location;
|
|
17
17
|
let backendsList = [];
|
|
18
18
|
try {
|
|
19
19
|
if (location !== "-") {
|
|
20
|
-
const backendInRegion = await apphosting.getBackend(projectId, location,
|
|
20
|
+
const backendInRegion = await apphosting.getBackend(projectId, location, backend);
|
|
21
21
|
backendsList.push(backendInRegion);
|
|
22
22
|
}
|
|
23
23
|
else {
|
|
24
24
|
const resp = await apphosting.listBackends(projectId, "-");
|
|
25
25
|
const allBackends = resp.backends || [];
|
|
26
|
-
backendsList = allBackends.filter((bkd) => bkd.name.split("/").pop() ===
|
|
26
|
+
backendsList = allBackends.filter((bkd) => bkd.name.split("/").pop() === backend);
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
29
|
catch (err) {
|
|
30
|
-
throw new error_1.FirebaseError(`Failed to get backend: ${
|
|
30
|
+
throw new error_1.FirebaseError(`Failed to get backend: ${backend}. Please check the parameters you have provided.`, { original: err });
|
|
31
31
|
}
|
|
32
32
|
if (backendsList.length === 0) {
|
|
33
|
-
(0, utils_1.logWarning)(`
|
|
33
|
+
(0, utils_1.logWarning)(`Backend "${backend}" not found`);
|
|
34
34
|
return;
|
|
35
35
|
}
|
|
36
36
|
(0, apphosting_backends_list_1.printBackendsTable)(backendsList);
|
|
@@ -8,10 +8,10 @@ const logger_1 = require("../logger");
|
|
|
8
8
|
const projectUtils_1 = require("../projectUtils");
|
|
9
9
|
const apphosting = require("../gcp/apphosting");
|
|
10
10
|
const Table = require("cli-table");
|
|
11
|
-
const TABLE_HEAD = ["Backend
|
|
11
|
+
const TABLE_HEAD = ["Backend", "Repository", "URL", "Location", "Updated Date"];
|
|
12
12
|
exports.command = new command_1.Command("apphosting:backends:list")
|
|
13
|
-
.description("list
|
|
14
|
-
.option("-l, --location <location>", "
|
|
13
|
+
.description("list Firebase App Hosting backends")
|
|
14
|
+
.option("-l, --location <location>", "list backends in the specified location", "-")
|
|
15
15
|
.before(apphosting.ensureApiEnabled)
|
|
16
16
|
.action(async (options) => {
|
|
17
17
|
var _a;
|
|
@@ -39,9 +39,8 @@ function printBackendsTable(backends) {
|
|
|
39
39
|
table.push([
|
|
40
40
|
backendId,
|
|
41
41
|
(_c = (_b = (_a = backend.codebase) === null || _a === void 0 ? void 0 : _a.repository) === null || _b === void 0 ? void 0 : _b.split("/").pop()) !== null && _c !== void 0 ? _c : "",
|
|
42
|
-
backendLocation,
|
|
43
42
|
backend.uri.startsWith("https:") ? backend.uri : "https://" + backend.uri,
|
|
44
|
-
|
|
43
|
+
backendLocation,
|
|
45
44
|
(0, utils_1.datetimeString)(new Date(backend.updateTime)),
|
|
46
45
|
]);
|
|
47
46
|
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.command = void 0;
|
|
4
|
+
const apphosting = require("../gcp/apphosting");
|
|
5
|
+
const logger_1 = require("../logger");
|
|
6
|
+
const command_1 = require("../command");
|
|
7
|
+
const projectUtils_1 = require("../projectUtils");
|
|
8
|
+
exports.command = new command_1.Command("apphosting:builds:create <backendId>")
|
|
9
|
+
.description("create a build for an App Hosting backend")
|
|
10
|
+
.option("-l, --location <location>", "specify the region of the backend", "us-central1")
|
|
11
|
+
.option("-i, --id <buildId>", "id of the build (defaults to autogenerating a random id)", "")
|
|
12
|
+
.option("-b, --branch <branch>", "repository branch to deploy (defaults to 'main')", "main")
|
|
13
|
+
.before(apphosting.ensureApiEnabled)
|
|
14
|
+
.action(async (backendId, options) => {
|
|
15
|
+
var _a;
|
|
16
|
+
const projectId = (0, projectUtils_1.needProjectId)(options);
|
|
17
|
+
const location = options.location;
|
|
18
|
+
const buildId = options.buildId ||
|
|
19
|
+
(await apphosting.getNextRolloutId(projectId, location, backendId));
|
|
20
|
+
const branch = (_a = options.branch) !== null && _a !== void 0 ? _a : "main";
|
|
21
|
+
const op = await apphosting.createBuild(projectId, location, backendId, buildId, {
|
|
22
|
+
source: {
|
|
23
|
+
codebase: {
|
|
24
|
+
branch,
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
logger_1.logger.info(`Started a build for backend ${backendId} on branch ${branch}.`);
|
|
29
|
+
logger_1.logger.info("Check status by running:");
|
|
30
|
+
logger_1.logger.info(`\tfirebase apphosting:builds:get ${backendId} ${buildId} --location ${location}`);
|
|
31
|
+
return op;
|
|
32
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.command = void 0;
|
|
4
|
+
const apphosting = require("../gcp/apphosting");
|
|
5
|
+
const logger_1 = require("../logger");
|
|
6
|
+
const command_1 = require("../command");
|
|
7
|
+
const projectUtils_1 = require("../projectUtils");
|
|
8
|
+
exports.command = new command_1.Command("apphosting:builds:get <backendId> <buildId>")
|
|
9
|
+
.description("get a build for an App Hosting backend")
|
|
10
|
+
.option("-l, --location <location>", "specify the region of the backend", "us-central1")
|
|
11
|
+
.before(apphosting.ensureApiEnabled)
|
|
12
|
+
.action(async (backendId, buildId, options) => {
|
|
13
|
+
const projectId = (0, projectUtils_1.needProjectId)(options);
|
|
14
|
+
const location = options.location;
|
|
15
|
+
const build = await apphosting.getBuild(projectId, location, backendId, buildId);
|
|
16
|
+
logger_1.logger.info(JSON.stringify(build, null, 2));
|
|
17
|
+
return build;
|
|
18
|
+
});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.command = void 0;
|
|
4
|
+
const apphosting = require("../gcp/apphosting");
|
|
5
|
+
const logger_1 = require("../logger");
|
|
6
|
+
const command_1 = require("../command");
|
|
7
|
+
const projectUtils_1 = require("../projectUtils");
|
|
8
|
+
exports.command = new command_1.Command("apphosting:rollouts:create <backendId> <buildId>")
|
|
9
|
+
.description("create a rollout using a build for an App Hosting backend")
|
|
10
|
+
.option("-l, --location <location>", "specify the region of the backend", "us-central1")
|
|
11
|
+
.option("-i, --id <rolloutId>", "id of the rollout (defaults to autogenerating a random id)", "")
|
|
12
|
+
.before(apphosting.ensureApiEnabled)
|
|
13
|
+
.action(async (backendId, buildId, options) => {
|
|
14
|
+
const projectId = (0, projectUtils_1.needProjectId)(options);
|
|
15
|
+
const location = options.location;
|
|
16
|
+
const rolloutId = options.buildId ||
|
|
17
|
+
(await apphosting.getNextRolloutId(projectId, location, backendId));
|
|
18
|
+
const build = `projects/${projectId}/backends/${backendId}/builds/${buildId}`;
|
|
19
|
+
const op = await apphosting.createRollout(projectId, location, backendId, rolloutId, {
|
|
20
|
+
build,
|
|
21
|
+
});
|
|
22
|
+
logger_1.logger.info(`Started a rollout for backend ${backendId} with build ${buildId}.`);
|
|
23
|
+
logger_1.logger.info("Check status by running:");
|
|
24
|
+
logger_1.logger.info(`\tfirebase apphosting:rollouts:list --location ${location}`);
|
|
25
|
+
return op;
|
|
26
|
+
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.command = void 0;
|
|
4
|
+
const apphosting = require("../gcp/apphosting");
|
|
5
|
+
const logger_1 = require("../logger");
|
|
6
|
+
const command_1 = require("../command");
|
|
7
|
+
const projectUtils_1 = require("../projectUtils");
|
|
8
|
+
exports.command = new command_1.Command("apphosting:rollouts:list <backendId>")
|
|
9
|
+
.description("list rollouts of an App Hosting backend")
|
|
10
|
+
.option("-l, --location <location>", "region of the rollouts (defaults to listing rollouts from all regions)", "-")
|
|
11
|
+
.before(apphosting.ensureApiEnabled)
|
|
12
|
+
.action(async (backendId, options) => {
|
|
13
|
+
const projectId = (0, projectUtils_1.needProjectId)(options);
|
|
14
|
+
const location = options.location;
|
|
15
|
+
const rollouts = await apphosting.listRollouts(projectId, location, backendId);
|
|
16
|
+
if (rollouts.unreachable) {
|
|
17
|
+
logger_1.logger.error(`WARNING: the following locations were unreachable: ${rollouts.unreachable.join(", ")}`);
|
|
18
|
+
}
|
|
19
|
+
logger_1.logger.info(JSON.stringify(rollouts.rollouts, null, 2));
|
|
20
|
+
return rollouts;
|
|
21
|
+
});
|
|
@@ -8,7 +8,7 @@ const secretManager_1 = require("../gcp/secretManager");
|
|
|
8
8
|
const requireAuth_1 = require("../requireAuth");
|
|
9
9
|
const secretManager = require("../gcp/secretManager");
|
|
10
10
|
const requirePermissions_1 = require("../requirePermissions");
|
|
11
|
-
exports.command = new command_1.Command("apphosting:secrets:access <secretName
|
|
11
|
+
exports.command = new command_1.Command("apphosting:secrets:access <secretName[@version]>")
|
|
12
12
|
.description("Access secret value given secret and its version. Defaults to accessing the latest version.")
|
|
13
13
|
.before(requireAuth_1.requireAuth)
|
|
14
14
|
.before(secretManager.ensureApi)
|
|
@@ -9,10 +9,11 @@ const secretManager = require("../gcp/secretManager");
|
|
|
9
9
|
const requirePermissions_1 = require("../requirePermissions");
|
|
10
10
|
const apphosting = require("../gcp/apphosting");
|
|
11
11
|
const secrets = require("../apphosting/secrets");
|
|
12
|
+
const apphosting_1 = require("../apphosting");
|
|
12
13
|
exports.command = new command_1.Command("apphosting:secrets:grantaccess <secretName>")
|
|
13
14
|
.description("grant service accounts permissions to the provided secret")
|
|
14
|
-
.option("-l, --location <location>", "
|
|
15
|
-
.option("-b, --backend <backend>", "
|
|
15
|
+
.option("-l, --location <location>", "backend location")
|
|
16
|
+
.option("-b, --backend <backend>", "backend name")
|
|
16
17
|
.before(requireAuth_1.requireAuth)
|
|
17
18
|
.before(secretManager.ensureApi)
|
|
18
19
|
.before(apphosting.ensureApiEnabled)
|
|
@@ -27,13 +28,12 @@ exports.command = new command_1.Command("apphosting:secrets:grantaccess <secretN
|
|
|
27
28
|
.action(async (secretName, options) => {
|
|
28
29
|
const projectId = (0, projectUtils_1.needProjectId)(options);
|
|
29
30
|
const projectNumber = await (0, projectUtils_1.needProjectNumber)(options);
|
|
30
|
-
if (!options.location) {
|
|
31
|
-
throw new error_1.FirebaseError("Missing required flag --location. See firebase apphosting:secrets:grantaccess --help for more info");
|
|
32
|
-
}
|
|
33
|
-
const location = options.location;
|
|
34
31
|
if (!options.backend) {
|
|
35
32
|
throw new error_1.FirebaseError("Missing required flag --backend. See firebase apphosting:secrets:grantaccess --help for more info");
|
|
36
33
|
}
|
|
34
|
+
let location = options.location;
|
|
35
|
+
location =
|
|
36
|
+
location || (await (0, apphosting_1.promptLocation)(projectId, "Please select the location of your backend"));
|
|
37
37
|
const exists = await secretManager.secretExists(projectId, secretName);
|
|
38
38
|
if (!exists) {
|
|
39
39
|
throw new error_1.FirebaseError(`Cannot find secret ${secretName}`);
|
|
@@ -41,5 +41,5 @@ exports.command = new command_1.Command("apphosting:secrets:grantaccess <secretN
|
|
|
41
41
|
const backendId = options.backend;
|
|
42
42
|
const backend = await apphosting.getBackend(projectId, location, backendId);
|
|
43
43
|
const accounts = secrets.toMulti(secrets.serviceAccountsForBackend(projectNumber, backend));
|
|
44
|
-
await secrets.grantSecretAccess(projectId, secretName, accounts);
|
|
44
|
+
await secrets.grantSecretAccess(projectId, projectNumber, secretName, accounts);
|
|
45
45
|
});
|
|
@@ -1,23 +1,19 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.command = void 0;
|
|
4
|
-
const tty = require("tty");
|
|
5
4
|
const clc = require("colorette");
|
|
6
|
-
const path_1 = require("path");
|
|
7
5
|
const command_1 = require("../command");
|
|
8
6
|
const projectUtils_1 = require("../projectUtils");
|
|
9
7
|
const requireAuth_1 = require("../requireAuth");
|
|
10
|
-
const fs = require("fs");
|
|
11
8
|
const gcsm = require("../gcp/secretManager");
|
|
12
9
|
const apphosting = require("../gcp/apphosting");
|
|
13
10
|
const requirePermissions_1 = require("../requirePermissions");
|
|
14
|
-
const prompt_1 = require("../prompt");
|
|
15
11
|
const secrets = require("../apphosting/secrets");
|
|
16
12
|
const dialogs = require("../apphosting/secrets/dialogs");
|
|
17
13
|
const config = require("../apphosting/config");
|
|
18
|
-
const
|
|
14
|
+
const utils = require("../utils");
|
|
19
15
|
exports.command = new command_1.Command("apphosting:secrets:set <secretName>")
|
|
20
|
-
.description("
|
|
16
|
+
.description("create or update a secret for use in Firebase App Hosting")
|
|
21
17
|
.option("-l, --location <location>", "optional location to retrict secret replication")
|
|
22
18
|
.withForce("Automatically create a secret, grant permissions, and add to YAML.")
|
|
23
19
|
.before(requireAuth_1.requireAuth)
|
|
@@ -33,73 +29,28 @@ exports.command = new command_1.Command("apphosting:secrets:set <secretName>")
|
|
|
33
29
|
])
|
|
34
30
|
.option("--data-file <dataFile>", 'File path from which to read secret data. Set to "-" to read the secret data from stdin.')
|
|
35
31
|
.action(async (secretName, options) => {
|
|
36
|
-
var _a;
|
|
37
|
-
const howToAccess = `You can access the contents of the secret's latest value with ${clc.bold(`firebase apphosting:secrets:access ${secretName}`)}`;
|
|
38
|
-
const grantAccess = `To use this secret in your backend, you must grant access. You can do so in the future with ${clc.bold("firebase apphosting:secrets:grantAccess")}`;
|
|
39
32
|
const projectId = (0, projectUtils_1.needProjectId)(options);
|
|
40
33
|
const projectNumber = await (0, projectUtils_1.needProjectNumber)(options);
|
|
41
34
|
const created = await secrets.upsertSecret(projectId, secretName, options.location);
|
|
42
35
|
if (created === null) {
|
|
43
36
|
return;
|
|
44
37
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
secretValue = await (0, prompt_1.promptOnce)({
|
|
48
|
-
type: "password",
|
|
49
|
-
message: `Enter a value for ${secretName}`,
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
else {
|
|
53
|
-
let dataFile = 0;
|
|
54
|
-
if (options.dataFile && options.dataFile !== "-") {
|
|
55
|
-
dataFile = options.dataFile;
|
|
56
|
-
}
|
|
57
|
-
secretValue = fs.readFileSync(dataFile, "utf-8");
|
|
58
|
-
}
|
|
59
|
-
if (created) {
|
|
60
|
-
(0, utils_1.logSuccess)(`Created new secret projects/${projectId}/secrets/${secretName}`);
|
|
38
|
+
else if (created) {
|
|
39
|
+
utils.logSuccess(`Created new secret projects/${projectId}/secrets/${secretName}`);
|
|
61
40
|
}
|
|
41
|
+
const secretValue = await utils.readSecretValue(`Enter a value for ${secretName}`, options.dataFile);
|
|
62
42
|
const version = await gcsm.addVersion(projectId, secretName, secretValue);
|
|
63
|
-
|
|
64
|
-
(
|
|
43
|
+
utils.logSuccess(`Created new secret version ${gcsm.toSecretVersionResourceName(version)}`);
|
|
44
|
+
utils.logBullet(`You can access the contents of the secret's latest value with ${clc.bold(`firebase apphosting:secrets:access ${secretName}\n`)}`);
|
|
65
45
|
if (!created) {
|
|
66
|
-
(0, utils_1.logWarning)(grantAccess);
|
|
67
46
|
return;
|
|
68
47
|
}
|
|
69
48
|
const accounts = await dialogs.selectBackendServiceAccounts(projectNumber, projectId, options);
|
|
70
49
|
if (!accounts.buildServiceAccounts.length && !accounts.runServiceAccounts.length) {
|
|
71
|
-
(
|
|
50
|
+
utils.logWarning(`To use this secret in your backend, you must grant access. You can do so in the future with ${clc.bold("firebase apphosting:secrets:grantaccess")}`);
|
|
72
51
|
}
|
|
73
52
|
else {
|
|
74
|
-
await secrets.grantSecretAccess(projectId, secretName, accounts);
|
|
75
|
-
}
|
|
76
|
-
let path = config.yamlPath(process.cwd());
|
|
77
|
-
let yaml = {};
|
|
78
|
-
if (path) {
|
|
79
|
-
yaml = config.load(path);
|
|
80
|
-
if ((_a = yaml.env) === null || _a === void 0 ? void 0 : _a.find((env) => env.variable === secretName)) {
|
|
81
|
-
return;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
const addToYaml = await (0, prompt_1.confirm)({
|
|
85
|
-
message: "Would you like to add this secret to apphosting.yaml?",
|
|
86
|
-
default: true,
|
|
87
|
-
});
|
|
88
|
-
if (!addToYaml) {
|
|
89
|
-
return;
|
|
90
|
-
}
|
|
91
|
-
if (!path) {
|
|
92
|
-
path = await (0, prompt_1.promptOnce)({
|
|
93
|
-
message: "It looks like you don't have an apphosting.yaml yet. Where would you like to store it?",
|
|
94
|
-
default: process.cwd(),
|
|
95
|
-
});
|
|
96
|
-
path = (0, path_1.join)(path, "apphosting.yaml");
|
|
53
|
+
await secrets.grantSecretAccess(projectId, projectNumber, secretName, accounts);
|
|
97
54
|
}
|
|
98
|
-
|
|
99
|
-
yaml.env = yaml.env || [];
|
|
100
|
-
yaml.env.push({
|
|
101
|
-
variable: envName,
|
|
102
|
-
secret: secretName,
|
|
103
|
-
});
|
|
104
|
-
config.store(path, yaml);
|
|
55
|
+
await config.maybeAddSecretToYaml(secretName);
|
|
105
56
|
});
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.command = void 0;
|
|
4
|
-
const tty = require("tty");
|
|
5
|
-
const fs = require("fs");
|
|
6
4
|
const clc = require("colorette");
|
|
7
5
|
const logger_1 = require("../logger");
|
|
8
6
|
const secrets_1 = require("../functions/secrets");
|
|
@@ -33,21 +31,7 @@ exports.command = new command_1.Command("functions:secrets:set <KEY>")
|
|
|
33
31
|
const projectNumber = await (0, projectUtils_1.needProjectNumber)(options);
|
|
34
32
|
const key = await (0, secrets_1.ensureValidKey)(unvalidatedKey, options);
|
|
35
33
|
const secret = await (0, secrets_1.ensureSecret)(projectId, key, options);
|
|
36
|
-
|
|
37
|
-
if ((!options.dataFile || options.dataFile === "-") && tty.isatty(0)) {
|
|
38
|
-
secretValue = await (0, prompt_1.promptOnce)({
|
|
39
|
-
name: key,
|
|
40
|
-
type: "password",
|
|
41
|
-
message: `Enter a value for ${key}`,
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
else {
|
|
45
|
-
let dataFile = 0;
|
|
46
|
-
if (options.dataFile && options.dataFile !== "-") {
|
|
47
|
-
dataFile = options.dataFile;
|
|
48
|
-
}
|
|
49
|
-
secretValue = fs.readFileSync(dataFile, "utf-8");
|
|
50
|
-
}
|
|
34
|
+
const secretValue = await (0, utils_1.readSecretValue)(`Enter a value for ${key}`, options.dataFile);
|
|
51
35
|
const secretVersion = await (0, secretManager_1.addVersion)(projectId, key, secretValue);
|
|
52
36
|
(0, utils_1.logSuccess)(`Created a new secret version ${(0, secretManager_1.toSecretVersionResourceName)(secretVersion)}`);
|
|
53
37
|
if (!(0, secretManager_1.isFunctionsManaged)(secret)) {
|
package/lib/commands/index.js
CHANGED
|
@@ -167,6 +167,14 @@ function load(client) {
|
|
|
167
167
|
client.apphosting.secrets.grantaccess = loadCommand("apphosting-secrets-grantaccess");
|
|
168
168
|
client.apphosting.secrets.describe = loadCommand("apphosting-secrets-describe");
|
|
169
169
|
client.apphosting.secrets.access = loadCommand("apphosting-secrets-access");
|
|
170
|
+
if (experiments.isEnabled("internaltesting")) {
|
|
171
|
+
client.apphosting.builds = {};
|
|
172
|
+
client.apphosting.builds.get = loadCommand("apphosting-builds-get");
|
|
173
|
+
client.apphosting.builds.create = loadCommand("apphosting-builds-create");
|
|
174
|
+
client.apphosting.rollouts = {};
|
|
175
|
+
client.apphosting.rollouts.create = loadCommand("apphosting-rollouts-create");
|
|
176
|
+
client.apphosting.rollouts.list = loadCommand("apphosting-rollouts-list");
|
|
177
|
+
}
|
|
170
178
|
}
|
|
171
179
|
client.login = loadCommand("login");
|
|
172
180
|
client.login.add = loadCommand("login-add");
|
|
@@ -4,7 +4,7 @@ exports.detectFromPort = exports.detectFromYaml = exports.yamlToBuild = exports.
|
|
|
4
4
|
const node_fetch_1 = require("node-fetch");
|
|
5
5
|
const fs = require("fs");
|
|
6
6
|
const path = require("path");
|
|
7
|
-
const yaml = require("
|
|
7
|
+
const yaml = require("yaml");
|
|
8
8
|
const util_1 = require("util");
|
|
9
9
|
const logger_1 = require("../../../../logger");
|
|
10
10
|
const api = require("../../.../../../../api");
|
|
@@ -41,7 +41,7 @@ async function detectFromYaml(directory, project, runtime) {
|
|
|
41
41
|
return;
|
|
42
42
|
}
|
|
43
43
|
logger_1.logger.debug("Found functions.yaml. Got spec:", text);
|
|
44
|
-
const parsed = yaml.
|
|
44
|
+
const parsed = yaml.parse(text);
|
|
45
45
|
return yamlToBuild(parsed, project, api.functionsDefaultRegion(), runtime);
|
|
46
46
|
}
|
|
47
47
|
exports.detectFromYaml = detectFromYaml;
|
|
@@ -74,7 +74,7 @@ async function detectFromPort(port, project, runtime, timeout = 10000) {
|
|
|
74
74
|
logger_1.logger.debug("Got response from /__/functions.yaml", text);
|
|
75
75
|
let parsed;
|
|
76
76
|
try {
|
|
77
|
-
parsed = yaml.
|
|
77
|
+
parsed = yaml.parse(text);
|
|
78
78
|
}
|
|
79
79
|
catch (err) {
|
|
80
80
|
logger_1.logger.debug("Failed to parse functions.yaml", err);
|
|
@@ -1,88 +1,33 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
2
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.guardVersionSupport = exports.isDecommissioned = exports.latest = exports.runtimeIsLanguage = exports.isRuntime =
|
|
4
|
-
const error_1 = require("
|
|
5
|
-
const utils = require("
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
}
|
|
9
|
-
exports.RUNTIMES = runtimes({
|
|
10
|
-
nodejs6: {
|
|
11
|
-
friendly: "Node.js 6",
|
|
12
|
-
status: "decommissioned",
|
|
13
|
-
deprecationDate: "2019-04-17",
|
|
14
|
-
decommissionDate: "2020-08-01",
|
|
15
|
-
},
|
|
16
|
-
nodejs8: {
|
|
17
|
-
friendly: "Node.js 8",
|
|
18
|
-
status: "decommissioned",
|
|
19
|
-
deprecationDate: "2020-06-05",
|
|
20
|
-
decommissionDate: "2021-02-01",
|
|
21
|
-
},
|
|
22
|
-
nodejs10: {
|
|
23
|
-
friendly: "Node.js 10",
|
|
24
|
-
status: "GA",
|
|
25
|
-
deprecationDate: "2024-01-30",
|
|
26
|
-
decommissionDate: "2025-01-30",
|
|
27
|
-
},
|
|
28
|
-
nodejs12: {
|
|
29
|
-
friendly: "Node.js 12",
|
|
30
|
-
status: "GA",
|
|
31
|
-
deprecationDate: "2024-01-30",
|
|
32
|
-
decommissionDate: "2025-01-30",
|
|
33
|
-
},
|
|
34
|
-
nodejs14: {
|
|
35
|
-
friendly: "Node.js 14",
|
|
36
|
-
status: "GA",
|
|
37
|
-
deprecationDate: "2024-01-30",
|
|
38
|
-
decommissionDate: "2025-01-30",
|
|
39
|
-
},
|
|
40
|
-
nodejs16: {
|
|
41
|
-
friendly: "Node.js 16",
|
|
42
|
-
status: "GA",
|
|
43
|
-
deprecationDate: "2024-01-30",
|
|
44
|
-
decommissionDate: "2025-01-30",
|
|
45
|
-
},
|
|
46
|
-
nodejs18: {
|
|
47
|
-
friendly: "Node.js 18",
|
|
48
|
-
status: "GA",
|
|
49
|
-
deprecationDate: "2025-04-30",
|
|
50
|
-
decommissionDate: "2025-10-31",
|
|
51
|
-
},
|
|
52
|
-
nodejs20: {
|
|
53
|
-
friendly: "Node.js 20",
|
|
54
|
-
status: "GA",
|
|
55
|
-
deprecationDate: "2026-04-30",
|
|
56
|
-
decommissionDate: "2026-10-31",
|
|
57
|
-
},
|
|
58
|
-
python310: {
|
|
59
|
-
friendly: "Python 3.10",
|
|
60
|
-
status: "GA",
|
|
61
|
-
deprecationDate: "2026-10-04",
|
|
62
|
-
decommissionDate: "2027-04-30",
|
|
63
|
-
},
|
|
64
|
-
python311: {
|
|
65
|
-
friendly: "Python 3.11",
|
|
66
|
-
status: "GA",
|
|
67
|
-
deprecationDate: "2027-10-24",
|
|
68
|
-
decommissionDate: "2028-04-30",
|
|
69
|
-
},
|
|
70
|
-
python312: {
|
|
71
|
-
friendly: "Python 3.12",
|
|
72
|
-
status: "GA",
|
|
73
|
-
deprecationDate: "2028-10-02",
|
|
74
|
-
decommissionDate: "2029-04-30",
|
|
75
|
-
},
|
|
76
|
-
});
|
|
17
|
+
exports.guardVersionSupport = exports.isDecommissioned = exports.latest = exports.runtimeIsLanguage = exports.isRuntime = void 0;
|
|
18
|
+
const error_1 = require("../../../../error");
|
|
19
|
+
const utils = require("../../../../utils");
|
|
20
|
+
const types_1 = require("./types");
|
|
21
|
+
__exportStar(require("./types"), exports);
|
|
77
22
|
function isRuntime(maybe) {
|
|
78
|
-
return maybe in
|
|
23
|
+
return maybe in types_1.RUNTIMES;
|
|
79
24
|
}
|
|
80
25
|
exports.isRuntime = isRuntime;
|
|
81
26
|
function runtimeIsLanguage(runtime, language) {
|
|
82
27
|
return runtime.startsWith(language);
|
|
83
28
|
}
|
|
84
29
|
exports.runtimeIsLanguage = runtimeIsLanguage;
|
|
85
|
-
function latest(language, runtimes = Object.keys(
|
|
30
|
+
function latest(language, runtimes = Object.keys(types_1.RUNTIMES)) {
|
|
86
31
|
const sorted = runtimes
|
|
87
32
|
.filter((s) => runtimeIsLanguage(s, language))
|
|
88
33
|
.sort((left, right) => {
|
|
@@ -103,20 +48,20 @@ function latest(language, runtimes = Object.keys(exports.RUNTIMES)) {
|
|
|
103
48
|
}
|
|
104
49
|
exports.latest = latest;
|
|
105
50
|
function isDecommissioned(runtime, now = new Date()) {
|
|
106
|
-
const cutoff = new Date(
|
|
51
|
+
const cutoff = new Date(types_1.RUNTIMES[runtime].decommissionDate);
|
|
107
52
|
return cutoff < now;
|
|
108
53
|
}
|
|
109
54
|
exports.isDecommissioned = isDecommissioned;
|
|
110
55
|
function guardVersionSupport(runtime, now = new Date()) {
|
|
111
|
-
const { deprecationDate, decommissionDate } =
|
|
56
|
+
const { deprecationDate, decommissionDate } = types_1.RUNTIMES[runtime];
|
|
112
57
|
const decommission = new Date(decommissionDate);
|
|
113
58
|
if (now >= decommission) {
|
|
114
|
-
throw new error_1.FirebaseError(`Runtime ${
|
|
59
|
+
throw new error_1.FirebaseError(`Runtime ${types_1.RUNTIMES[runtime].friendly} was decommissioned on ${decommissionDate}. To deploy ` +
|
|
115
60
|
"you must first upgrade your runtime version.", { exit: 1 });
|
|
116
61
|
}
|
|
117
62
|
const deprecation = new Date(deprecationDate);
|
|
118
63
|
if (now >= deprecation) {
|
|
119
|
-
utils.logLabeledWarning("functions", `Runtime ${
|
|
64
|
+
utils.logLabeledWarning("functions", `Runtime ${types_1.RUNTIMES[runtime].friendly} was deprecated on ${deprecationDate} and will be ` +
|
|
120
65
|
`decommissioned on ${decommissionDate}, after which you will not be able ` +
|
|
121
66
|
"to deploy without upgrading. Consider upgrading now to avoid disruption. See " +
|
|
122
67
|
"https://cloud.google.com/functions/docs/runtime-support for full " +
|
|
@@ -125,7 +70,7 @@ function guardVersionSupport(runtime, now = new Date()) {
|
|
|
125
70
|
}
|
|
126
71
|
const warning = new Date(deprecation.getTime() - 90 * 24 * 60 * 60 * 1000);
|
|
127
72
|
if (now >= warning) {
|
|
128
|
-
utils.logLabeledWarning("functions", `Runtime ${
|
|
73
|
+
utils.logLabeledWarning("functions", `Runtime ${types_1.RUNTIMES[runtime].friendly} will be deprecated on ${deprecationDate} and will be ` +
|
|
129
74
|
`decommissioned on ${decommissionDate}, after which you will not be able ` +
|
|
130
75
|
"to deploy without upgrading. Consider upgrading now to avoid disruption. See " +
|
|
131
76
|
"https://cloud.google.com/functions/docs/runtime-support for full " +
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RUNTIMES = void 0;
|
|
4
|
+
function runtimes(r) {
|
|
5
|
+
return r;
|
|
6
|
+
}
|
|
7
|
+
exports.RUNTIMES = runtimes({
|
|
8
|
+
nodejs6: {
|
|
9
|
+
friendly: "Node.js 6",
|
|
10
|
+
status: "decommissioned",
|
|
11
|
+
deprecationDate: "2019-04-17",
|
|
12
|
+
decommissionDate: "2020-08-01",
|
|
13
|
+
},
|
|
14
|
+
nodejs8: {
|
|
15
|
+
friendly: "Node.js 8",
|
|
16
|
+
status: "decommissioned",
|
|
17
|
+
deprecationDate: "2020-06-05",
|
|
18
|
+
decommissionDate: "2021-02-01",
|
|
19
|
+
},
|
|
20
|
+
nodejs10: {
|
|
21
|
+
friendly: "Node.js 10",
|
|
22
|
+
status: "GA",
|
|
23
|
+
deprecationDate: "2024-01-30",
|
|
24
|
+
decommissionDate: "2025-01-30",
|
|
25
|
+
},
|
|
26
|
+
nodejs12: {
|
|
27
|
+
friendly: "Node.js 12",
|
|
28
|
+
status: "GA",
|
|
29
|
+
deprecationDate: "2024-01-30",
|
|
30
|
+
decommissionDate: "2025-01-30",
|
|
31
|
+
},
|
|
32
|
+
nodejs14: {
|
|
33
|
+
friendly: "Node.js 14",
|
|
34
|
+
status: "GA",
|
|
35
|
+
deprecationDate: "2024-01-30",
|
|
36
|
+
decommissionDate: "2025-01-30",
|
|
37
|
+
},
|
|
38
|
+
nodejs16: {
|
|
39
|
+
friendly: "Node.js 16",
|
|
40
|
+
status: "GA",
|
|
41
|
+
deprecationDate: "2024-01-30",
|
|
42
|
+
decommissionDate: "2025-01-30",
|
|
43
|
+
},
|
|
44
|
+
nodejs18: {
|
|
45
|
+
friendly: "Node.js 18",
|
|
46
|
+
status: "GA",
|
|
47
|
+
deprecationDate: "2025-04-30",
|
|
48
|
+
decommissionDate: "2025-10-31",
|
|
49
|
+
},
|
|
50
|
+
nodejs20: {
|
|
51
|
+
friendly: "Node.js 20",
|
|
52
|
+
status: "GA",
|
|
53
|
+
deprecationDate: "2026-04-30",
|
|
54
|
+
decommissionDate: "2026-10-31",
|
|
55
|
+
},
|
|
56
|
+
python310: {
|
|
57
|
+
friendly: "Python 3.10",
|
|
58
|
+
status: "GA",
|
|
59
|
+
deprecationDate: "2026-10-04",
|
|
60
|
+
decommissionDate: "2027-04-30",
|
|
61
|
+
},
|
|
62
|
+
python311: {
|
|
63
|
+
friendly: "Python 3.11",
|
|
64
|
+
status: "GA",
|
|
65
|
+
deprecationDate: "2027-10-24",
|
|
66
|
+
decommissionDate: "2028-04-30",
|
|
67
|
+
},
|
|
68
|
+
python312: {
|
|
69
|
+
friendly: "Python 3.12",
|
|
70
|
+
status: "GA",
|
|
71
|
+
deprecationDate: "2028-10-02",
|
|
72
|
+
decommissionDate: "2029-04-30",
|
|
73
|
+
},
|
|
74
|
+
});
|