-
Notifications
You must be signed in to change notification settings - Fork 205
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Annotate function triggers with __endpoint property #999
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good. My comments are more about what the contract should actually be. It's possible that this is a hint we should be sending this through API review.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left a few questions, also do you want to add a CHANGELOG entry for these changes?
}, | ||
}; | ||
copyIfPresent(endpoint.eventTrigger, opts, 'retry', 'retry'); | ||
func.__endpoint = endpoint; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We seem to be alternating between using Object.defineProperty()
and directly setting the property in the v2 providers. Would it be beneficial to stick with one format for all the providers?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have mixed feels. We could always use define property because it's safest, but it is a bit arcane and is only needed for endpoint types that rely on firebaseConfig (RTDB and Storage)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've been leaning towards "don't use defineProperty()
unless we have to. And we have to use defineProperty()
in some cases b/c user code will throw an error if environment variables like FIREBASE_CONFIG
does not exist (which we use to define a trigger, like default bucket info).
eventTrigger: { | ||
eventType: eventType, | ||
eventFilters: { | ||
bucket, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yay! So much easier to add new filters 🎆
@@ -322,9 +333,9 @@ export interface MakeCloudFunctionArgs<EventData> { | |||
dataConstructor?: (raw: Event) => EventData; | |||
eventType: string; | |||
handler?: (data: EventData, context: EventContext) => PromiseLike<any> | any; | |||
labels?: { [key: string]: any }; | |||
labels?: Record<string, string>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a risk that some projects might have non-string values here? If so, are we releasing this as a breaking change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The backend never accepted anything but a string.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So my understanding is - yes this is breaking but uses who used anything other than string would not have succeeded in deploying a function with non-string. This seems okay to do.
legacyEventType?: string; | ||
options?: { [key: string]: any }; | ||
options?: DeploymentOptions; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same question as above, what if projects don't have options
that fit into DeploymentOptions
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another good point. Fortunately, no one should be calling makeCloudFunction
directly, and in our public APIs, we make sure that passed options are typed with DeploymentOption
. e.g.
private options: DeploymentOptions |
Think we should be okay making this change.
… into dl-endpoint-prop
@@ -322,9 +333,9 @@ export interface MakeCloudFunctionArgs<EventData> { | |||
dataConstructor?: (raw: Event) => EventData; | |||
eventType: string; | |||
handler?: (data: EventData, context: EventContext) => PromiseLike<any> | any; | |||
labels?: { [key: string]: any }; | |||
labels?: Record<string, string>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The backend never accepted anything but a string.
src/cloud-functions.ts
Outdated
options, | ||
'vpc', | ||
'vpcConnectorEgressSettings', | ||
(egressSettings, vpc) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is confusing to me. Is this an edit in place as an optional second parameter? I'm wondering if a more explicit approach will be clearer since now convertIfPresent only works when the calls are in the right order.
Maybe something vaguely like:
const vpc: <whateverthetypeishere> = {};
convertIfPresent(vpc, options, 'connector', 'vpcConnector');
convertIfPresent(vpc, options, 'egressSettings', 'vpcConnectorEgressSettings');
if (Object.keys(vpc).length !== 0) {
endpoint.vpc = vpc;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's fair. I agree that the suggested code is simpler!
options, | ||
'invoker', | ||
'invoker', | ||
convertInvoker |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
doesn't convertInvoker
turn foo@
into foo@project.gserviceaccount.com
and we didn't want that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have that kind of logic for service accounts:
firebase-functions/src/common/encoding.ts
Lines 53 to 72 in 38f1946
export function serviceAccountFromShorthand( | |
serviceAccount: string | |
): string | null { | |
if (serviceAccount === 'default') { | |
return null; | |
} else if (serviceAccount.endsWith('@')) { | |
if (!process.env.GCLOUD_PROJECT) { | |
throw new Error( | |
`Unable to determine email for service account '${serviceAccount}' because process.env.GCLOUD_PROJECT is not set.` | |
); | |
} | |
return `${serviceAccount}${process.env.GCLOUD_PROJECT}.iam.gserviceaccount.com`; | |
} else if (serviceAccount.includes('@')) { | |
return serviceAccount; | |
} else { | |
throw new Error( | |
`Invalid option for serviceAccount: '${serviceAccount}'. Valid options are 'default', a service account email, or '{serviceAccountName}@'` | |
); | |
} | |
} |
But not for invoker - we only do light validation checks, e.g. to make sure that invoker option with public
or private
doesn't conflict, etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's keep the shorthand syntax in the manifest so we can stay project-independent.
}, | ||
}; | ||
copyIfPresent(endpoint.eventTrigger, opts, 'retry', 'retry'); | ||
func.__endpoint = endpoint; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have mixed feels. We could always use define property because it's safest, but it is a bit arcane and is only needed for endpoint types that rely on firebaseConfig (RTDB and Storage)
In addition to annotating function triggers with `__trigger` property, we add `__endpoint` annotation. This property will be used by the to-be-developed functions runtime to generate/declare deployment manifest that the CLI will use to deploy the function. There are lots of code duplication between the utility functions for annotating the `__trigger` and `__endpoint` properties. I didn't try to refactor the common code since I expect that we will favor `__endpoint` property in the future.
Follows up #999 to annotate each funuctions with `__endpoint` property. Highlight of changes: * Extend unit test coverage for all v1 providers * Add `__endpoint` annotation to v1 task queue functions * Add `__requiredAPIs` annotation to task queue and scheduler functions * Explicitly set `__endpoint` to undefined in the handler namespace * No SDK-level label setting in the __endpoint annotation.
* Annotate function triggers with __endpoint property (#999) In addition to annotating function triggers with `__trigger` property, we add `__endpoint` annotation. This property will be used by the to-be-developed functions runtime to generate/declare deployment manifest that the CLI will use to deploy the function. There are lots of code duplication between the utility functions for annotating the `__trigger` and `__endpoint` properties. I didn't try to refactor the common code since I expect that we will favor `__endpoint` property in the future. * Add missing import. * More of annotate endpoint property for functions (#1009) Follows up #999 to annotate each funuctions with `__endpoint` property. Highlight of changes: * Extend unit test coverage for all v1 providers * Add `__endpoint` annotation to v1 task queue functions * Add `__requiredAPIs` annotation to task queue and scheduler functions * Explicitly set `__endpoint` to undefined in the handler namespace * No SDK-level label setting in the __endpoint annotation.
In addition to annotating function triggers with
__trigger
property, we add__endpoint
annotation. This property will be used by the to-be-developed functions runtime to generate/declare deployment manifest that the CLI will use to deploy the function.There are lots of code duplication between the utility functions for annotating the
__trigger
and__endpoint
properties. I didn't try to refactor the common code since I expect that we will favor__endpoint
property in the future.