-
Notifications
You must be signed in to change notification settings - Fork 59
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(twilio-run): restructure configuration
This PR aims to restructure the way configuration is handled by dropping .twilio-functions files in favor of a dedicated config file and a deploy info cache file. BREAKING CHANGE: Drops support for .twilio-functions files and internally restructures activate files to promote fix #166
- Loading branch information
Showing
38 changed files
with
1,248 additions
and
635 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -69,5 +69,6 @@ dist/ | |
|
||
*.tsbuildinfo | ||
.twilio-functions | ||
*.twiliodeployinfo | ||
|
||
packages/serverless-api/docs/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
# Configuration | ||
|
||
## Examples | ||
|
||
### Functions with Preprocessor like TypeScript or Babel | ||
|
||
By default the Serverless Toolkit will be looking for Functions inside a `functions/` or `src/` directory and for assets for an `assets/` or `static/` directory. | ||
|
||
If you are using a pre-processor such as TypeScript or Babel, your structure might look different. For example maybe you have a structure where `src/` contains all TypeScript files and `dist/` contains the output. | ||
|
||
In which case you'd want a config that looks similar to this: | ||
|
||
```json | ||
{ | ||
"functionsFolderName": "dist" | ||
} | ||
``` | ||
|
||
### Using different `.env` files for different environments | ||
|
||
If you are deploying to different environments you might want different environment variables for your application. | ||
|
||
You can specify environment specific configurations inside the config file by using the domain suffix of your environment. | ||
|
||
If you are using the `--production` flag you'll need to use the environment: `*`. | ||
|
||
For example: | ||
|
||
```json | ||
{ | ||
"environments": { | ||
"dev": { | ||
"env": ".env" | ||
}, | ||
"stage": { | ||
"env": ".env.stage" | ||
}, | ||
"*": { | ||
"env": ".env.prod" | ||
} | ||
} | ||
} | ||
``` | ||
|
||
### Deploy to specific services on different accounts | ||
|
||
There might be a scenario where you want to deploy the same project to different Twilio accounts or projects with different services. | ||
|
||
Inside the config you can define which service the project should be deployed to depending on the Twilio Account SID. | ||
|
||
```json | ||
{ | ||
"projects": { | ||
"AC11111111111111111111111111111111": { | ||
"serviceSid": "ZSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" | ||
}, | ||
"AC22222222222222222222222222222222": { | ||
"serviceSid": "ZSbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" | ||
} | ||
} | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
jest.mock('../../src/config/utils/configLoader'); | ||
|
||
import { readSpecializedConfig } from '../../src/config/global'; | ||
import { ConfigurationFile } from '../../src/types/config'; | ||
const { | ||
__setTestConfig, | ||
}: { | ||
__setTestConfig: (config: Partial<ConfigurationFile>) => void; | ||
} = require('../../src/config/utils/configLoader'); | ||
|
||
describe('readSpecializedConfig', () => { | ||
test('returns the right base config', () => { | ||
__setTestConfig({ | ||
serviceSid: 'ZS11112222111122221111222211112222', | ||
env: '.env.example', | ||
}); | ||
|
||
expect( | ||
readSpecializedConfig('/tmp', '.twilioserverlessrc', 'deploy') | ||
).toEqual({ | ||
serviceSid: 'ZS11112222111122221111222211112222', | ||
env: '.env.example', | ||
}); | ||
}); | ||
|
||
test('merges command-specific config', () => { | ||
__setTestConfig({ | ||
serviceSid: 'ZS11112222111122221111222211112222', | ||
commands: { | ||
deploy: { | ||
functionsFolder: '/tmp/functions', | ||
}, | ||
}, | ||
}); | ||
|
||
expect( | ||
readSpecializedConfig('/tmp', '.twilioserverlessrc', 'deploy') | ||
).toEqual({ | ||
serviceSid: 'ZS11112222111122221111222211112222', | ||
functionsFolder: '/tmp/functions', | ||
}); | ||
}); | ||
|
||
test('ignores other command-specific config', () => { | ||
__setTestConfig({ | ||
serviceSid: 'ZS11112222111122221111222211112222', | ||
commands: { | ||
deploy: { | ||
functionsFolder: '/tmp/functions', | ||
}, | ||
start: { | ||
functionsFolder: '/tmp/src', | ||
}, | ||
}, | ||
}); | ||
|
||
expect( | ||
readSpecializedConfig('/tmp', '.twilioserverlessrc', 'deploy') | ||
).toEqual({ | ||
serviceSid: 'ZS11112222111122221111222211112222', | ||
functionsFolder: '/tmp/functions', | ||
}); | ||
}); | ||
|
||
test('environments override other config', () => { | ||
__setTestConfig({ | ||
serviceSid: 'ZS11112222111122221111222211112222', | ||
env: '.env.example', | ||
commands: { | ||
deploy: { | ||
functionsFolder: '/tmp/functions', | ||
}, | ||
}, | ||
environments: { | ||
stage: { | ||
env: '.env.stage', | ||
}, | ||
'*': { | ||
env: '.env.prod', | ||
}, | ||
}, | ||
}); | ||
|
||
expect( | ||
readSpecializedConfig('/tmp', '.twilioserverlessrc', 'deploy', { | ||
environmentSuffix: 'stage', | ||
}) | ||
).toEqual({ | ||
serviceSid: 'ZS11112222111122221111222211112222', | ||
functionsFolder: '/tmp/functions', | ||
env: '.env.stage', | ||
}); | ||
}); | ||
|
||
test('account config overrides every other config', () => { | ||
__setTestConfig({ | ||
serviceSid: 'ZS11112222111122221111222211112222', | ||
env: '.env.example', | ||
commands: { | ||
deploy: { | ||
functionsFolder: '/tmp/functions', | ||
}, | ||
}, | ||
environments: { | ||
stage: { | ||
serviceSid: 'ZS11112222111122221111222211112223', | ||
env: '.env.stage', | ||
}, | ||
'*': { | ||
env: '.env.prod', | ||
}, | ||
}, | ||
projects: { | ||
AC11112222111122221111222211114444: { | ||
serviceSid: 'ZS11112222111122221111222211114444', | ||
}, | ||
}, | ||
}); | ||
|
||
expect( | ||
readSpecializedConfig('/tmp', '.twilioserverlessrc', 'deploy', { | ||
environmentSuffix: 'stage', | ||
accountSid: 'AC11112222111122221111222211114444', | ||
}) | ||
).toEqual({ | ||
serviceSid: 'ZS11112222111122221111222211114444', | ||
functionsFolder: '/tmp/functions', | ||
env: '.env.stage', | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
48 changes: 48 additions & 0 deletions
48
packages/twilio-run/__tests__/templating/__snapshots__/defaultConfig.test.ts.snap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
// Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
||
exports[`writeDefaultConfigFile default file should match snapshot 1`] = ` | ||
"{ | ||
\\"commands\\": {}, | ||
\\"environments\\": {}, | ||
\\"projects\\": {}, | ||
// \\"accountSid\\": null /* A specific account SID to be used for deployment. Uses fields in .env otherwise */, | ||
// \\"assets\\": true /* Upload assets. Can be turned off with --no-assets */, | ||
// \\"assetsFolder\\": null /* Specific folder name to be used for static assets */, | ||
// \\"authToken\\": null /* Use a specific auth token for deployment. Uses fields from .env otherwise */, | ||
// \\"buildSid\\": null /* An existing Build SID to deploy to the new environment */, | ||
// \\"config\\": null /* Location of the config file. Absolute path or relative to current working directory (cwd) */, | ||
// \\"createEnvironment\\": false /* Creates environment if it couldn't find it. */, | ||
// \\"cwd\\": null /* Sets the directory of your existing Serverless project. Defaults to current directory */, | ||
// \\"detailedLogs\\": false /* Toggles detailed request logging by showing request body and query params */, | ||
// \\"edge\\": null /* Twilio API Region */, | ||
// \\"env\\": null /* Path to .env file for environment variables that should be installed */, | ||
// \\"environment\\": \\"dev\\" /* The environment name (domain suffix) you want to use for your deployment */, | ||
// \\"experimentalForkProcess\\": false /* Enable forking function processes to emulate production environment */, | ||
// \\"extendedOutput\\": false /* Show an extended set of properties on the output */, | ||
// \\"force\\": false /* Will run deployment in force mode. Can be dangerous. */, | ||
// \\"functionSid\\": null /* Specific Function SID to retrieve logs for */, | ||
// \\"functions\\": true /* Upload functions. Can be turned off with --no-functions */, | ||
// \\"functionsFolder\\": null /* Specific folder name to be used for static functions */, | ||
// \\"inspect\\": null /* Enables Node.js debugging protocol */, | ||
// \\"inspectBrk\\": null /* Enables Node.js debugging protocol, stops execution until debugger is attached */, | ||
// \\"legacyMode\\": false /* Enables legacy mode, it will prefix your asset paths with /assets */, | ||
// \\"live\\": true /* Always serve from the current functions (no caching) */, | ||
// \\"loadLocalEnv\\": false /* Includes the local environment variables */, | ||
// \\"loadSystemEnv\\": false /* Uses system environment variables as fallback for variables specified in your .env file. Needs to be used with --env explicitly specified. */, | ||
// \\"logCacheSize\\": null /* Tailing the log endpoint will cache previously seen entries to avoid duplicates. The cache is topped at a maximum of 1000 by default. This option can change that. */, | ||
// \\"logLevel\\": \\"info\\" /* Level of logging messages. */, | ||
// \\"logs\\": true /* Toggles request logging */, | ||
// \\"ngrok\\": null /* Uses ngrok to create a public url. Pass a string to set the subdomain (requires a paid-for ngrok account). */, | ||
// \\"outputFormat\\": \\"\\" /* Output the log in a different format */, | ||
// \\"overrideExistingProject\\": false /* Deploys Serverless project to existing service if a naming conflict has been found. */, | ||
// \\"port\\": \\"3000\\" /* Override default port of 3000 */, | ||
// \\"production\\": false /* Promote build to the production environment (no domain suffix). Overrides environment flag */, | ||
// \\"properties\\": null /* Specify the output properties you want to see. Works best on single types */, | ||
// \\"region\\": null /* Twilio API Region */, | ||
// \\"serviceName\\": null /* Overrides the name of the Serverless project. Default: the name field in your package.json */, | ||
// \\"serviceSid\\": null /* SID of the Twilio Serverless Service to deploy to */, | ||
// \\"sourceEnvironment\\": null /* SID or suffix of an existing environment you want to deploy from. */, | ||
// \\"tail\\": false /* Continuously stream the logs */, | ||
// \\"template\\": null /* undefined */, | ||
}" | ||
`; |
47 changes: 47 additions & 0 deletions
47
packages/twilio-run/__tests__/templating/defaultConfig.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
let _shouldFileExist = false; | ||
const writeFile = jest.fn().mockImplementation(async () => {}); | ||
const fileExists = jest.fn().mockImplementation(async () => _shouldFileExist); | ||
|
||
jest.mock('../../src/utils/fs', () => { | ||
return { | ||
writeFile, | ||
fileExists, | ||
}; | ||
}); | ||
|
||
import { writeDefaultConfigFile } from '../../src/templating/defaultConfig'; | ||
|
||
describe('writeDefaultConfigFile', () => { | ||
test('should write default file if none exists', async () => { | ||
_shouldFileExist = false; | ||
const wroteFile = await writeDefaultConfigFile('/tmp/'); | ||
expect(wroteFile).toEqual(true); | ||
expect(writeFile).toHaveBeenCalled(); | ||
}); | ||
|
||
test('default file should match snapshot', async () => { | ||
_shouldFileExist = false; | ||
const wroteFile = await writeDefaultConfigFile('/tmp/'); | ||
expect(wroteFile).toEqual(true); | ||
expect( | ||
writeFile.mock.calls[writeFile.mock.calls.length - 1][1] | ||
).toMatchSnapshot(); | ||
}); | ||
|
||
test('should not write false file if one exists', async () => { | ||
_shouldFileExist = true; | ||
const wroteFile = await writeDefaultConfigFile('/tmp/'); | ||
expect(wroteFile).toEqual(false); | ||
expect(writeFile).not.toHaveBeenCalled(); | ||
}); | ||
|
||
test('should handle if the default file could not be written', async () => { | ||
_shouldFileExist = false; | ||
writeFile.mockImplementationOnce(() => { | ||
throw new Error('Expected error'); | ||
}); | ||
const wroteFile = await writeDefaultConfigFile('/tmp/'); | ||
expect(wroteFile).toEqual(false); | ||
expect(writeFile).toHaveBeenCalled(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.