1
1
import assert , { fail } from "node:assert" ;
2
+ import { exec } from "node:child_process" ;
2
3
import type { Stats } from "node:fs" ;
3
- import { stat } from "node:fs/promises" ;
4
+ import { mkdtemp , rm , stat } from "node:fs/promises" ;
5
+ import { tmpdir } from "node:os" ;
6
+ import { join } from "node:path" ;
4
7
import { Readable , Writable } from "node:stream" ;
8
+ import { promisify } from "node:util" ;
5
9
import type { BuildManifest } from "../src/build.js" ;
6
10
import { normalizeConfig , setCurrentDate } from "../src/config.js" ;
7
11
import type { DeployEffects , DeployOptions } from "../src/deploy.js" ;
@@ -115,7 +119,9 @@ class MockDeployEffects extends MockAuthEffects implements DeployEffects {
115
119
async getDeployConfig ( sourceRoot : string , deployConfigPath ?: string ) : Promise < DeployConfig > {
116
120
const key = this . getDeployConfigKey ( sourceRoot , deployConfigPath ) ;
117
121
return (
118
- this . deployConfigs [ key ] ?? this . defaultDeployConfig ?? { projectId : null , projectSlug : null , workspaceLogin : null }
122
+ this . deployConfigs [ key ] ??
123
+ this . defaultDeployConfig ??
124
+ ( { projectId : null , projectSlug : null , workspaceLogin : null , continuousDeployment : null } satisfies DeployConfig )
119
125
) ;
120
126
}
121
127
@@ -194,11 +200,89 @@ const DEPLOY_CONFIG: DeployConfig & {projectId: string; projectSlug: string; wor
194
200
continuousDeployment : false
195
201
} ;
196
202
203
+ function mockIsolatedDirectory ( { git} : { git : boolean } ) {
204
+ let dir : string ;
205
+ let cwd : string ;
206
+ beforeEach ( async ( ) => {
207
+ cwd = process . cwd ( ) ;
208
+ dir = await mkdtemp ( join ( tmpdir ( ) , "framework-test-" ) ) ;
209
+ process . chdir ( dir ) ;
210
+ if ( git ) ( await promisify ( exec ) ( "git init" ) ) . stdout ;
211
+ } ) ;
212
+
213
+ afterEach ( async ( ) => {
214
+ process . chdir ( cwd ) ;
215
+ await rm ( dir , { recursive : true } ) ;
216
+ } ) ;
217
+ }
218
+
197
219
describe ( "deploy" , ( ) => {
198
220
before ( ( ) => setCurrentDate ( new Date ( "2024-01-10T16:00:00" ) ) ) ;
199
221
mockObservableApi ( ) ;
200
222
mockJsDelivr ( ) ;
201
223
224
+ describe ( "in isolated directory with git repo" , ( ) => {
225
+ mockIsolatedDirectory ( { git : true } ) ;
226
+
227
+ it ( "fails continuous deployment if repo has no GitHub remote" , async ( ) => {
228
+ getCurrentObservableApi ( )
229
+ . handleGetCurrentUser ( )
230
+ . handleGetWorkspaceProjects ( {
231
+ workspaceLogin : DEPLOY_CONFIG . workspaceLogin ,
232
+ projects : [ ]
233
+ } )
234
+ . handlePostProject ( { projectId : DEPLOY_CONFIG . projectId } )
235
+ . start ( ) ;
236
+ const effects = new MockDeployEffects ( ) ;
237
+ effects . clack . inputs . push (
238
+ true , // No apps found. Do you want to create a new app?
239
+ "cloud-deployed-app" , // What slug do you want to use?
240
+ "public" , // Who is allowed to access your app?
241
+ true // Do you want to enable continuous deployment?
242
+ ) ;
243
+
244
+ try {
245
+ await deploy ( TEST_OPTIONS , effects ) ;
246
+ assert . fail ( "expected error" ) ;
247
+ } catch ( error ) {
248
+ CliError . assert ( error , { message : "No GitHub remote found." } ) ;
249
+ }
250
+
251
+ effects . close ( ) ;
252
+ } ) ;
253
+ } ) ;
254
+
255
+ describe ( "in isolated directory without git repo" , ( ) => {
256
+ mockIsolatedDirectory ( { git : false } ) ;
257
+
258
+ it ( "fails continuous deployment if not in a git repo" , async ( ) => {
259
+ getCurrentObservableApi ( )
260
+ . handleGetCurrentUser ( )
261
+ . handleGetWorkspaceProjects ( {
262
+ workspaceLogin : DEPLOY_CONFIG . workspaceLogin ,
263
+ projects : [ ]
264
+ } )
265
+ . handlePostProject ( { projectId : DEPLOY_CONFIG . projectId } )
266
+ . start ( ) ;
267
+ const effects = new MockDeployEffects ( ) ;
268
+ effects . clack . inputs . push (
269
+ true , // No apps found. Do you want to create a new app?
270
+ "cloud-deployed-app" , // What slug do you want to use?
271
+ "public" , // Who is allowed to access your app?
272
+ true // Do you want to enable continuous deployment?
273
+ ) ;
274
+
275
+ try {
276
+ await deploy ( TEST_OPTIONS , effects ) ;
277
+ assert . fail ( "expected error" ) ;
278
+ } catch ( error ) {
279
+ CliError . assert ( error , { message : "Not at root of a git repository." } ) ;
280
+ }
281
+
282
+ effects . close ( ) ;
283
+ } ) ;
284
+ } ) ;
285
+
202
286
it ( "makes expected API calls for an existing project" , async ( ) => {
203
287
const deployId = "deploy456" ;
204
288
getCurrentObservableApi ( )
@@ -334,6 +418,7 @@ describe("deploy", () => {
334
418
effects . clack . inputs . push (
335
419
DEPLOY_CONFIG . projectSlug , // which project do you want to use?
336
420
true , // Do you want to continue? (and overwrite the project)
421
+ false , // Do you want to enable continuous deployment?
337
422
"change project title" // "what changed?"
338
423
) ;
339
424
await deploy ( TEST_OPTIONS , effects ) ;
@@ -887,10 +972,7 @@ describe("deploy", () => {
887
972
force : null ,
888
973
config : { ...TEST_OPTIONS . config , output : "test/output/does-not-exist" }
889
974
} satisfies DeployOptions ;
890
- getCurrentObservableApi ( )
891
- . handleGetCurrentUser ( )
892
- . handleGetProject ( DEPLOY_CONFIG )
893
- . start ( ) ;
975
+ getCurrentObservableApi ( ) . handleGetCurrentUser ( ) . handleGetProject ( DEPLOY_CONFIG ) . start ( ) ;
894
976
const effects = new MockDeployEffects ( {
895
977
deployConfig : DEPLOY_CONFIG ,
896
978
fixedInputStatTime : new Date ( "2024-03-09" ) ,
@@ -905,10 +987,7 @@ describe("deploy", () => {
905
987
...TEST_OPTIONS ,
906
988
force : null
907
989
} satisfies DeployOptions ;
908
- getCurrentObservableApi ( )
909
- . handleGetCurrentUser ( )
910
- . handleGetProject ( DEPLOY_CONFIG )
911
- . start ( ) ;
990
+ getCurrentObservableApi ( ) . handleGetCurrentUser ( ) . handleGetProject ( DEPLOY_CONFIG ) . start ( ) ;
912
991
const effects = new MockDeployEffects ( {
913
992
deployConfig : DEPLOY_CONFIG ,
914
993
fixedInputStatTime : new Date ( "2024-03-09" ) ,
@@ -926,10 +1005,7 @@ describe("deploy", () => {
926
1005
...TEST_OPTIONS ,
927
1006
force : null
928
1007
} satisfies DeployOptions ;
929
- getCurrentObservableApi ( )
930
- . handleGetCurrentUser ( )
931
- . handleGetProject ( DEPLOY_CONFIG )
932
- . start ( ) ;
1008
+ getCurrentObservableApi ( ) . handleGetCurrentUser ( ) . handleGetProject ( DEPLOY_CONFIG ) . start ( ) ;
933
1009
const effects = new MockDeployEffects ( {
934
1010
deployConfig : DEPLOY_CONFIG ,
935
1011
fixedInputStatTime : new Date ( "2024-03-11" ) ,
@@ -947,10 +1023,7 @@ describe("deploy", () => {
947
1023
...TEST_OPTIONS ,
948
1024
force : "build"
949
1025
} satisfies DeployOptions ;
950
- getCurrentObservableApi ( )
951
- . handleGetCurrentUser ( )
952
- . handleGetProject ( DEPLOY_CONFIG )
953
- . start ( ) ;
1026
+ getCurrentObservableApi ( ) . handleGetCurrentUser ( ) . handleGetProject ( DEPLOY_CONFIG ) . start ( ) ;
954
1027
const effects = new MockDeployEffects ( {
955
1028
deployConfig : DEPLOY_CONFIG ,
956
1029
fixedInputStatTime : new Date ( "2024-03-09" ) ,
0 commit comments