Skip to content

Commit 482ee0e

Browse files
bao1018jb-pwczxhaaa6Peachey_Chen
authored
feat: Switch from CloudFunctions v1 beta to v1 (#206)
BREAKING CHANGE: Services deployed with v1 Beta cannot be updated with v1. Co-authored-by: Jeremy Minhua Bao (US - ADVS) <jeremy.bao@pwc.com> Co-authored-by: zxhaaa <zxhaaa@hotmail.com> Co-authored-by: Peachey_Chen <mr_robot2015@foxmail.com>
1 parent 285523a commit 482ee0e

7 files changed

+166
-68
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@
44
/node_modules
55
npm-debug.log
66
/package-lock.json
7+
yarn.lock

MIGRATION_GUIDE.md

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# Migration Reference from v2 to v3
2+
3+
## Background
4+
5+
> Google Cloud Functions v1beta2 API version will be shut down on April 15, 2020
6+
7+
When you are using serverless to deploy google cloud functions with serverless google plugin v3 (Support google api v1),
8+
It may face a error like
9+
10+
```
11+
Deployment failed: TYPE_MISMATCH
12+
Resource types cannot be changed, previous (cloudfunctions.v1beta2.function) -> updated (gcp-types/cloudfunctions-v1:projects.locations.functions)
13+
```
14+
15+
Which means the former ones deployed used serverless-google-cloudfunctions v2, thus it failed to deploy.
16+
First please be careful that
17+
18+
## Solutions
19+
20+
If you choose to upgrade to v1 function , and make sure the _package.json_ using the latest plugin in nodejs project
21+
22+
```json
23+
"devDependencies": {
24+
"serverless-google-cloudfunctions": "*"
25+
},
26+
```
27+
28+
There are two options to upgrade the exising cloud functions that deploy via _serverless-google-cloudfunctions v2_ (google api v1beta).
29+
30+
### Option 1
31+
32+
The first is from the devops point of view ,you don't need to change the code at all.
33+
34+
you need to open the [deployment manager](https://cloud.google.com/deployment-manager) in GCP.
35+
36+
- _Delete all the functions_
37+
38+
You have to delete all the functions and related bucket first ,and then delete the all the related resources from deployment manager
39+
40+
- _Delete all the related buckets with cloud functions_
41+
42+
By default, each time you you use `serverless deploy` , it would create a bucket for you to store the zip package for the function. pls delete this bucket first.
43+
44+
- _Delete all the function resources in deployment manager_
45+
46+
- _Redeploy the functions_
47+
48+
### Option 2
49+
50+
The second is from the developers' point of view , which means you need to make some changes to the `serverless.yml`.
51+
52+
- Change the service name or change the function name to make sure this function is different from the older one.
53+
54+
- Redeploy the functions.
55+
56+
- Once it's done,you may consider delete the old ones.
57+
58+
### Notices
59+
60+
Both the methods have some pros and cons, see the details from here:
61+
62+
1. If your functions are called by bucket or pubsub, the modification of the function name may not impact your business.
63+
64+
2. If your functions are called by http, the function name would be changed, which means the http url that need to be called may also be changed
65+
66+
3. If you use cloud function to store some important data, pls export these data first and then import them to a new bucket.

README.md

+6
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,9 @@ You can spin up a Docker container which mounts this code with the following com
2727
```bash
2828
docker-compose run node bash
2929
```
30+
31+
## Migration
32+
33+
> Google Cloud Functions v1beta2 API version will be shut down on April 15, 2020
34+
35+
You can follow this [document](./MIGRATION_GUIDE.md) to upgrade your serverless-google-cloudfunctions v2 to v3

info/lib/displayServiceInfo.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ module.exports = {
3737
};
3838

3939
_.forEach(resources.resources, resource => {
40-
if (resource.type === 'cloudfunctions.v1beta2.function') {
40+
if (resource.type === 'gcp-types/cloudfunctions-v1:projects.locations.functions') {
4141
const serviceFuncName = getFunctionNameInService(
4242
resource.name,
4343
this.serverless.service.service,
@@ -53,7 +53,7 @@ module.exports = {
5353
const region = this.options.region;
5454
const project = this.serverless.service.provider.project;
5555
const baseUrl = `https://${region}-${project}.cloudfunctions.net`;
56-
const path = serviceFunc.handler; // NOTE this might change
56+
const path = serviceFunc.name; // NOTE this might change
5757
funcResource = `${baseUrl}/${path}`;
5858
}
5959

info/lib/displayServiceInfo.test.js

+12-5
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,14 @@ describe('DisplayServiceInfo', () => {
9696
const resources = {
9797
resources: [
9898
{ type: 'resource.which.should.be.filterered', name: 'someResource' },
99-
{ type: 'cloudfunctions.v1beta2.function', name: 'my-service-dev-func1' },
100-
{ type: 'cloudfunctions.v1beta2.function', name: 'my-service-dev-func2' },
99+
{
100+
type: 'gcp-types/cloudfunctions-v1:projects.locations.functions',
101+
name: 'my-service-dev-func1',
102+
},
103+
{
104+
type: 'gcp-types/cloudfunctions-v1:projects.locations.functions',
105+
name: 'my-service-dev-func2',
106+
},
101107
],
102108
};
103109

@@ -110,7 +116,7 @@ describe('DisplayServiceInfo', () => {
110116
functions: [
111117
{
112118
name: 'func1',
113-
resource: 'https://us-central1-my-project.cloudfunctions.net/handler',
119+
resource: 'https://us-central1-my-project.cloudfunctions.net/my-service-dev-func1',
114120
},
115121
{
116122
name: 'func2',
@@ -167,7 +173,7 @@ describe('DisplayServiceInfo', () => {
167173
functions: [
168174
{
169175
name: 'func1',
170-
resource: 'https://us-central1-my-project.cloudfunctions.net/handler',
176+
resource: 'https://us-central1-my-project.cloudfunctions.net/my-service-dev-func1',
171177
},
172178
{
173179
name: 'func2',
@@ -188,7 +194,8 @@ describe('DisplayServiceInfo', () => {
188194

189195
expectedOutput += `${chalk.yellow.underline('Deployed functions')}\n`;
190196
expectedOutput += `${chalk.yellow('func1')}\n`;
191-
expectedOutput += ' https://us-central1-my-project.cloudfunctions.net/handler\n';
197+
expectedOutput +=
198+
' https://us-central1-my-project.cloudfunctions.net/my-service-dev-func1\n';
192199
expectedOutput += `${chalk.yellow('func2')}\n`;
193200
expectedOutput += ' projects/*/topics/my-test-topic\n';
194201

package/lib/compileFunctions.js

+9-9
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ module.exports = {
1111
compileFunctions() {
1212
const artifactFilePath = this.serverless.service.package.artifact;
1313
const fileName = artifactFilePath.split(path.sep).pop();
14-
14+
const projectName = _.get(this, 'serverless.service.provider.project');
15+
this.serverless.service.provider.region =
16+
this.serverless.service.provider.region || 'us-central1';
1517
this.serverless.service.package.artifactFilePath = `${this.serverless.service.package.artifactDirectoryName}/${fileName}`;
1618

1719
this.serverless.service.getAllFunctions().forEach(functionName => {
@@ -25,6 +27,7 @@ module.exports = {
2527

2628
const funcTemplate = getFunctionTemplate(
2729
funcObject,
30+
projectName,
2831
this.serverless.service.provider.region,
2932
`gs://${this.serverless.service.provider.deploymentBucketName}/${this.serverless.service.package.artifactFilePath}`
3033
);
@@ -33,10 +36,6 @@ module.exports = {
3336
_.get(funcObject, 'memorySize') ||
3437
_.get(this, 'serverless.service.provider.memorySize') ||
3538
256;
36-
funcTemplate.properties.location =
37-
_.get(funcObject, 'location') ||
38-
_.get(this, 'serverless.service.provider.region') ||
39-
'us-central1';
4039
funcTemplate.properties.runtime =
4140
_.get(funcObject, 'runtime') ||
4241
_.get(this, 'serverless.service.provider.runtime') ||
@@ -150,17 +149,18 @@ const validateVpcConnectorProperty = (funcObject, functionName) => {
150149
}
151150
};
152151

153-
const getFunctionTemplate = (funcObject, region, sourceArchiveUrl) => {
152+
const getFunctionTemplate = (funcObject, projectName, region, sourceArchiveUrl) => {
154153
//eslint-disable-line
155154
return {
156-
type: 'cloudfunctions.v1beta2.function',
155+
type: 'gcp-types/cloudfunctions-v1:projects.locations.functions',
157156
name: funcObject.name,
158157
properties: {
159-
location: region,
158+
parent: `projects/${projectName}/locations/${region}`,
160159
availableMemoryMb: 256,
161160
runtime: 'nodejs8',
162161
timeout: '60s',
163-
function: funcObject.handler,
162+
entryPoint: funcObject.handler,
163+
function: funcObject.name,
164164
sourceArchiveUrl,
165165
},
166166
};

0 commit comments

Comments
 (0)