@@ -11,6 +11,8 @@ import {
1111 getCacheDeploymentsRevision ,
1212 removeDeployableRecords ,
1313 prepareDeployableDirectory ,
14+ getDeployableFileRevision ,
15+ getRandomString ,
1416} from '../deployables' ;
1517import {
1618 createOrUpdateClientFunction ,
@@ -19,14 +21,18 @@ import {
1921 deleteClientFunction ,
2022 deleteServerFunction ,
2123 deleteWebhook ,
24+ getClientFunctionById ,
2225 getClientFunctionByName ,
26+ getServerFunctionById ,
2327 getServerFunctionByName ,
28+ getWebhookById ,
2429 getWebhookByName ,
2530} from '../api' ;
31+ import { FunctionDetailsDto , WebhookHandleDto } from '../types' ;
2632
2733const DEPLOY_ORDER : DeployableTypes [ ] = [
28- 'server-function' ,
2934 'client-function' ,
35+ 'server-function' ,
3036 'webhook' ,
3137] ;
3238
@@ -105,6 +111,32 @@ const syncDeployableAndGetId = async (deployable, code) => {
105111 throw new Error ( `Unsupported deployable type: '${ deployable . type } '` ) ;
106112} ;
107113
114+ const getDeployableFromServer = async < T = FunctionDetailsDto | WebhookHandleDto > (
115+ deployable : SyncDeployment ,
116+ ) : Promise < T | null | undefined > => {
117+ try {
118+ switch ( deployable . type ) {
119+ case 'server-function' : {
120+ return deployable . id
121+ ? getServerFunctionById ( deployable . id ) as T
122+ : getServerFunctionByName ( deployable . context , deployable . name , true ) as T ;
123+ }
124+ case 'client-function' : {
125+ return deployable . id
126+ ? getClientFunctionById ( deployable . id ) as T
127+ : getClientFunctionByName ( deployable . context , deployable . name , true ) as T ;
128+ }
129+ case 'webhook' : {
130+ return deployable . id
131+ ? getWebhookById ( deployable . id ) as T
132+ : getWebhookByName ( deployable . context , deployable . name , true ) as T ;
133+ }
134+ }
135+ } catch ( err ) {
136+ return null ;
137+ }
138+ }
139+
108140const syncDeployable = async (
109141 deployable : SyncDeployment ,
110142) : Promise < Deployment > => {
@@ -149,33 +181,51 @@ export const syncDeployables = async (
149181 const previousDeployment = deployable . deployments . find (
150182 ( i ) => i . instance === instance ,
151183 ) ;
184+ // Any deployable may be deployed to multiple instances/environments at the same time
185+ // So we reduce the deployable record down to a single instance we want to deploy to
186+ const syncDeployment : SyncDeployment = {
187+ ...deployable ,
188+ ...previousDeployment , // flatten to grab name & context
189+ type : deployable . type , // but make sure we use the latest type
190+ description : deployable . description ?? deployable . types ?. description ,
191+ instance,
192+ } ;
193+ const deployed = await getDeployableFromServer ( syncDeployment ) ;
152194 const gitRevisionChanged = gitRevision !== deployable . gitRevision ;
153- const fileRevisionChanged =
154- previousDeployment ?. fileRevision !== deployable . fileRevision ;
195+ const serverFileRevision = ! deployed
196+ ? ''
197+ : type === 'webhook'
198+ // TODO: Actually calculate real revision on webhook
199+ ? getRandomString ( 8 )
200+ : ( ( deployed as FunctionDetailsDto ) . hash || getDeployableFileRevision ( ( deployed as FunctionDetailsDto ) . code ) ) ;
201+ const fileRevisionChanged = serverFileRevision !== deployable . fileRevision ;
202+ // TODO: If deployed variabnt exists AND was deployed after timestamp on previousDeployment then sync it back to the repo
155203 let action = gitRevisionChanged
156204 ? 'REMOVED'
157- : ! previousDeployment ?. id
205+ : ! previousDeployment ?. id && ! deployed
158206 ? 'ADDED'
159207 : fileRevisionChanged
160208 ? 'UPDATED'
161- : 'OK ' ;
209+ : 'SKIPPED ' ;
162210
163- if ( ! dryRun && ( gitRevisionChanged || fileRevisionChanged ) ) {
211+ if ( ! dryRun && action !== 'SKIPPED' ) {
164212 // if user is changing type, ex. server -> client function or vice versa
165213 // then try to cleanup the old type first
166214 if ( previousDeployment && deployable . type !== previousDeployment . type ) {
167215 await removeDeployable ( previousDeployment ) ;
168216 }
169- // Any deployable may be deployed to multiple instances/environments at the same time
170- // So we reduce the deployable record down to a single instance we want to deploy to
171- const syncDeployment : SyncDeployment = {
172- ...deployable ,
173- ...previousDeployment , // flatten to grab name & context
174- type : deployable . type , // but make sure we use the latest type
175- description : deployable . description ?? deployable . types ?. description ,
176- instance,
177- } ;
178- if ( gitRevision === deployable . gitRevision ) {
217+ if ( gitRevisionChanged ) {
218+ // This deployable no longer exists so let's remove it
219+ const found = await removeDeployable ( syncDeployment ) ;
220+ if ( ! found ) action = 'NOT FOUND' ;
221+ const removeIndex = allDeployables . findIndex (
222+ ( d ) =>
223+ d . name === deployable . name &&
224+ d . context === deployable . context &&
225+ d . file === deployable . file ,
226+ ) ;
227+ toRemove . push ( ...allDeployables . splice ( removeIndex , 1 ) ) ;
228+ } else {
179229 const deployment = await syncDeployable ( syncDeployment ) ;
180230 if ( previousDeployment ) {
181231 previousDeployment . id = deployment . id ;
@@ -187,17 +237,6 @@ export const syncDeployables = async (
187237 } else {
188238 deployable . deployments . unshift ( deployment ) ;
189239 }
190- } else {
191- // This deployable no longer exists so let's remove it
192- const found = await removeDeployable ( syncDeployment ) ;
193- if ( ! found ) action = 'NOT FOUND' ;
194- const removeIndex = allDeployables . findIndex (
195- ( d ) =>
196- d . name === deployable . name &&
197- d . context === deployable . context &&
198- d . file === deployable . file ,
199- ) ;
200- toRemove . push ( ...allDeployables . splice ( removeIndex , 1 ) ) ;
201240 }
202241 }
203242
0 commit comments