2
2
3
3
namespace Appwrite \Platform \Modules \Functions \Http \Functions ;
4
4
5
+ use Appwrite \Event \Build ;
5
6
use Appwrite \Event \Event ;
7
+ use Appwrite \Event \Func ;
8
+ use Appwrite \Event \Realtime ;
6
9
use Appwrite \Event \Validator \FunctionEvent ;
10
+ use Appwrite \Event \Webhook ;
7
11
use Appwrite \Extend \Exception ;
8
12
use Appwrite \Platform \Modules \Compute \Base ;
9
13
use Appwrite \Platform \Modules \Compute \Validator \Specification ;
13
17
use Appwrite \Task \Validator \Cron ;
14
18
use Appwrite \Utopia \Database \Validator \CustomId ;
15
19
use Appwrite \Utopia \Response ;
20
+ use Appwrite \Utopia \Response \Model \Rule ;
16
21
use Utopia \Abuse \Abuse ;
17
22
use Utopia \Config \Config ;
18
23
use Utopia \Database \Database ;
25
30
use Utopia \Database \Validator \Roles ;
26
31
use Utopia \Platform \Action ;
27
32
use Utopia \Platform \Scope \HTTP ;
33
+ use Utopia \Request ;
28
34
use Utopia \System \System ;
29
35
use Utopia \Validator \ArrayList ;
30
36
use Utopia \Validator \Boolean ;
31
37
use Utopia \Validator \Range ;
32
38
use Utopia \Validator \Text ;
33
39
use Utopia \Validator \WhiteList ;
40
+ use Utopia \VCS \Adapter \Git \GitHub ;
34
41
35
42
class Create extends Base
36
43
{
@@ -91,12 +98,22 @@ public function __construct()
91
98
System::getEnv ('_APP_COMPUTE_CPUS ' , 0 ),
92
99
System::getEnv ('_APP_COMPUTE_MEMORY ' , 0 )
93
100
), 'Runtime specification for the function and builds. ' , true , ['plan ' ])
101
+ ->param ('templateRepository ' , '' , new Text (128 , 0 ), 'Repository name of the template. ' , true , deprecated: true )
102
+ ->param ('templateOwner ' , '' , new Text (128 , 0 ), 'The name of the owner of the template. ' , true , deprecated: true )
103
+ ->param ('templateRootDirectory ' , '' , new Text (128 , 0 ), 'Path to function code in the template repo. ' , true , deprecated: true )
104
+ ->param ('templateVersion ' , '' , new Text (128 , 0 ), 'Version (tag) for the repo linked to the function template. ' , true , deprecated: true )
94
105
->inject ('response ' )
95
106
->inject ('dbForProject ' )
96
107
->inject ('timelimit ' )
97
108
->inject ('project ' )
98
109
->inject ('queueForEvents ' )
110
+ ->inject ('queueForBuilds ' )
111
+ ->inject ('queueForRealtime ' )
112
+ ->inject ('queueForWebhooks ' )
113
+ ->inject ('queueForFunctions ' )
99
114
->inject ('dbForPlatform ' )
115
+ ->inject ('request ' )
116
+ ->inject ('gitHub ' )
100
117
->callback ([$ this , 'action ' ]);
101
118
}
102
119
@@ -119,12 +136,22 @@ public function action(
119
136
bool $ providerSilentMode ,
120
137
string $ providerRootDirectory ,
121
138
string $ specification ,
139
+ string $ templateRepository ,
140
+ string $ templateOwner ,
141
+ string $ templateRootDirectory ,
142
+ string $ templateVersion ,
122
143
Response $ response ,
123
144
Database $ dbForProject ,
124
145
callable $ timelimit ,
125
146
Document $ project ,
126
147
Event $ queueForEvents ,
127
- Database $ dbForPlatform
148
+ Build $ queueForBuilds ,
149
+ Realtime $ queueForRealtime ,
150
+ Webhook $ queueForWebhooks ,
151
+ Func $ queueForFunctions ,
152
+ Database $ dbForPlatform ,
153
+ Request $ request ,
154
+ GitHub $ github
128
155
) {
129
156
130
157
// Temporary abuse check
@@ -251,6 +278,136 @@ public function action(
251
278
252
279
$ function = $ dbForProject ->updateDocument ('functions ' , $ function ->getId (), $ function );
253
280
281
+ // Backwards compatibility with 1.6 behaviour
282
+ $ requestFormat = $ request ->getHeader ('x-appwrite-response-format ' , System::getEnv ('_APP_SYSTEM_RESPONSE_FORMAT ' , '' ));
283
+ if ($ requestFormat && version_compare ($ requestFormat , '1.7.0 ' , '< ' )) {
284
+ // build from template
285
+ $ template = new Document ([]);
286
+ if (
287
+ !empty ($ templateRepository )
288
+ && !empty ($ templateOwner )
289
+ && !empty ($ templateRootDirectory )
290
+ && !empty ($ templateVersion )
291
+ ) {
292
+ $ template ->setAttribute ('repositoryName ' , $ templateRepository )
293
+ ->setAttribute ('ownerName ' , $ templateOwner )
294
+ ->setAttribute ('rootDirectory ' , $ templateRootDirectory )
295
+ ->setAttribute ('version ' , $ templateVersion );
296
+ }
297
+
298
+ if (!empty ($ providerRepositoryId )) {
299
+ // Deploy VCS
300
+ $ template = new Document ();
301
+
302
+ $ installation = $ dbForPlatform ->getDocument ('installations ' , $ function ->getAttribute ('installationId ' ));
303
+ $ deployment = $ this ->redeployVcsFunction (
304
+ request: $ request ,
305
+ function: $ function ,
306
+ project: $ project ,
307
+ installation: $ installation ,
308
+ dbForProject: $ dbForProject ,
309
+ queueForBuilds: $ queueForBuilds ,
310
+ template: $ template ,
311
+ github: $ github ,
312
+ activate: true ,
313
+ reference: $ providerBranch ,
314
+ referenceType: 'branch '
315
+ );
316
+
317
+ $ function = $ function
318
+ ->setAttribute ('latestDeploymentId ' , $ deployment ->getId ())
319
+ ->setAttribute ('latestDeploymentInternalId ' , $ deployment ->getInternalId ())
320
+ ->setAttribute ('latestDeploymentCreatedAt ' , $ deployment ->getCreatedAt ())
321
+ ->setAttribute ('latestDeploymentStatus ' , $ deployment ->getAttribute ('status ' , '' ));
322
+ $ dbForProject ->updateDocument ('functions ' , $ function ->getId (), $ function );
323
+ } elseif (!$ template ->isEmpty ()) {
324
+ // Deploy non-VCS from template
325
+ $ deploymentId = ID ::unique ();
326
+ $ deployment = $ dbForProject ->createDocument ('deployments ' , new Document ([
327
+ '$id ' => $ deploymentId ,
328
+ '$permissions ' => [
329
+ Permission::read (Role::any ()),
330
+ Permission::update (Role::any ()),
331
+ Permission::delete (Role::any ()),
332
+ ],
333
+ 'resourceId ' => $ function ->getId (),
334
+ 'resourceInternalId ' => $ function ->getInternalId (),
335
+ 'resourceType ' => 'functions ' ,
336
+ 'entrypoint ' => $ function ->getAttribute ('entrypoint ' , '' ),
337
+ 'buildCommands ' => $ function ->getAttribute ('commands ' , '' ),
338
+ 'type ' => 'manual ' ,
339
+ 'activate ' => true ,
340
+ ]));
341
+
342
+ $ function = $ function
343
+ ->setAttribute ('latestDeploymentId ' , $ deployment ->getId ())
344
+ ->setAttribute ('latestDeploymentInternalId ' , $ deployment ->getInternalId ())
345
+ ->setAttribute ('latestDeploymentCreatedAt ' , $ deployment ->getCreatedAt ())
346
+ ->setAttribute ('latestDeploymentStatus ' , $ deployment ->getAttribute ('status ' , '' ));
347
+ $ dbForProject ->updateDocument ('functions ' , $ function ->getId (), $ function );
348
+
349
+ $ queueForBuilds
350
+ ->setType (BUILD_TYPE_DEPLOYMENT )
351
+ ->setResource ($ function )
352
+ ->setDeployment ($ deployment )
353
+ ->setTemplate ($ template );
354
+ }
355
+
356
+ $ functionsDomain = System::getEnv ('_APP_DOMAIN_FUNCTIONS ' , '' );
357
+ if (!empty ($ functionsDomain )) {
358
+ $ routeSubdomain = ID ::unique ();
359
+ $ domain = "{$ routeSubdomain }. {$ functionsDomain }" ;
360
+ // TODO: @christyjacob remove once we migrate the rules in 1.7.x
361
+ $ ruleId = System::getEnv ('_APP_RULES_FORMAT ' ) === 'md5 ' ? md5 ($ domain ) : ID ::unique ();
362
+
363
+ $ rule = Authorization::skip (
364
+ fn () => $ dbForPlatform ->createDocument ('rules ' , new Document ([
365
+ '$id ' => $ ruleId ,
366
+ 'projectId ' => $ project ->getId (),
367
+ 'projectInternalId ' => $ project ->getInternalId (),
368
+ 'domain ' => $ domain ,
369
+ 'status ' => 'verified ' ,
370
+ 'type ' => 'deployment ' ,
371
+ 'trigger ' => 'manual ' ,
372
+ 'deploymentId ' => !isset ($ deployment ) || $ deployment ->isEmpty () ? '' : $ deployment ->getId (),
373
+ 'deploymentInternalId ' => !isset ($ deployment ) || $ deployment ->isEmpty () ? '' : $ deployment ->getInternalId (),
374
+ 'deploymentResourceType ' => 'function ' ,
375
+ 'deploymentResourceId ' => $ function ->getId (),
376
+ 'deploymentResourceInternalId ' => $ function ->getInternalId (),
377
+ 'deploymentVcsProviderBranch ' => '' ,
378
+ 'certificateId ' => '' ,
379
+ 'search ' => implode (' ' , [$ ruleId , $ domain ]),
380
+ 'owner ' => 'Appwrite ' ,
381
+ 'region ' => $ project ->getAttribute ('region ' )
382
+ ]))
383
+ );
384
+
385
+ $ ruleModel = new Rule ();
386
+ $ ruleCreate =
387
+ $ queueForEvents
388
+ ->setProject ($ project )
389
+ ->setEvent ('rules.[ruleId].create ' )
390
+ ->setParam ('ruleId ' , $ rule ->getId ())
391
+ ->setPayload ($ rule ->getArrayCopy (array_keys ($ ruleModel ->getRules ())));
392
+
393
+ /** Trigger Webhook */
394
+ $ queueForWebhooks
395
+ ->from ($ ruleCreate )
396
+ ->trigger ();
397
+
398
+ /** Trigger Functions */
399
+ $ queueForFunctions
400
+ ->from ($ ruleCreate )
401
+ ->trigger ();
402
+
403
+ /** Trigger Realtime Events */
404
+ $ queueForRealtime
405
+ ->from ($ ruleCreate )
406
+ ->setSubscribers (['console ' , $ project ->getId ()])
407
+ ->trigger ();
408
+ }
409
+ }
410
+
254
411
$ queueForEvents ->setParam ('functionId ' , $ function ->getId ());
255
412
256
413
$ response
0 commit comments