-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathdeploy.config.ts
More file actions
127 lines (124 loc) · 3.98 KB
/
Copy pathdeploy.config.ts
File metadata and controls
127 lines (124 loc) · 3.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
import { defineDeployManifest } from '@vers/scripts';
import { z } from 'zod';
const rpcUnauthorizedBody = z.object({
code: z.literal('UNAUTHORIZED'),
data: z.object({ reason: z.literal('missing-session') }),
defined: z.literal(true),
});
const rpcUnauthorizedReply = z.object({
json: rpcUnauthorizedBody,
});
/**
* Fleet manifest for the deploy CLI (`bun run deploy`): which Fly apps exist,
* what makes each one stale, and how a deploy is verified. Staleness compares
* HEAD against the `GIT_SHA` each deploy stamps into machine env, so a
* skipped or cancelled rollout self-heals on the next push. The anonymous RPC
* probe must round-trip the contract's typed UNAUTHORIZED through
* app-web → flycast → service-user, which no /health check can see.
*/
export default defineDeployManifest({
apps: [
{
app: 'vers-service-activity',
configDir: 'services/activity',
dockerfile: 'services/activity/Dockerfile',
exposure: 'flycast',
trigger: { kind: 'turbo-affected', pkg: '@vers/service-activity' },
},
{
app: 'vers-service-avatar',
configDir: 'services/avatar',
dockerfile: 'services/avatar/Dockerfile',
exposure: 'flycast',
trigger: { kind: 'turbo-affected', pkg: '@vers/service-avatar' },
},
{
app: 'vers-service-email',
configDir: 'services/email',
dockerfile: 'services/email/Dockerfile',
exposure: 'flycast',
scheduledMachines: [
{
command: ['/usr/local/bin/sweep'],
name: 'email-sweeper',
region: 'syd',
schedule: 'hourly',
},
],
trigger: { kind: 'turbo-affected', pkg: '@vers/service-email' },
},
{
app: 'vers-service-keys',
configDir: 'services/keys',
dockerfile: 'services/keys/Dockerfile',
exposure: 'flycast',
trigger: { kind: 'turbo-affected', pkg: '@vers/service-keys' },
},
{
app: 'vers-service-session',
configDir: 'services/session',
dockerfile: 'services/session/Dockerfile',
exposure: 'flycast',
trigger: { kind: 'turbo-affected', pkg: '@vers/service-session' },
},
{
app: 'vers-service-user',
configDir: 'services/user',
dockerfile: 'services/user/Dockerfile',
exposure: 'flycast',
trigger: { kind: 'turbo-affected', pkg: '@vers/service-user' },
},
{
app: 'vers-service-verification',
configDir: 'services/verification',
dockerfile: 'services/verification/Dockerfile',
exposure: 'flycast',
trigger: { kind: 'turbo-affected', pkg: '@vers/service-verification' },
},
{
app: 'vers-service-replay',
buildArgsFromEnv: ['SIM_ENGINE_HASH', 'BUN_VERSION'],
configDir: 'services/replay',
dockerfile: 'services/replay/Dockerfile',
exposure: 'flycast',
simVersionProvider: { region: 'syd' },
trigger: { kind: 'turbo-affected', pkg: '@vers/service-replay' },
},
{
app: 'vers-app-web',
buildArgsFromEnv: [
'SENTRY_AUTH_TOKEN',
'VITE_SENTRY_DSN',
'VITE_SIM_ENGINE_HASH',
'VITE_UMAMI_WEBSITE_ID',
],
configDir: 'apps/web',
dockerfile: 'apps/web/Dockerfile',
exposure: 'public',
minStartedMachines: 1,
probes: [
{ expectStatus: 200, kind: 'http', url: 'https://vers-app-web.fly.dev/health' },
{
body: { json: {} },
expect: (body) => rpcUnauthorizedReply.safeParse(body).success,
kind: 'json-post',
url: 'https://vers-app-web.fly.dev/api/rpc/user/getCurrentUser',
},
],
trigger: { kind: 'turbo-affected', pkg: '@vers/web' },
},
{
app: 'vers-bugsink',
configDir: 'apps/bugsink',
dockerfile: 'apps/bugsink/Dockerfile',
exposure: 'public',
trigger: { globs: ['apps/bugsink/**'], kind: 'paths' },
},
{
app: 'vers-umami',
configDir: 'apps/umami',
exposure: 'public',
trigger: { globs: ['apps/umami/**'], kind: 'paths' },
},
],
});