1
- import { docker } from "@dokploy/server/constants" ;
1
+ import { docker , paths } from "@dokploy/server/constants" ;
2
2
import { db } from "@dokploy/server/db" ;
3
3
import {
4
4
type apiCreateApplication ,
@@ -13,7 +13,7 @@ import {
13
13
} from "@dokploy/server/utils/builders" ;
14
14
import { sendBuildErrorNotifications } from "@dokploy/server/utils/notifications/build-error" ;
15
15
import { sendBuildSuccessNotifications } from "@dokploy/server/utils/notifications/build-success" ;
16
- import { execAsyncRemote } from "@dokploy/server/utils/process/execAsync" ;
16
+ import { execAsync , execAsyncRemote } from "@dokploy/server/utils/process/execAsync" ;
17
17
import {
18
18
cloneBitbucketRepository ,
19
19
getBitbucketCloneCommand ,
@@ -46,8 +46,10 @@ import { getDokployUrl } from "./admin";
46
46
import {
47
47
createDeployment ,
48
48
createDeploymentPreview ,
49
+ updateDeployment ,
49
50
updateDeploymentStatus ,
50
51
} from "./deployment" ;
52
+ import { join } from "node:path" ;
51
53
import { type Domain , getDomainHost } from "./domain" ;
52
54
import {
53
55
createPreviewDeploymentComment ,
@@ -63,6 +65,80 @@ import { validUniqueServerAppName } from "./project";
63
65
import { createRollback } from "./rollbacks" ;
64
66
export type Application = typeof applications . $inferSelect ;
65
67
68
+ const tryUpdateWithGitInfoLocal = async (
69
+ application : Application & { appName : string ; env : string | null } ,
70
+ deploymentId : string ,
71
+ defaultTitle : string ,
72
+ defaultDescription : string ,
73
+ ) => {
74
+ try {
75
+ const { APPLICATIONS_PATH } = paths ( ) ;
76
+ const codePath = join ( APPLICATIONS_PATH , application . appName , "code" ) ;
77
+ const { stdout : hashStdout } = await execAsync (
78
+ `git -C ${ codePath } rev-parse HEAD` ,
79
+ ) ;
80
+ const gitHash = hashStdout . trim ( ) ;
81
+ const { stdout : msgStdout } = await execAsync (
82
+ `git -C ${ codePath } log -1 --pretty=%B` ,
83
+ ) ;
84
+ const gitMessage = msgStdout . trim ( ) ;
85
+ if ( gitHash ) {
86
+ const current = application . env || "" ;
87
+ const withoutOld = current
88
+ . split ( "\n" )
89
+ . filter ( ( l ) => l . trim ( ) && ! l . startsWith ( "GIT_HASH=" ) )
90
+ . join ( "\n" ) ;
91
+ const newEnv = `${ withoutOld } ${ withoutOld ? "\n" : "" } GIT_HASH=${ gitHash } ` ;
92
+ application . env = newEnv ;
93
+ await updateApplication ( application . applicationId , { env : newEnv } ) ;
94
+ }
95
+ await updateDeployment ( deploymentId , {
96
+ title : gitMessage || defaultTitle ,
97
+ description : gitHash ? `Hash: ${ gitHash } ` : defaultDescription ,
98
+ } ) ;
99
+ } catch {
100
+ // ignore if git data can't be fetched
101
+ }
102
+ } ;
103
+
104
+ const tryUpdateWithGitInfoRemote = async (
105
+ application : Application & { appName : string ; env : string | null ; serverId : string } ,
106
+ deploymentId : string ,
107
+ defaultTitle : string ,
108
+ defaultDescription : string ,
109
+ ) => {
110
+ try {
111
+ const { APPLICATIONS_PATH } = paths ( true ) ;
112
+ const codePath = join ( APPLICATIONS_PATH , application . appName , "code" ) ;
113
+ const { stdout : hashStdout } = await execAsyncRemote (
114
+ application . serverId ,
115
+ `git -C ${ codePath } rev-parse HEAD | tr -d '\n'` ,
116
+ ) ;
117
+ const gitHash = ( hashStdout || "" ) . trim ( ) ;
118
+ const { stdout : msgStdout } = await execAsyncRemote (
119
+ application . serverId ,
120
+ `git -C ${ codePath } log -1 --pretty=%B` ,
121
+ ) ;
122
+ const gitMessage = ( msgStdout || "" ) . trim ( ) ;
123
+ if ( gitHash ) {
124
+ const current = application . env || "" ;
125
+ const withoutOld = current
126
+ . split ( "\n" )
127
+ . filter ( ( l ) => l . trim ( ) && ! l . startsWith ( "GIT_HASH=" ) )
128
+ . join ( "\n" ) ;
129
+ const newEnv = `${ withoutOld } ${ withoutOld ? "\n" : "" } GIT_HASH=${ gitHash } ` ;
130
+ application . env = newEnv ;
131
+ await updateApplication ( application . applicationId , { env : newEnv } ) ;
132
+ }
133
+ await updateDeployment ( deploymentId , {
134
+ title : gitMessage || defaultTitle ,
135
+ description : gitHash ? `Hash: ${ gitHash } ` : defaultDescription ,
136
+ } ) ;
137
+ } catch {
138
+ // ignore if git data can't be fetched
139
+ }
140
+ } ;
141
+
66
142
export const createApplication = async (
67
143
input : typeof apiCreateApplication . _type ,
68
144
) => {
@@ -197,20 +273,50 @@ export const deployApplication = async ({
197
273
...application ,
198
274
logPath : deployment . logPath ,
199
275
} ) ;
276
+ await tryUpdateWithGitInfoLocal (
277
+ application as any ,
278
+ deployment . deploymentId ,
279
+ titleLog ,
280
+ descriptionLog ,
281
+ ) ;
200
282
await buildApplication ( application , deployment . logPath ) ;
201
283
} else if ( application . sourceType === "gitlab" ) {
202
284
await cloneGitlabRepository ( application , deployment . logPath ) ;
285
+ await tryUpdateWithGitInfoLocal (
286
+ application as any ,
287
+ deployment . deploymentId ,
288
+ titleLog ,
289
+ descriptionLog ,
290
+ ) ;
203
291
await buildApplication ( application , deployment . logPath ) ;
204
292
} else if ( application . sourceType === "gitea" ) {
205
293
await cloneGiteaRepository ( application , deployment . logPath ) ;
294
+ await tryUpdateWithGitInfoLocal (
295
+ application as any ,
296
+ deployment . deploymentId ,
297
+ titleLog ,
298
+ descriptionLog ,
299
+ ) ;
206
300
await buildApplication ( application , deployment . logPath ) ;
207
301
} else if ( application . sourceType === "bitbucket" ) {
208
302
await cloneBitbucketRepository ( application , deployment . logPath ) ;
303
+ await tryUpdateWithGitInfoLocal (
304
+ application as any ,
305
+ deployment . deploymentId ,
306
+ titleLog ,
307
+ descriptionLog ,
308
+ ) ;
209
309
await buildApplication ( application , deployment . logPath ) ;
210
310
} else if ( application . sourceType === "docker" ) {
211
311
await buildDocker ( application , deployment . logPath ) ;
212
312
} else if ( application . sourceType === "git" ) {
213
313
await cloneGitRepository ( application , deployment . logPath ) ;
314
+ await tryUpdateWithGitInfoLocal (
315
+ application as any ,
316
+ deployment . deploymentId ,
317
+ titleLog ,
318
+ descriptionLog ,
319
+ ) ;
214
320
await buildApplication ( application , deployment . logPath ) ;
215
321
} else if ( application . sourceType === "drop" ) {
216
322
await buildApplication ( application , deployment . logPath ) ;
@@ -349,6 +455,12 @@ export const deployRemoteApplication = async ({
349
455
command += getBuildCommand ( application , deployment . logPath ) ;
350
456
}
351
457
await execAsyncRemote ( application . serverId , command ) ;
458
+ await tryUpdateWithGitInfoRemote (
459
+ application as any ,
460
+ deployment . deploymentId ,
461
+ titleLog ,
462
+ descriptionLog ,
463
+ ) ;
352
464
await mechanizeDockerContainer ( application ) ;
353
465
}
354
466
0 commit comments