@naturalcycles/backend-lib 9.79.0 → 9.80.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.
Files changed (46) hide show
  1. package/dist/deploy/deployHealthCheck.d.ts +1 -5
  2. package/dist/deploy/deployHealthCheck.js +3 -34
  3. package/dist/deploy/index.d.ts +2 -9
  4. package/dist/deploy/index.js +1 -6
  5. package/dist/express/createDefaultApp.js +2 -2
  6. package/dist/server/serverStatusMiddleware.d.ts +2 -2
  7. package/dist/server/serverStatusMiddleware.js +5 -14
  8. package/dist/util.d.ts +0 -1
  9. package/dist/util.js +1 -4
  10. package/package.json +3 -13
  11. package/src/deploy/deployHealthCheck.ts +2 -48
  12. package/src/deploy/index.ts +2 -17
  13. package/src/express/createDefaultApp.ts +2 -2
  14. package/src/server/serverStatusMiddleware.ts +4 -20
  15. package/src/util.ts +1 -5
  16. package/bin/deploy-gae.js +0 -2
  17. package/bin/deploy-prepare.js +0 -2
  18. package/bin/undeploy-gae.js +0 -2
  19. package/dist/bin/deploy-gae.d.ts +0 -1
  20. package/dist/bin/deploy-gae.js +0 -12
  21. package/dist/bin/deploy-prepare.d.ts +0 -1
  22. package/dist/bin/deploy-prepare.js +0 -19
  23. package/dist/bin/undeploy-gae.d.ts +0 -1
  24. package/dist/bin/undeploy-gae.js +0 -13
  25. package/dist/deploy/backend.cfg.util.d.ts +0 -30
  26. package/dist/deploy/backend.cfg.util.js +0 -23
  27. package/dist/deploy/deploy.model.d.ts +0 -29
  28. package/dist/deploy/deploy.model.js +0 -1
  29. package/dist/deploy/deploy.util.d.ts +0 -7
  30. package/dist/deploy/deploy.util.js +0 -151
  31. package/dist/deploy/deployGae.d.ts +0 -10
  32. package/dist/deploy/deployGae.js +0 -90
  33. package/dist/deploy/deployInfo.util.d.ts +0 -1
  34. package/dist/deploy/deployInfo.util.js +0 -25
  35. package/dist/deploy/deployPrepare.d.ts +0 -13
  36. package/dist/deploy/deployPrepare.js +0 -85
  37. package/src/bin/deploy-gae.ts +0 -14
  38. package/src/bin/deploy-prepare.ts +0 -24
  39. package/src/bin/undeploy-gae.ts +0 -15
  40. package/src/deploy/backend.cfg.util.ts +0 -63
  41. package/src/deploy/deploy.model.ts +0 -32
  42. package/src/deploy/deploy.util.ts +0 -214
  43. package/src/deploy/deployGae.ts +0 -127
  44. package/src/deploy/deployInfo.util.ts +0 -27
  45. package/src/deploy/deployPrepare.ts +0 -113
  46. package/src/deploy/files-default/.gcloudignore +0 -7
@@ -1,151 +0,0 @@
1
- import { localTime } from '@naturalcycles/js-lib/datetime/localTime.js';
2
- import { _assert } from '@naturalcycles/js-lib/error/assert.js';
3
- import { _mapValues, _merge } from '@naturalcycles/js-lib/object/object.util.js';
4
- import { _truncate } from '@naturalcycles/js-lib/string/string.util.js';
5
- import { sha256 } from '@naturalcycles/nodejs-lib';
6
- import { dimGrey, white } from '@naturalcycles/nodejs-lib/colors';
7
- import { fs2 } from '@naturalcycles/nodejs-lib/fs2';
8
- import { yaml2 } from '@naturalcycles/nodejs-lib/yaml2';
9
- const APP_YAML_DEFAULT = () => ({
10
- runtime: 'nodejs22',
11
- service: 'default',
12
- inbound_services: ['warmup'],
13
- instance_class: 'F1',
14
- automatic_scaling: {
15
- min_instances: 0,
16
- max_instances: 1,
17
- },
18
- env_variables: {
19
- APP_ENV: 'prod',
20
- DEBUG: 'app*,nc:*',
21
- DEBUG_HIDE_DATE: 'true',
22
- // DEBUG_COLORS: 'true',
23
- TZ: 'UTC',
24
- },
25
- });
26
- export async function createAndSaveDeployInfo(backendCfg, targetDir) {
27
- const deployInfo = await createDeployInfo(backendCfg);
28
- const deployInfoPath = `${targetDir}/deployInfo.json`;
29
- fs2.writeJson(deployInfoPath, deployInfo, { spaces: 2 });
30
- console.log(`saved ${dimGrey(deployInfoPath)}`);
31
- return deployInfo;
32
- }
33
- export async function createDeployInfo(backendCfg, overrideBranch) {
34
- const { simpleGit } = await import('simple-git'); // lazy load
35
- const git = simpleGit('.');
36
- const now = localTime.now();
37
- const gitBranch = overrideBranch || (await git.status()).current;
38
- const gitRev = (await git.revparse(['HEAD'])).slice(0, 7);
39
- let { gaeProject, gaeProjectByBranch = {}, gaeService, gaeServiceByBranch = {}, branchesWithTimestampVersions = [], } = backendCfg;
40
- gaeProject = gaeProjectByBranch[gitBranch] || gaeProject;
41
- if (gaeServiceByBranch[gitBranch]) {
42
- gaeService = validateGAEServiceName(gaeServiceByBranch[gitBranch]);
43
- }
44
- else {
45
- let branchName = gitBranch;
46
- if (backendCfg.hashedBranches) {
47
- // Obfuscates the branch name by hashing it.
48
- // If there are Jira issue names in the branch name, the first one found will be used as a prefix.
49
- const jiraIssue = gitBranch.match(/([Dd][Ee][Vv]-\d+)/)?.[0];
50
- const branchHash = sha256(gitBranch).slice(0, 10);
51
- branchName = [jiraIssue, branchHash].filter(Boolean).join('-');
52
- }
53
- gaeService = validateGAEServiceName([branchName, gaeService].join('--'));
54
- }
55
- let gaeVersion = '1';
56
- if (branchesWithTimestampVersions.includes(gitBranch)) {
57
- // May only contain lowercase letters, digits, and hyphens. Must begin and end with a letter or digit. Must not exceed 63 characters.
58
- gaeVersion = [
59
- // now.format('YYYYMMDD-HHmm'), // 20190521-1721
60
- now.toStringCompact().replace('_', '-'),
61
- gitRev,
62
- ].join('-');
63
- }
64
- const versionUrl = `https://${[gaeVersion, gaeService, gaeProject].join('-dot-')}.appspot.com`;
65
- // Check the 63-char limit
66
- const versionUrlString = [gaeVersion, gaeService, gaeProject].join('-dot-');
67
- _assert(versionUrlString.length <= 63, `versionUrl length should be <= 63 characters, but it's ${versionUrlString.length} instead: ${versionUrlString}`);
68
- const serviceUrl = `https://${[gaeService, gaeProject].join('-dot-')}.appspot.com`;
69
- const deployInfo = {
70
- gaeProject,
71
- gaeService,
72
- gaeVersion,
73
- versionUrl,
74
- serviceUrl,
75
- gitBranch,
76
- gitRev,
77
- ts: now.unix,
78
- };
79
- console.log({ deployInfo });
80
- return deployInfo;
81
- }
82
- export function createAndSaveAppYaml(backendCfg, deployInfo, projectDir, targetDir, appYamlPassEnv = '') {
83
- const appYaml = createAppYaml(backendCfg, deployInfo, projectDir, appYamlPassEnv);
84
- const appYamlPath = `${targetDir}/app.yaml`;
85
- yaml2.writeYaml(appYamlPath, appYaml);
86
- console.log(`saved ${dimGrey(appYamlPath)}`);
87
- return appYaml;
88
- }
89
- export function createAppYaml(backendCfg, deployInfo, projectDir, appYamlPassEnv = '') {
90
- const { appEnvDefault, appEnvByBranch = {} } = backendCfg;
91
- const { gaeService: service, gitBranch } = deployInfo;
92
- const { APP_ENV: processAppEnv } = process.env;
93
- const APP_ENV = processAppEnv || appEnvByBranch[gitBranch] || appEnvDefault;
94
- if (processAppEnv) {
95
- console.log(`using APP_ENV=${dimGrey(processAppEnv)} from process.env`);
96
- }
97
- const appYaml = APP_YAML_DEFAULT();
98
- // Check existing app.yaml
99
- const appYamlPath = `${projectDir}/app.yaml`;
100
- if (fs2.pathExists(appYamlPath)) {
101
- console.log(`merging-in ${dimGrey(appYamlPath)}`);
102
- _merge(appYaml, yaml2.readYaml(appYamlPath));
103
- }
104
- const appEnvYamlPath = `${projectDir}/app.${APP_ENV}.yaml`;
105
- if (fs2.pathExists(appEnvYamlPath)) {
106
- console.log(`merging-in ${dimGrey(appEnvYamlPath)}`);
107
- _merge(appYaml, yaml2.readYaml(appEnvYamlPath));
108
- }
109
- // appYamlPassEnv
110
- const passEnv = appYamlPassEnv
111
- .split(',')
112
- .filter(Boolean)
113
- // oxlint-disable-next-line unicorn/no-array-reduce
114
- .reduce((map, key) => {
115
- const v = process.env[key];
116
- if (!v) {
117
- throw new Error(`appYamlPassEnv.${key} is requested, but process.env.${key} is not defined!`);
118
- }
119
- map[key] = v;
120
- return map;
121
- }, {});
122
- if (Object.keys(passEnv).length) {
123
- console.log(`will merge ${white(String(Object.keys(passEnv).length))} process.env keys to app.yaml: ${dimGrey(Object.keys(passEnv).join(', '))}`);
124
- }
125
- _merge(appYaml, {
126
- service,
127
- env_variables: {
128
- APP_ENV,
129
- ...passEnv,
130
- },
131
- });
132
- // Redacted appYaml to not show up secrets
133
- console.log({
134
- appYaml: redactedAppYaml(appYaml),
135
- });
136
- return appYaml;
137
- }
138
- function redactedAppYaml(appYaml) {
139
- return {
140
- ...appYaml,
141
- env_variables: _mapValues(appYaml.env_variables || {}, (_k, v) => _truncate(v, 7)),
142
- };
143
- }
144
- export function validateGAEServiceName(serviceName) {
145
- // May only contain lowercase letters, digits, and hyphens. Must begin and end with a letter or digit. Must not exceed 63 characters.
146
- return serviceName
147
- .replaceAll('_', '-')
148
- .toLowerCase()
149
- .replaceAll(/[^0-9a-z-]/gi, '')
150
- .slice(0, 40);
151
- }
@@ -1,10 +0,0 @@
1
- import type { DeployHealthCheckOptions } from './deployHealthCheck.js';
2
- import type { DeployPrepareOptions } from './deployPrepare.js';
3
- export interface DeployGaeOptions extends DeployPrepareOptions, DeployHealthCheckOptions {
4
- }
5
- export declare function deployGae(opt?: DeployGaeOptions): Promise<void>;
6
- /**
7
- * Undeploys/removes the GAE service/version, using the same rules as deployGae.
8
- * Detects the service/version by the same criteria: branch name, backend.cfg.yaml, etc.
9
- */
10
- export declare function undeployGae(branch: string): Promise<void>;
@@ -1,90 +0,0 @@
1
- import { _anyToError } from '@naturalcycles/js-lib/error';
2
- import { pRetry } from '@naturalcycles/js-lib/promise/pRetry.js';
3
- import { _objectAssign } from '@naturalcycles/js-lib/types';
4
- import { appendToGithubSummary } from '@naturalcycles/nodejs-lib/env';
5
- import { exec2 } from '@naturalcycles/nodejs-lib/exec2';
6
- import { fs2 } from '@naturalcycles/nodejs-lib/fs2';
7
- import { getBackendCfg } from './backend.cfg.util.js';
8
- import { createDeployInfo } from './deploy.util.js';
9
- import { deployHealthCheck } from './deployHealthCheck.js';
10
- import { deployPrepare } from './deployPrepare.js';
11
- export async function deployGae(opt = {}) {
12
- const { logOnFailure, logOnSuccess } = opt;
13
- // 1. build
14
- const packageManager = detectPackageManager();
15
- exec2.spawn(`${packageManager} build`);
16
- // 2. deploy-prepare
17
- const deployInfo = await deployPrepare();
18
- const targetDir = './tmp/deploy';
19
- const appYamlPath = `${targetDir}/app.yaml`;
20
- const { gaeProject, gaeService, gaeVersion, versionUrl, serviceUrl } = deployInfo;
21
- _objectAssign(opt, {
22
- gaeProject,
23
- gaeService,
24
- gaeVersion,
25
- });
26
- await pRetry(async () => {
27
- try {
28
- exec2.spawn(`gcloud app deploy ${appYamlPath} --project ${gaeProject} --version ${gaeVersion} --quiet --no-promote`);
29
- }
30
- catch (err) {
31
- if (logOnFailure) {
32
- logs(gaeProject, gaeService, gaeVersion);
33
- }
34
- throw err;
35
- }
36
- }, {
37
- name: 'deploy',
38
- maxAttempts: 2,
39
- delay: 30_000,
40
- // todo: this doesn't work, as the error is different from what is logged.
41
- // We shoud somehow capture the logged text
42
- predicate: err => _anyToError(err).message.includes('operation is already in progress'),
43
- });
44
- // Health check (versionUrl)
45
- // yarn deploy-health-check --url $deployInfo_versionUrl --repeat 3 --timeoutSec 180 --intervalSec 2
46
- await deployHealthCheck(versionUrl, opt);
47
- // Only if "timestamped version" is used ('1' is default)
48
- if (gaeVersion !== '1') {
49
- // Rollout (promote versionUrl to serviceUrl)
50
- // gcloud app services set-traffic $deployInfo_gaeService --project $deployInfo_gaeProject --splits $deployInfo_gaeVersion=1 --quiet
51
- exec2.spawn(`gcloud app services set-traffic ${gaeService} --project ${gaeProject} --splits ${gaeVersion}=1 --quiet`);
52
- // Health check (serviceUrl)
53
- // yarn deploy-health-check --url $deployInfo_serviceUrl --repeat 3 --timeoutSec 60 --intervalSec 2
54
- await deployHealthCheck(serviceUrl, opt);
55
- }
56
- appendToGithubSummary(`Deployed ${serviceUrl}`);
57
- // Logs
58
- if (logOnSuccess) {
59
- logs(gaeProject, gaeService, gaeVersion);
60
- }
61
- }
62
- /**
63
- * Undeploys/removes the GAE service/version, using the same rules as deployGae.
64
- * Detects the service/version by the same criteria: branch name, backend.cfg.yaml, etc.
65
- */
66
- export async function undeployGae(branch) {
67
- const projectDir = '.';
68
- const backendCfg = getBackendCfg(projectDir);
69
- const { gaeProject, gaeService, gaeVersion } = await createDeployInfo(backendCfg, branch);
70
- // if (prod) {
71
- // console.log(`undeployGae (branch: ${branch}): not removing prod version (safety check)`)
72
- // return
73
- // }
74
- console.log(`undeployGae (branch: ${branch}): going to remove ${gaeProject}/${gaeService}/${gaeVersion}`);
75
- exec2.spawn(`gcloud app versions delete --project ${gaeProject} --service ${gaeService} ${gaeVersion} --quiet`);
76
- appendToGithubSummary(`removed ${gaeProject}/${gaeService}/${gaeVersion}`);
77
- }
78
- function logs(gaeProject, gaeService, gaeVersion) {
79
- try {
80
- exec2.spawn(`gcloud app logs read --project ${gaeProject} --service ${gaeService} --version ${gaeVersion}`);
81
- }
82
- catch { }
83
- }
84
- function detectPackageManager() {
85
- const pj = fs2.readText('package.json');
86
- if (pj.includes('pnpm')) {
87
- return 'pnpm';
88
- }
89
- return 'yarn'; // yarn is still the default
90
- }
@@ -1 +0,0 @@
1
- export declare const getDeployInfo: any;
@@ -1,25 +0,0 @@
1
- import { localTime } from '@naturalcycles/js-lib/datetime/localTime.js';
2
- import { _memoized } from '@naturalcycles/js-lib/decorators';
3
- import { fs2 } from '@naturalcycles/nodejs-lib/fs2';
4
- export const getDeployInfo = _memoized((projectDir) => {
5
- const deployInfoPath = `${projectDir}/deployInfo.json`;
6
- try {
7
- return fs2.readJson(deployInfoPath);
8
- }
9
- catch {
10
- // console.error(`cannot read ${deployInfoPath}, returning empty version`)
11
- return getDeployInfoStub();
12
- }
13
- });
14
- function getDeployInfoStub(stub = '') {
15
- return {
16
- gaeProject: stub,
17
- gaeService: stub,
18
- gaeVersion: stub,
19
- serviceUrl: stub,
20
- versionUrl: stub,
21
- gitBranch: stub,
22
- gitRev: stub,
23
- ts: localTime.nowUnix(),
24
- };
25
- }
@@ -1,13 +0,0 @@
1
- import type { DeployInfo } from './deploy.model.js';
2
- export interface DeployPrepareOptions {
3
- projectDir?: string;
4
- targetDir?: string;
5
- createNpmrc?: boolean;
6
- /**
7
- * Comma-separated list of env variables that will be passed to app.yaml from process.env.
8
- * Use it to pass secrets.
9
- */
10
- appYamlPassEnv?: string;
11
- }
12
- export declare const deployPrepareCliOptions: CliOptions;
13
- export declare function deployPrepare(opt?: DeployPrepareOptions): Promise<DeployInfo>;
@@ -1,85 +0,0 @@
1
- import { loadEnvFileIfExists } from '@naturalcycles/nodejs-lib';
2
- import { dimGrey } from '@naturalcycles/nodejs-lib/colors';
3
- import { fs2 } from '@naturalcycles/nodejs-lib/fs2';
4
- import { kpySync } from '@naturalcycles/nodejs-lib/kpy';
5
- import { srcDir } from '../paths.cnst.js';
6
- import { getBackendCfg } from './backend.cfg.util.js';
7
- import { createAndSaveAppYaml, createAndSaveDeployInfo } from './deploy.util.js';
8
- export const deployPrepareCliOptions = {
9
- projectDir: {
10
- type: 'string',
11
- default: '.',
12
- },
13
- targetDir: {
14
- type: 'string',
15
- default: `./tmp/deploy`,
16
- },
17
- createNpmrc: {
18
- type: 'boolean',
19
- desc: 'Create .npmrc in targetDir if NPM_TOKEN env var is set',
20
- default: true,
21
- },
22
- appYamlPassEnv: {
23
- type: 'string',
24
- desc: 'Comma-separated list of env variables that will be passed to app.yaml from process.env',
25
- },
26
- };
27
- const DEFAULT_FILES = [
28
- 'dist',
29
- // '!dist/test',
30
- // '!dist/**/*.test.*',
31
- // '!dist/**/*.mock.*',
32
- '!dist/**/*.script.*',
33
- 'src', // For Sentry
34
- '!src/test',
35
- '!src/**/*.test.*',
36
- '!src/**/*.mock.*',
37
- '!src/**/*.script.*',
38
- '!**/__snapshots__',
39
- '!**/__exclude',
40
- 'static',
41
- 'secret/**/*.enc', // encrypted secrets
42
- 'package.json',
43
- 'yarn.lock',
44
- '.yarnrc',
45
- 'pnpm-lock.yaml',
46
- 'pnpm-workspace.yaml',
47
- // 'tsconfig.json', // for path-mapping to work!
48
- // 'tsconfig.dist.json',
49
- '.gcloudignore',
50
- 'app.yaml',
51
- 'patches', // to allow patch-package
52
- 'resources',
53
- ];
54
- const defaultFilesDir = `${srcDir}/deploy/files-default`;
55
- export async function deployPrepare(opt = {}) {
56
- loadEnvFileIfExists();
57
- const { projectDir = '.', targetDir = './tmp/deploy', createNpmrc = true } = opt;
58
- const backendCfg = getBackendCfg(projectDir);
59
- const inputPatterns = backendCfg.files || DEFAULT_FILES;
60
- const appYamlPassEnv = opt.appYamlPassEnv || backendCfg.appYamlPassEnv;
61
- console.log(`1. Copy files to ${dimGrey(targetDir)}`);
62
- // Clean targetDir
63
- fs2.emptyDir(targetDir);
64
- kpySync({
65
- baseDir: defaultFilesDir,
66
- outputDir: targetDir,
67
- dotfiles: true,
68
- });
69
- kpySync({
70
- baseDir: projectDir,
71
- inputPatterns,
72
- outputDir: targetDir,
73
- dotfiles: true,
74
- });
75
- const { NPM_TOKEN } = process.env;
76
- if (NPM_TOKEN && createNpmrc) {
77
- const npmrcPath = `${targetDir}/.npmrc`;
78
- const npmrc = `//registry.npmjs.org/:_authToken=${NPM_TOKEN}`;
79
- fs2.writeFile(npmrcPath, npmrc);
80
- }
81
- console.log(`2. Generate ${dimGrey('deployInfo.json')} and ${dimGrey('app.yaml')} in targetDir`);
82
- const deployInfo = await createAndSaveDeployInfo(backendCfg, targetDir);
83
- createAndSaveAppYaml(backendCfg, deployInfo, projectDir, targetDir, appYamlPassEnv);
84
- return deployInfo;
85
- }
@@ -1,14 +0,0 @@
1
- import { _parseArgs } from '@naturalcycles/nodejs-lib/args'
2
- import { runScript } from '@naturalcycles/nodejs-lib/runScript'
3
- import { deployGae } from '../deploy/deployGae.js'
4
- import { deployHealthCheckCliOptions } from '../deploy/deployHealthCheck.js'
5
- import { deployPrepareCliOptions } from '../deploy/deployPrepare.js'
6
-
7
- runScript(async () => {
8
- const opt = _parseArgs({
9
- ...deployPrepareCliOptions,
10
- ...deployHealthCheckCliOptions,
11
- })
12
-
13
- await deployGae(opt)
14
- })
@@ -1,24 +0,0 @@
1
- /*
2
-
3
- yarn deploy-prepare
4
-
5
- */
6
-
7
- import { _parseArgs } from '@naturalcycles/nodejs-lib/args'
8
- import { runScript } from '@naturalcycles/nodejs-lib/runScript'
9
- import { deployPrepare, deployPrepareCliOptions } from '../deploy/deployPrepare.js'
10
-
11
- runScript(async () => {
12
- const opt = _parseArgs(deployPrepareCliOptions)
13
-
14
- await deployPrepare(opt)
15
- })
16
-
17
- // deploy strategy
18
- // gae project: from config
19
- // gae service: from config -- branch name
20
- // gae version: automatic form date
21
-
22
- // yarn build-prod
23
- // yarn deploy-prepare && ./tmp/deploy/app.yaml && ./tmp/deploy/deployInfo.json && json2env
24
- //
@@ -1,15 +0,0 @@
1
- import { _parseArgs } from '@naturalcycles/nodejs-lib/args'
2
- import { runScript } from '@naturalcycles/nodejs-lib/runScript'
3
- import { undeployGae } from '../deploy/deployGae.js'
4
-
5
- runScript(async () => {
6
- const { branch } = _parseArgs({
7
- branch: {
8
- type: 'string',
9
- demandOption: true,
10
- desc: `Because Github Actions delete event happens after the branch is already deleted - you need to pass it manually`,
11
- },
12
- })
13
-
14
- await undeployGae(branch)
15
- })
@@ -1,63 +0,0 @@
1
- import type { StringMap } from '@naturalcycles/js-lib/types'
2
- import { j } from '@naturalcycles/nodejs-lib/ajv'
3
- import { fs2 } from '@naturalcycles/nodejs-lib/fs2'
4
- import { yaml2 } from '@naturalcycles/nodejs-lib/yaml2'
5
-
6
- export interface BackendCfg {
7
- gaeProject: string
8
- gaeProjectByBranch?: StringMap
9
-
10
- /**
11
- * @example default
12
- */
13
- gaeService: string
14
- gaeServiceByBranch?: StringMap
15
-
16
- /**
17
- * List of file patterns to include in deployment.
18
- */
19
- files?: string[]
20
-
21
- appEnvDefault: string
22
- appEnvByBranch?: StringMap
23
-
24
- /**
25
- * List of branches to use timestamps in gae version names (to keep previous versions).
26
- */
27
- branchesWithTimestampVersions?: string[]
28
-
29
- /**
30
- * If true - branch names are not passed into deployed urls as is, but are hashed.
31
- */
32
- hashedBranches?: boolean
33
-
34
- /**
35
- * Comma-separated list of env variables that will be passed to app.yaml from process.env
36
- */
37
- appYamlPassEnv?: string
38
- }
39
-
40
- export const backendCfgSchema = j.object<BackendCfg>({
41
- gaeProject: j.string(),
42
- gaeProjectByBranch: j.object.stringMap(j.string()).optional(),
43
- gaeService: j.string(),
44
- gaeServiceByBranch: j.object.stringMap(j.string()).optional(),
45
- files: j.array(j.string()).optional(),
46
- appEnvDefault: j.string(),
47
- appEnvByBranch: j.object.stringMap(j.string()).optional(),
48
- branchesWithTimestampVersions: j.array(j.string()).optional(),
49
- hashedBranches: j.boolean().optional(),
50
- appYamlPassEnv: j.string().optional(),
51
- })
52
-
53
- export function getBackendCfg(projectDir = '.'): BackendCfg {
54
- const backendCfgYamlPath = `${projectDir}/backend.cfg.yaml`
55
-
56
- fs2.requireFileToExist(backendCfgYamlPath)
57
-
58
- const backendCfg: BackendCfg = {
59
- ...yaml2.readYaml(backendCfgYamlPath),
60
- }
61
-
62
- return backendCfgSchema.validate(backendCfg)
63
- }
@@ -1,32 +0,0 @@
1
- import type { UnixTimestamp } from '@naturalcycles/js-lib/types'
2
-
3
- export interface DeployInfo {
4
- gaeProject: string
5
- gaeService: string
6
- gaeVersion: string
7
- versionUrl: string
8
- serviceUrl: string
9
- gitRev: string
10
- gitBranch: string
11
-
12
- /**
13
- * Unix timestamp of deployInfo.json being generated.
14
- */
15
- ts: UnixTimestamp
16
- }
17
-
18
- export interface AppYaml extends Record<string, any> {
19
- runtime: string
20
- service: string
21
- inbound_services?: string[]
22
- instance_class?: string
23
- automatic_scaling?: {
24
- min_instances?: number
25
- max_instances?: number
26
- }
27
- env_variables: {
28
- APP_ENV: string
29
- DEBUG: string
30
- [k: string]: string
31
- }
32
- }