@adobe/helix-deploy 5.0.4 → 6.0.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.
- package/CHANGELOG.md +33 -0
- package/README.md +125 -43
- package/package.json +19 -21
- package/src/ActionBuilder.js +5 -1
- package/src/BaseConfig.js +13 -2
- package/src/bundler/BaseBundler.js +6 -6
- package/src/bundler/WebpackBundler.js +2 -0
- package/src/cli.js +0 -2
- package/src/template/node-index.js +2 -3
- package/src/template/node-index.mjs +3 -3
- package/src/template/validate-bundle.js +42 -7
- package/src/utils.js +2 -5
- package/src/deploy/AzureConfig.js +0 -38
- package/src/deploy/AzureDeployer.js +0 -232
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,36 @@
|
|
|
1
|
+
# [6.0.0](https://github.com/adobe/helix-deploy/compare/v5.1.0...v6.0.0) (2022-01-18)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* remove support for Azure deployments ([#359](https://github.com/adobe/helix-deploy/issues/359)) ([14322ef](https://github.com/adobe/helix-deploy/commit/14322ef5dd51224f538f0f32f8116cccde4c26d6))
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### BREAKING CHANGES
|
|
10
|
+
|
|
11
|
+
* azure support dropped.
|
|
12
|
+
|
|
13
|
+
# [5.1.0](https://github.com/adobe/helix-deploy/compare/v5.0.6...v5.1.0) (2022-01-12)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
### Features
|
|
17
|
+
|
|
18
|
+
* 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)
|
|
19
|
+
|
|
20
|
+
## [5.0.6](https://github.com/adobe/helix-deploy/compare/v5.0.5...v5.0.6) (2022-01-11)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
### Bug Fixes
|
|
24
|
+
|
|
25
|
+
* **deps:** update external fixes ([#352](https://github.com/adobe/helix-deploy/issues/352)) ([ee411f3](https://github.com/adobe/helix-deploy/commit/ee411f3c03993f23eecbd024eff8d2a7e0b97ab7))
|
|
26
|
+
|
|
27
|
+
## [5.0.5](https://github.com/adobe/helix-deploy/compare/v5.0.4...v5.0.5) (2022-01-03)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
### Bug Fixes
|
|
31
|
+
|
|
32
|
+
* use fixed import conditions ([#350](https://github.com/adobe/helix-deploy/issues/350)) ([28464d2](https://github.com/adobe/helix-deploy/commit/28464d245229236ff15bad6e20278ce5ebd8594b))
|
|
33
|
+
|
|
1
34
|
## [5.0.4](https://github.com/adobe/helix-deploy/compare/v5.0.3...v5.0.4) (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
|
-
|
|
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
|
-
|
|
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
|
|
67
|
-
-s, --static
|
|
68
|
-
|
|
69
|
-
--
|
|
70
|
-
|
|
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
|
-
|
|
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
|
|
81
|
-
|
|
82
|
-
--test-params
|
|
83
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
106
|
-
[number] [default:
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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-
|
|
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-
|
|
131
|
-
|
|
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
|
-
|
|
134
|
-
--
|
|
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
|
-
--
|
|
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
|
|
147
|
-
|
|
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": "
|
|
3
|
+
"version": "6.0.0",
|
|
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.
|
|
43
|
-
"@aws-sdk/client-lambda": "3.
|
|
44
|
-
"@aws-sdk/client-s3": "3.
|
|
45
|
-
"@aws-sdk/client-secrets-manager": "3.
|
|
46
|
-
"@aws-sdk/client-ssm": "3.
|
|
47
|
-
"@azure/arm-appservice": "9.0.0",
|
|
48
|
-
"@azure/ms-rest-nodeauth": "3.1.1",
|
|
42
|
+
"@aws-sdk/client-apigatewayv2": "3.47.0",
|
|
43
|
+
"@aws-sdk/client-lambda": "3.47.0",
|
|
44
|
+
"@aws-sdk/client-s3": "3.47.0",
|
|
45
|
+
"@aws-sdk/client-secrets-manager": "3.47.0",
|
|
46
|
+
"@aws-sdk/client-ssm": "3.47.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.
|
|
50
|
+
"@google-cloud/storage": "5.17.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.
|
|
54
|
+
"@rollup/plugin-node-resolve": "13.1.3",
|
|
57
55
|
"archiver": "5.3.0",
|
|
58
|
-
"chalk-template": "0.
|
|
56
|
+
"chalk-template": "0.3.0",
|
|
59
57
|
"constants-browserify": "1.0.0",
|
|
60
|
-
"dotenv": "
|
|
58
|
+
"dotenv": "14.1.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.
|
|
66
|
-
"openwhisk": "3.21.
|
|
63
|
+
"isomorphic-git": "1.10.4",
|
|
64
|
+
"openwhisk": "3.21.6",
|
|
67
65
|
"proxyquire": "2.1.3",
|
|
68
|
-
"rollup": "2.
|
|
66
|
+
"rollup": "2.64.0",
|
|
69
67
|
"rollup-plugin-terser": "7.0.2",
|
|
70
68
|
"semver": "7.3.5",
|
|
71
69
|
"tar": "6.1.11",
|
|
72
|
-
"webpack": "5.
|
|
70
|
+
"webpack": "5.66.0",
|
|
73
71
|
"yargs": "17.3.1"
|
|
74
72
|
},
|
|
75
73
|
"devDependencies": {
|
|
76
|
-
"@adobe/eslint-config-helix": "1.3.
|
|
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.
|
|
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.
|
|
91
|
-
"mocha": "9.1.
|
|
88
|
+
"lint-staged": "12.1.7",
|
|
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.
|
|
92
|
+
"nock": "13.2.2",
|
|
95
93
|
"semantic-release": "18.0.1",
|
|
96
94
|
"sinon": "12.0.1",
|
|
97
95
|
"yauzl": "2.10.0"
|
package/src/ActionBuilder.js
CHANGED
|
@@ -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 (
|
|
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,
|
|
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
|
-
|
|
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');
|
|
@@ -74,6 +74,8 @@ export default class WebpackBundler extends BaseBundler {
|
|
|
74
74
|
// the main.js is imported in the universal adapter and is _the_ action entry point
|
|
75
75
|
'./main.js': cfg.file,
|
|
76
76
|
},
|
|
77
|
+
// use fixed conditions to omit the `development` condition.
|
|
78
|
+
conditionNames: ['node', 'require'],
|
|
77
79
|
},
|
|
78
80
|
node: {
|
|
79
81
|
__dirname: true,
|
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 =
|
|
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
|
|
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
|
|
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,
|
|
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
|
|
18
|
-
if (!
|
|
19
|
-
throw Error('Action has no
|
|
18
|
+
const lambda = bundle.default?.lambda;
|
|
19
|
+
if (!lambda || typeof lambda !== 'function') {
|
|
20
|
+
throw Error('Action has no lambda() function.');
|
|
20
21
|
}
|
|
21
|
-
|
|
22
|
-
|
|
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,
|
|
158
|
+
export async function validateBundle(bundlePath, cfg) {
|
|
159
159
|
try {
|
|
160
|
-
const
|
|
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;
|