@adobe/helix-deploy 5.0.5 → 6.0.1

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/CHANGELOG.md CHANGED
@@ -1,3 +1,36 @@
1
+ ## [6.0.1](https://github.com/adobe/helix-deploy/compare/v6.0.0...v6.0.1) (2022-01-24)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * **deps:** update external fixes ([#360](https://github.com/adobe/helix-deploy/issues/360)) ([93a99c3](https://github.com/adobe/helix-deploy/commit/93a99c33357c92d4ca2aab6c591acc3f8ed4b400))
7
+
8
+ # [6.0.0](https://github.com/adobe/helix-deploy/compare/v5.1.0...v6.0.0) (2022-01-18)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * remove support for Azure deployments ([#359](https://github.com/adobe/helix-deploy/issues/359)) ([14322ef](https://github.com/adobe/helix-deploy/commit/14322ef5dd51224f538f0f32f8116cccde4c26d6))
14
+
15
+
16
+ ### BREAKING CHANGES
17
+
18
+ * azure support dropped.
19
+
20
+ # [5.1.0](https://github.com/adobe/helix-deploy/compare/v5.0.6...v5.1.0) (2022-01-12)
21
+
22
+
23
+ ### Features
24
+
25
+ * use lambda adapter to validate bundle and execute it ([#354](https://github.com/adobe/helix-deploy/issues/354)) ([c48b4f0](https://github.com/adobe/helix-deploy/commit/c48b4f0dfcae09fd784212b770bcdc7246a7d332)), closes [#353](https://github.com/adobe/helix-deploy/issues/353)
26
+
27
+ ## [5.0.6](https://github.com/adobe/helix-deploy/compare/v5.0.5...v5.0.6) (2022-01-11)
28
+
29
+
30
+ ### Bug Fixes
31
+
32
+ * **deps:** update external fixes ([#352](https://github.com/adobe/helix-deploy/issues/352)) ([ee411f3](https://github.com/adobe/helix-deploy/commit/ee411f3c03993f23eecbd024eff8d2a7e0b97ab7))
33
+
1
34
  ## [5.0.5](https://github.com/adobe/helix-deploy/compare/v5.0.4...v5.0.5) (2022-01-03)
2
35
 
3
36
 
package/README.md CHANGED
@@ -53,85 +53,139 @@ Operation Options
53
53
  --build Build the deployment package [boolean] [default: true]
54
54
  --deploy Automatically deploy to specified targets
55
55
  [boolean] [default: false]
56
- --test Invoke action after deployment. Can be relative url.
57
- [string]
56
+ --test Invoke action after deployment. Can be relative url or "
57
+ true" [string]
58
+ --test-bundle Invoke bundle after build. Can be relative url or "true"
59
+ . Defaults to the same as --test [string]
58
60
  --update-package Create or update package with params.
59
61
  [boolean] [default: false]
60
- -l, --version-link Create symlinks (sequences) after deployment. "major"
61
- and "minor" will create respective version links [array]
62
+ -l, --version-link Create symlinks (sequences) after deployment. "major" an
63
+ d "minor" will create respective version links [array]
62
64
  --delete Delete the action from OpenWhisk. Implies no-build
63
65
  [boolean] [default: false]
64
66
 
65
67
  Build Options
66
- --minify Minify the final bundle [boolean] [default: false]
67
- -s, --static Includes a static file into the archive [array] [default: []]
68
- --entryFile Specifies the entry file. [default: "src/index.js"]
69
- --externals Defines the externals for webpack. [array] [default: []]
70
- -m, --modules Include a node_module as is. [array] [default: []]
68
+ --minify Minify the final bundle [boolean] [default: false]
69
+ -s, --static Includes a static file into the archive
70
+ [array] [default: []]
71
+ --entryFile Specifies the entry file (the universal function).
72
+ [default: "src/index.js"]
73
+ --externals Defines the externals for the bundler.[array] [default: []]
74
+ -m, --modules Include a node_module as is. [array] [default: []]
75
+ --adapterFile Specifies the adapter file (the exported module).
76
+ --esm Produce EcmaScript Module (experimental, disables edge arch
77
+ ) [boolean] [default: false]
78
+ --bundler Select bundler backend (webpack, rollup)
79
+ [string] [default: "webpack"]
71
80
 
72
81
  Deploy Options
73
- --target Select target(s) for test, deploy, update-package
74
- actions (wsk,aws,azure,google,auto)
75
- [array] [default: ["auto"]]
82
+ --target Select target(s) for test, deploy, update-package act
83
+ ions (wsk,aws,google,auto)[array] [default: ["auto"]]
76
84
  --hints, --no-hints Show additional hints for deployment
77
85
  [boolean] [default: true]
78
86
 
79
87
  Test Options
80
- --target Select target(s) for test, deploy, update-package actions
81
- (wsk,aws,azure,google,auto) [array] [default: ["auto"]]
82
- --test-params Invoke openwhisk action after deployment with the given
83
- params. [array] [default: []]
88
+ --target Select target(s) for test, deploy, update-package actions
89
+ (wsk,aws,google,auto) [array] [default: ["auto"]]
90
+ --test-params Invoke openwhisk action after deployment with the given pa
91
+ rams. [array] [default: []]
92
+ --test-url Test url to use after deployment, in case --test is not an
93
+ url. [string]
94
+ --test-headers Test headers to send in test requests.
95
+ [array] [default: []]
84
96
 
85
97
  Link Options
86
- --target Select target(s) for test, deploy, update-package actions
87
- (wsk,aws,azure,google,auto) [array] [default: ["auto"]]
98
+ --target Select target(s) for test, deploy, update-package actions (
99
+ wsk,aws,google,auto) [array] [default: ["auto"]]
88
100
  --linkPackage Package name for version links [string]
89
101
 
90
102
  Update Package Options
91
103
  --package.params OpenWhisk package params. [array] [default: []]
92
104
  --package.params-file OpenWhisk package params file.[array] [default: []]
93
105
 
106
+ Cleanup Old Deployments: automatically delete redundant versions older than spe
107
+ cified.
108
+ Use a pattern like 7d or 1m to specify time frames.
109
+ Use a simple number like --cleanup-ci=5 to retain the last five CI builds
110
+ --cleanup-ci Automatically delete redundant CI versions
111
+ --cleanup-patch Automatically delete redundant patch versions. At least o
112
+ ne patch version for each minor version will be kept.
113
+ --cleanup-minor Automatically delete redundant minor versions. At least o
114
+ ne minor version for each major version will be kept.
115
+ --cleanup-major Automatically delete redundant major versions.
116
+
94
117
  General Action Options
95
118
  --name Action name. Can be prefixed with package.
96
119
  --package.name Action package name. [string]
97
- --node-version Specifies the node.js version to use in the serverless
98
- runtime [default: "12"]
120
+ --node-version Specifies the node.js version to use in the serverless run
121
+ time [default: "14"]
99
122
  -p, --params Include the given action param. can be json or env.
100
123
  [array] [default: []]
101
124
  -f, --params-file Include the given action param from a file; can be json or
102
- env. [array] [default: []]
125
+ env. [array] [default: []]
103
126
  --updated-by user that updated the action or sequence. [string]
104
- --updated-at unix timestamp when the action or sequence was updated
105
- (defaults to the current time).
106
- [number] [default: 1611635868339]
127
+ --updated-at unix timestamp when the action or sequence was updated (de
128
+ faults to the current time).
129
+ [number] [default: 1642491741896]
107
130
  --web-secure Annotates the action with require-whisk-auth. leave empty
108
131
  to generate random token. [string]
109
- -t, --timeout the timeout limit in milliseconds after which the action
110
- is terminated [default: 60000]
132
+ -t, --timeout the timeout limit in milliseconds after which the action i
133
+ s terminated [default: 60000]
111
134
  --pkgVersion Version use in the embedded package.json.
112
135
  --memory the maximum memory LIMIT in MB for the action
113
- --concurrency the maximum intra-container concurrent activation LIMIT
114
- for the action
136
+ --concurrency the maximum intra-container concurrent activation LIMIT fo
137
+ r the action
115
138
 
116
139
  OpenWhisk Action Options
117
- --namespace OpenWhisk namespace. Needs to match the namespace
118
- provided with the openwhisk credentials.
140
+ --namespace OpenWhisk namespace. Needs to match the namespace provid
141
+ ed with the openwhisk credentials.
119
142
  --package.shared OpenWhisk package scope. [boolean] [default: false]
120
143
 
121
144
  AWS Deployment Options
122
- --aws-region the AWS region to deploy lambda functions to
123
- [string] [default: ""]
124
- --aws-api the AWS API Gateway name. (id, "auto" or "create")
125
- [string] [default: "auto"]
126
- --aws-role the AWS role ARN to execute lambda functions with
145
+ --aws-region the AWS region to deploy lambda functions to
127
146
  [string] [default: ""]
128
- --aws-cleanup-buckets Cleans up stray temporary S3 buckets
147
+ --aws-api the AWS API Gateway name. (id, "auto" or "crea
148
+ te") [string] [default: "auto"]
149
+ --aws-role the AWS role ARN to execute lambda functions w
150
+ ith [string] [default: ""]
151
+ --aws-cleanup-buckets Cleans up stray temporary S3 buckets
129
152
  [boolean] [default: false]
130
- --aws-create-routes Create routes for function (usually not needed due
131
- to proxy function). [boolean] [default: false]
153
+ --aws-cleanup-integrations Cleans up unused integrations
154
+ [boolean] [default: false]
155
+ --aws-create-routes Create routes for function (usually not needed
156
+ due to proxy function).
157
+ [boolean] [default: false]
158
+
159
+ Google Deployment Options
160
+ --google-project-id the Google Cloud project to deploy to. Optional when
161
+ the key file is a JSON file [string] [default: ""]
162
+ --google-key-file full path to the a .json, .pem, or .p12 key downloade
163
+ d from the Google Developers Console
164
+ [string] [default: ""]
165
+ --google-email the Google account email address. Required when usin
166
+ g a .pem or .p12 credential file
167
+ [string] [default: ""]
168
+
169
+ Cloudflare Workers Deployment Options
170
+ --cloudflare-account-id the Cloudflare account ID to deploy to
171
+ [string] [default: ""]
172
+ --cloudflare-auth the Cloudflare API token from https://dash.cloud
173
+ flare.com/profile/api-tokens
174
+ [string] [default: ""]
175
+ --cloudflare-email the Cloudflare email address belonging to the au
176
+ thentication token [string] [default: ""]
177
+ --cloudflare-test-domain the *.workers.dev subdomain to use for testing d
178
+ eployed scripts [string] [default: ""]
132
179
 
133
- Azure Deployment Options
134
- --azure-app the Azure function app to deploy to [string] [default: ""]
180
+ Fastly Compute@Edge Options
181
+ --compute-service-id the Fastly Service to deploy the action to
182
+ [string] [default: ""]
183
+ --compute-domain
184
+ --fastly-auth the Fastly token [string] [default: ""]
185
+ --coralogix-token the Coralogix token (to enable logging)
186
+ [string] [default: ""]
187
+ --compute-coralogix-app the Application name
188
+ [string] [default: "fastly-compute"]
135
189
 
136
190
  Fastly Gateway Options
137
191
  --fastly-service-id the Fastly Service to use as a gateway
@@ -139,12 +193,40 @@ Fastly Gateway Options
139
193
  --fastly-auth the Fastly token [string] [default: ""]
140
194
  --checkpath the path to check as part of the Fastly health check
141
195
  [string] [default: ""]
196
+ --coralogix-token the Coralogix token (to enable logging)
197
+ [string] [default: ""]
198
+ --coralogix-app the Application name
199
+ [string] [default: "universal-runtime"]
142
200
 
143
201
  Options:
144
- --format Action formats
202
+ --arch Select archs(s) for bundles (node,edge).
203
+ [array] [default: ["node"]]
204
+ --format Action formats
145
205
  [default: {"aws":"/${packageName}/${baseName}/${version}"}]
146
- --property Additional properties that can be used in formats.
147
- [default: {}]
206
+ --property Additional properties that can be used in formats
207
+ . [default: {}]
208
+ --package-token Protects access to the gateway-stored package par
209
+ ameters with this token. leave empty to generate
210
+ random token.
211
+ [string] [default: "gXhVnUf6kIqZ64Xr0E4nTnlGBrKOrybQA7Ifx1S/2CA="]
212
+ --aws-parameter-manager Manager to use for storing package params. (eithe
213
+ r "secret" for Secrets Manager or "system" for Sy
214
+ stem Manager)
215
+ [array] [default: ["secret","system"]]
216
+ --aws-lambda-format Format to use to create lambda functions (note th
217
+ at all dots ('.') will be replaced with underscor
218
+ es.
219
+ [string] [default: "${packageName}--${baseName}"]
220
+ --google-region the Google Cloud region to deploy in
221
+ [string] [default: ""]
222
+ --compute-test-domain the domain name of the Compute@Edge service (used
223
+ for testing) [string] [default: ""]
224
+ --fastly-gateway the hostname of the Fastly gateway for package pa
225
+ rams [string] [default: ""]
226
+ --checkinterval the interval in milliseconds that each Fastly POP
227
+ should perform a health check. Set to 0 to disab
228
+ le health checks entirely.
229
+ [number] [default: 6000000]
148
230
  ```
149
231
 
150
232
  With no arguments,the `hedy` just bundles your code into the respective `action.zip`:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adobe/helix-deploy",
3
- "version": "5.0.5",
3
+ "version": "6.0.1",
4
4
  "description": "Library and Commandline Tools to build and deploy OpenWhisk Actions",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://github.com/adobe/helix-deploy#readme",
@@ -39,41 +39,39 @@
39
39
  "dependencies": {
40
40
  "@adobe/fastly-native-promises": "2.0.0",
41
41
  "@adobe/helix-fetch": "3.0.0",
42
- "@aws-sdk/client-apigatewayv2": "3.45.0",
43
- "@aws-sdk/client-lambda": "3.45.0",
44
- "@aws-sdk/client-s3": "3.45.0",
45
- "@aws-sdk/client-secrets-manager": "3.45.0",
46
- "@aws-sdk/client-ssm": "3.45.0",
47
- "@azure/arm-appservice": "9.0.0",
48
- "@azure/ms-rest-nodeauth": "3.1.1",
42
+ "@aws-sdk/client-apigatewayv2": "3.48.0",
43
+ "@aws-sdk/client-lambda": "3.48.0",
44
+ "@aws-sdk/client-s3": "3.48.0",
45
+ "@aws-sdk/client-secrets-manager": "3.48.0",
46
+ "@aws-sdk/client-ssm": "3.48.0",
49
47
  "@fastly/js-compute": "0.2.1",
50
48
  "@google-cloud/functions": "1.2.0",
51
49
  "@google-cloud/secret-manager": "3.10.1",
52
- "@google-cloud/storage": "5.16.1",
50
+ "@google-cloud/storage": "5.18.0",
53
51
  "@rollup/plugin-alias": "3.1.9",
54
52
  "@rollup/plugin-commonjs": "21.0.1",
55
53
  "@rollup/plugin-json": "4.1.0",
56
- "@rollup/plugin-node-resolve": "13.1.2",
54
+ "@rollup/plugin-node-resolve": "13.1.3",
57
55
  "archiver": "5.3.0",
58
- "chalk-template": "0.2.0",
56
+ "chalk-template": "0.3.1",
59
57
  "constants-browserify": "1.0.0",
60
- "dotenv": "10.0.0",
58
+ "dotenv": "14.2.0",
61
59
  "express": "4.17.2",
62
60
  "form-data": "4.0.0",
63
61
  "fs-extra": "10.0.0",
64
62
  "get-stream": "6.0.1",
65
- "isomorphic-git": "1.10.3",
66
- "openwhisk": "3.21.5",
63
+ "isomorphic-git": "1.10.5",
64
+ "openwhisk": "3.21.6",
67
65
  "proxyquire": "2.1.3",
68
- "rollup": "2.62.0",
66
+ "rollup": "2.66.0",
69
67
  "rollup-plugin-terser": "7.0.2",
70
68
  "semver": "7.3.5",
71
69
  "tar": "6.1.11",
72
- "webpack": "5.65.0",
70
+ "webpack": "5.67.0",
73
71
  "yargs": "17.3.1"
74
72
  },
75
73
  "devDependencies": {
76
- "@adobe/eslint-config-helix": "1.3.1",
74
+ "@adobe/eslint-config-helix": "1.3.2",
77
75
  "@adobe/helix-shared-wrap": "1.0.0",
78
76
  "@adobe/helix-status": "9.2.4",
79
77
  "@adobe/helix-universal-logger": "2.0.0",
@@ -83,15 +81,15 @@
83
81
  "chai": "4.3.4",
84
82
  "chai-http": "4.3.0",
85
83
  "codecov": "3.8.3",
86
- "eslint": "8.6.0",
84
+ "eslint": "8.7.0",
87
85
  "eslint-plugin-header": "3.1.1",
88
86
  "eslint-plugin-import": "2.25.4",
89
87
  "husky": "7.0.4",
90
- "lint-staged": "12.1.5",
91
- "mocha": "9.1.3",
88
+ "lint-staged": "12.3.1",
89
+ "mocha": "9.1.4",
92
90
  "mocha-junit-reporter": "2.0.2",
93
91
  "mocha-multi-reporters": "1.5.1",
94
- "nock": "13.2.1",
92
+ "nock": "13.2.2",
95
93
  "semantic-release": "18.0.1",
96
94
  "sinon": "12.0.1",
97
95
  "yauzl": "2.10.0"
@@ -381,6 +381,10 @@ export default class ActionBuilder {
381
381
  for (const bundler of this.bundlers) {
382
382
  await bundler.createBundle();
383
383
  await bundler.createArchive();
384
+ }
385
+ }
386
+ if (cfg.build || cfg.test !== undefined || cfg.testBundle !== undefined) {
387
+ for (const bundler of this.bundlers) {
384
388
  await bundler.validateBundle();
385
389
  }
386
390
  }
@@ -408,7 +412,7 @@ export default class ActionBuilder {
408
412
  await this.delete();
409
413
  }
410
414
 
411
- if (typeof cfg.test === 'string' || Object.keys(cfg.testParams).length) {
415
+ if (cfg.test !== undefined || Object.keys(cfg.testParams).length) {
412
416
  await this.validateDeployers();
413
417
  await this.test();
414
418
  }
package/src/BaseConfig.js CHANGED
@@ -58,6 +58,7 @@ export default class BaseConfig {
58
58
  nodeVersion: null,
59
59
  deploy: false,
60
60
  test: null,
61
+ testBundle: null,
61
62
  testUrl: null,
62
63
  testParams: {},
63
64
  testHeaders: {},
@@ -173,6 +174,7 @@ export default class BaseConfig {
173
174
  .withDelete(argv.delete)
174
175
  .withDeploy(argv.deploy)
175
176
  .withTest(argv.test)
177
+ .withTestBundle(argv.testBundle)
176
178
  .withTestParams(argv.testParams)
177
179
  .withTestHeaders(argv.testHeaders)
178
180
  .withTestUrl(argv.testUrl)
@@ -279,6 +281,11 @@ export default class BaseConfig {
279
281
  return this;
280
282
  }
281
283
 
284
+ withTestBundle(enable) {
285
+ this.testBundle = enable;
286
+ return this;
287
+ }
288
+
282
289
  withTestUrl(value) {
283
290
  this.testUrl = value;
284
291
  return this;
@@ -572,7 +579,7 @@ export default class BaseConfig {
572
579
  default: '.',
573
580
  })
574
581
 
575
- .group(['help', 'build', 'deploy', 'test', 'update-package', 'version-link', 'delete'], 'Operation Options')
582
+ .group(['help', 'build', 'deploy', 'test', 'test-bundle', 'update-package', 'version-link', 'delete'], 'Operation Options')
576
583
  .option('build', {
577
584
  description: 'Build the deployment package',
578
585
  type: 'boolean',
@@ -587,6 +594,10 @@ export default class BaseConfig {
587
594
  description: 'Invoke action after deployment. Can be relative url or "true"',
588
595
  type: 'string',
589
596
  })
597
+ .option('test-bundle', {
598
+ description: 'Invoke bundle after build. Can be relative url or "true". Defaults to the same as --test',
599
+ type: 'string',
600
+ })
590
601
  .option('version-link', {
591
602
  alias: 'l',
592
603
  description: 'Create symlinks (sequences) after deployment. "major" and "minor" will create respective version links',
@@ -653,7 +664,7 @@ export default class BaseConfig {
653
664
 
654
665
  .group(['target', 'hints'], 'Deploy Options')
655
666
  .option('target', {
656
- description: 'Select target(s) for test, deploy, update-package actions (wsk,aws,azure,google,auto)',
667
+ description: 'Select target(s) for test, deploy, update-package actions (wsk,aws,google,auto)',
657
668
  type: 'string',
658
669
  default: ['auto'],
659
670
  array: true,
@@ -60,12 +60,15 @@ export default class BaseBundler {
60
60
  async validateBundle() {
61
61
  const { cfg } = this;
62
62
  cfg.log.info('--: validating bundle ...');
63
- const result = await validateBundle(cfg.bundle);
63
+ const result = await validateBundle(cfg.bundle, cfg);
64
64
  if (result.error) {
65
- cfg.log.error(chalk`{red error:}`, result.error);
66
65
  throw Error(`Validation failed: ${result.error}`);
67
66
  }
68
- cfg.log.info(chalk`{green ok:} bundle can be loaded and has a {grey main()} function.`);
67
+ if (result.response) {
68
+ cfg.log.info(chalk`{green ok:} bundle can be loaded and {grey lambda()} function can be executed.`);
69
+ } else {
70
+ cfg.log.info(chalk`{green ok:} bundle can be loaded and has a {grey lambda()} function.`);
71
+ }
69
72
  }
70
73
 
71
74
  async createArchive() {
@@ -179,9 +182,6 @@ export default class BaseBundler {
179
182
  'workers_dev = true',
180
183
  ].join('\n'), { name: 'wrangler.toml' });
181
184
 
182
- // azure functions manifest
183
- archive.append(JSON.stringify(this.functionJson, null, ' '), { name: 'function.json' });
184
-
185
185
  // this allows to use a cjs loader for the esm modules. but it still doesn't work on AWS
186
186
  if (cfg.esm) {
187
187
  archive.directory('esm-adapter');
package/src/cli.js CHANGED
@@ -17,7 +17,6 @@ import { config as envConfig } from 'dotenv';
17
17
  import BaseConfig from './BaseConfig.js';
18
18
  import OpenWhiskDeployer from './deploy/OpenWhiskDeployer.js';
19
19
  import AWSDeployer from './deploy/AWSDeployer.js';
20
- import AzureDeployer from './deploy/AzureDeployer.js';
21
20
  import GoogleDeployer from './deploy/GoogleDeployer.js';
22
21
  import CloudflareDeployer from './deploy/CloudflareDeployer.js';
23
22
  import ComputeAtEdgeDeployer from './deploy/ComputeAtEdgeDeployer.js';
@@ -27,7 +26,6 @@ import ActionBuilder from './ActionBuilder.js';
27
26
  const PLUGINS = [
28
27
  OpenWhiskDeployer,
29
28
  AWSDeployer,
30
- AzureDeployer,
31
29
  GoogleDeployer,
32
30
  CloudflareDeployer,
33
31
  ComputeAtEdgeDeployer,
@@ -14,14 +14,13 @@ const {
14
14
  openwhisk,
15
15
  aws,
16
16
  google,
17
- azure,
18
17
  } = require('@adobe/helix-universal').adapter;
19
18
 
20
19
  // eslint-disable-next-line no-underscore-dangle
21
20
  global.__rootdir = dirname(__filename); // __dirname is transformed by webpack, __filename isn't
22
21
 
23
- module.exports = Object.assign(azure, {
22
+ module.exports = {
24
23
  main: openwhisk,
25
24
  lambda: aws,
26
25
  google,
27
- });
26
+ };
@@ -13,13 +13,13 @@
13
13
  import { dirname } from 'path';
14
14
  import { fileURLToPath } from 'url';
15
15
  import { adapter } from '@adobe/helix-universal';
16
- const { openwhisk, aws, google, azure } = adapter;
16
+ const { openwhisk, aws, google } = adapter;
17
17
 
18
18
  // eslint-disable-next-line no-underscore-dangle
19
19
  global.__rootdir = dirname(fileURLToPath(import.meta.url));
20
20
 
21
- export default Object.assign(azure, {
21
+ export default {
22
22
  main: openwhisk,
23
23
  lambda: aws,
24
24
  google,
25
- });
25
+ };
@@ -9,19 +9,54 @@
9
9
  * OF ANY KIND, either express or implied. See the License for the specific language
10
10
  * governing permissions and limitations under the License.
11
11
  */
12
- async function run(bundlePath, opts) {
12
+ async function run(bundlePath, cfg) {
13
13
  const result = {
14
+ status: 'ok',
14
15
  };
15
16
  try {
16
17
  const bundle = await import(bundlePath);
17
- const main = bundle.default?.main;
18
- if (!main || typeof main !== 'function') {
19
- throw Error('Action has no main() function.');
18
+ const lambda = bundle.default?.lambda;
19
+ if (!lambda || typeof lambda !== 'function') {
20
+ throw Error('Action has no lambda() function.');
20
21
  }
21
- if (opts.invoke) {
22
- result.response = await main({});
22
+ const test = cfg.testBundle ?? cfg.test;
23
+ if (test !== undefined) {
24
+ const event = {
25
+ headers: cfg.testHeaders || {},
26
+ rawPath: `/${cfg.packageName}/${cfg.baseName}/${cfg.version}`,
27
+ rawQueryString: '',
28
+ pathParameters: {
29
+ path: '',
30
+ },
31
+ requestContext: {
32
+ domainName: 'localhost',
33
+ http: {
34
+ method: 'get',
35
+ },
36
+ },
37
+ };
38
+
39
+ const testUrl = String(test).startsWith('/') ? test : cfg.testUrl;
40
+ if (testUrl) {
41
+ const url = new URL(testUrl, 'https://localhost/');
42
+ event.pathParameters.path = url.pathname.substring(1);
43
+ event.rawPath += url.pathname;
44
+ event.rawQueryString = url.searchParams.toString();
45
+ }
46
+ const fn = typeof lambda.raw === 'function' ? lambda.raw : lambda;
47
+ result.response = await fn(event, {
48
+ invokedFunctionArn: `arn:aws:lambda:us-east-1:118435662149:function:${cfg.packageName}--${cfg.baseName}:${cfg.version}`,
49
+ getRemainingTimeInMillis: () => 60 * 1000,
50
+ });
51
+ if (cfg.verbose) {
52
+ // eslint-disable-next-line no-console
53
+ console.log(result.response);
54
+ }
55
+ if (result.response.statusCode !== 200) {
56
+ result.status = 'error';
57
+ result.error = result.response.statusCode;
58
+ }
23
59
  }
24
- result.status = 'ok';
25
60
  } catch (e) {
26
61
  result.status = 'error';
27
62
  result.error = `${e.message}\n${e.stack}`;
package/src/utils.js CHANGED
@@ -155,12 +155,9 @@ export function filterActions(fns, now, {
155
155
  ...cleanmajorbyage, ...cleanmajorbycount];
156
156
  }
157
157
 
158
- export async function validateBundle(bundlePath, invoke = false) {
158
+ export async function validateBundle(bundlePath, cfg) {
159
159
  try {
160
- const opts = {
161
- invoke,
162
- };
163
- const child = fork(path.resolve(__dirname, 'template', 'validate-bundle.js'), [bundlePath, JSON.stringify(opts)]);
160
+ const child = fork(path.resolve(__dirname, 'template', 'validate-bundle.js'), [bundlePath, JSON.stringify(cfg)]);
164
161
  const ret = await new Promise((resolve, reject) => {
165
162
  child.on('message', resolve);
166
163
  child.on('error', reject);
@@ -1,38 +0,0 @@
1
- /*
2
- * Copyright 2020 Adobe. All rights reserved.
3
- * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
- * you may not use this file except in compliance with the License. You may obtain a copy
5
- * of the License at http://www.apache.org/licenses/LICENSE-2.0
6
- *
7
- * Unless required by applicable law or agreed to in writing, software distributed under
8
- * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
- * OF ANY KIND, either express or implied. See the License for the specific language
10
- * governing permissions and limitations under the License.
11
- */
12
- export default class AzureConfig {
13
- constructor() {
14
- Object.assign(this, {
15
- appName: '',
16
- });
17
- }
18
-
19
- configure(argv) {
20
- return this
21
- .withAzureApp(argv.azureApp);
22
- }
23
-
24
- withAzureApp(value) {
25
- this.appName = value;
26
- return this;
27
- }
28
-
29
- static yarg(yargs) {
30
- return yargs
31
- .group(['azure-app'], 'Azure Deployment Options')
32
- .option('azure-app', {
33
- description: 'the Azure function app to deploy to',
34
- type: 'string',
35
- default: '',
36
- });
37
- }
38
- }
@@ -1,232 +0,0 @@
1
- /*
2
- * Copyright 2020 Adobe. All rights reserved.
3
- * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
- * you may not use this file except in compliance with the License. You may obtain a copy
5
- * of the License at http://www.apache.org/licenses/LICENSE-2.0
6
- *
7
- * Unless required by applicable law or agreed to in writing, software distributed under
8
- * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
- * OF ANY KIND, either express or implied. See the License for the specific language
10
- * governing permissions and limitations under the License.
11
- */
12
- import msRestNodeAuth from '@azure/ms-rest-nodeauth';
13
- import { WebSiteManagementClient } from '@azure/arm-appservice';
14
-
15
- import fs from 'fs';
16
- import BaseDeployer from './BaseDeployer.js';
17
- import AzureConfig from './AzureConfig.js';
18
-
19
- export default class AzureDeployer extends BaseDeployer {
20
- constructor(baseConfig, config) {
21
- super(baseConfig);
22
- Object.assign(this, {
23
- id: 'azure',
24
- name: 'Azure',
25
- _cfg: config,
26
- _auth: null,
27
- _pubcreds: null,
28
- });
29
- }
30
-
31
- ready() {
32
- return !!this._cfg.appName && !!this._auth;
33
- }
34
-
35
- validate() {
36
- if (!this.ready()) {
37
- throw Error('Azure target needs --azure-app');
38
- }
39
- }
40
-
41
- get basePath() {
42
- return `/api/${this.cfg.packageName}/${this.cfg.name.replace('@', '/')}`;
43
- }
44
-
45
- // eslint-disable-next-line class-methods-use-this
46
- get customVCL() {
47
- // fix azure's blob handling
48
- // todo: more comprehensive regex of commonly uploaded mime types
49
- return `if (req.http.content-type != "" && req.http.content-type ~ "^(image)/.*") {
50
- set req.http.x-backup-content-type = req.http.content-type;
51
- set req.http.content-type = "application/octet-stream";
52
- }`;
53
- }
54
-
55
- async init() {
56
- const clientId = process.env.AZURE_CLIENT_ID;
57
- const secret = process.env.AZURE_CLIENT_SECRET;
58
- const tenantId = process.env.AZURE_TENANT_ID;
59
-
60
- if (!!clientId && !!secret && !!tenantId && !!this._cfg.appName) {
61
- try {
62
- const res = await msRestNodeAuth.loginWithServicePrincipalSecretWithAuthResponse(
63
- clientId,
64
- secret,
65
- tenantId,
66
- );
67
- this._auth = res;
68
-
69
- const subscription = process.env.AZURE_SUBSCRIPTION_ID || this._auth.subscriptions[0].id;
70
-
71
- this._client = new WebSiteManagementClient(
72
- this._auth.credentials,
73
- subscription,
74
- );
75
- const [apps] = (await this._client.webApps.list()).filter(
76
- (app) => app.name === this._cfg.appName,
77
- );
78
- this._app = apps;
79
-
80
- this._pubcreds = await this._client.webApps.listPublishingCredentials(
81
- this._app.resourceGroup,
82
- this._cfg.appName,
83
- );
84
- } catch (e) {
85
- this.log.error(`Unable to authenticate with Azure:${e.message}`);
86
- throw e;
87
- }
88
- }
89
- }
90
-
91
- get fullFunctionName() {
92
- const { cfg } = this;
93
- const funcname = `${cfg.packageName}--${cfg.name}`.replace('@', '_').replace(/\./g, '_');
94
- return funcname;
95
- }
96
-
97
- async uploadFunctionZIP() {
98
- const { cfg } = this;
99
- const url = new URL(
100
- `${this._pubcreds.scmUri}/api/zip/site/wwwroot/${this.fullFunctionName}/`,
101
- ).href.replace(/https:\/\/.*?@/, 'https://');
102
- // const url = new URL(this._pubcreds.scmUri + `/api/zip/site/wwwroot/${'newfunc'.replace('/', '--')}/`).href.replace(/https:\/\/.*?@/, 'https://');
103
- const body = fs.createReadStream(cfg.zipFile);
104
- const authorization = `Basic ${Buffer.from(
105
- `${this._pubcreds.publishingUserName
106
- }:${
107
- this._pubcreds.publishingPassword}`,
108
- ).toString('base64')}`;
109
-
110
- this.log.info(`--: uploading ${this.relZip} to Azure bucket ${url} ...`);
111
-
112
- const resp = await this.fetch(url, {
113
- method: 'PUT',
114
- body,
115
- headers: {
116
- authorization,
117
- },
118
- });
119
- if (resp.ok) {
120
- this.log.info(`File uploaded ${await resp.text()}`);
121
- } else {
122
- throw new Error(
123
- `File upload failed (${resp.status}): ${await resp.text()}`,
124
- );
125
- }
126
- }
127
-
128
- async updateParams() {
129
- const { cfg } = this;
130
- this.log.info('--: updating function parameters ...');
131
- const url = new URL(
132
- `${this._pubcreds.scmUri}/api/vfs/site/wwwroot/${this.fullFunctionName}/params.json`,
133
- ).href.replace(/https:\/\/.*?@/, 'https://');
134
-
135
- const authorization = `Basic ${Buffer.from(
136
- `${this._pubcreds.publishingUserName
137
- }:${
138
- this._pubcreds.publishingPassword}`,
139
- ).toString('base64')}`;
140
-
141
- let params = {};
142
- let ifmatch = '*';
143
- try {
144
- const prereq = await this.fetch(url, {
145
- method: 'GET',
146
- headers: {
147
- authorization,
148
- },
149
- });
150
- ifmatch = prereq.headers.get('ETag');
151
- params = prereq.json();
152
- } catch (err) {
153
- this.log.warn('Unable to get existing function parameters, starting from scratch.');
154
- }
155
-
156
- const resp = await this.fetch(url, {
157
- method: 'PUT',
158
- body: JSON.stringify({
159
- ...cfg.params,
160
- ...params,
161
- }),
162
- headers: {
163
- authorization,
164
- 'Content-Type': 'application/json',
165
- 'If-Match': ifmatch,
166
- },
167
- });
168
-
169
- if (resp.ok) {
170
- this.log.info(`Params updated ${await resp.text()}`);
171
- } else {
172
- throw new Error(
173
- `Parameter update failed (${resp.status}): ${await resp.text()}`,
174
- );
175
- }
176
- }
177
-
178
- async updatePackage() {
179
- const { cfg } = this;
180
- this.log.info('--: updating app (package) parameters ...');
181
-
182
- const result = await this._client.webApps.listApplicationSettings(
183
- this._app.resourceGroup,
184
- this._cfg.appName,
185
- );
186
-
187
- const update = {
188
- ...cfg.packageParams,
189
- ...result.properties,
190
- };
191
-
192
- await this._client.webApps.updateApplicationSettings(
193
- this._app.resourceGroup,
194
- this._cfg.appName,
195
- {
196
- properties: update,
197
- },
198
- );
199
-
200
- this.log.info(`${Object.keys(update).length} package parameters have been updated.`);
201
- }
202
-
203
- async deploy() {
204
- try {
205
- await this.uploadFunctionZIP();
206
- await this.updateParams();
207
- } catch (err) {
208
- this.log.error(`Unable to update Azure function: ${err.message}`);
209
- throw err;
210
- }
211
- }
212
-
213
- get host() {
214
- return this._app.hostNames[0];
215
- }
216
-
217
- // eslint-disable-next-line class-methods-use-this
218
- get urlVCL() {
219
- return '"/api/" + var.package + "/" + var.action + var.slashversion + var.rest';
220
- }
221
-
222
- async test() {
223
- const url = `https://${this._app.hostNames[0]}/api/${this.cfg.packageName}/${this.cfg.name.replace('@', '/')}`;
224
- return this.testRequest({
225
- url,
226
- // idHeader: 'X-Cloud-Trace-Context',
227
- retry404: 1,
228
- });
229
- }
230
- }
231
-
232
- AzureDeployer.Config = AzureConfig;