firevault 0.2.0-beta.0 → 0.2.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -1
- package/README.md +53 -0
- package/dist/commands/doctor.js +225 -0
- package/dist/commands/setupGithubAction.js +120 -0
- package/dist/commands/status.js +124 -0
- package/dist/git/git.js +65 -0
- package/dist/index.js +6 -0
- package/docs/architecture.md +8 -0
- package/docs/doctor-design.md +418 -0
- package/docs/github-actions-design.md +317 -0
- package/docs/roadmap.md +6 -0
- package/docs/status-design.md +218 -0
- package/package.json +4 -1
|
@@ -0,0 +1,418 @@
|
|
|
1
|
+
# firevault doctor Design
|
|
2
|
+
|
|
3
|
+
`firevault doctor` should answer:
|
|
4
|
+
|
|
5
|
+
> Is my Firevault setup correctly configured?
|
|
6
|
+
|
|
7
|
+
This is different from `firevault status`.
|
|
8
|
+
|
|
9
|
+
- `status` is the current operational state: compact, confidence-oriented, and useful for quick checks.
|
|
10
|
+
- `doctor` is validation: more detailed, actionable, and focused on fixes.
|
|
11
|
+
|
|
12
|
+
## Scope
|
|
13
|
+
|
|
14
|
+
First version: local validation only.
|
|
15
|
+
|
|
16
|
+
Doctor must not:
|
|
17
|
+
|
|
18
|
+
- contact Firebase,
|
|
19
|
+
- call GitHub APIs,
|
|
20
|
+
- use the network,
|
|
21
|
+
- write files,
|
|
22
|
+
- stage,
|
|
23
|
+
- commit,
|
|
24
|
+
- push,
|
|
25
|
+
- print secrets.
|
|
26
|
+
|
|
27
|
+
## Output Shape
|
|
28
|
+
|
|
29
|
+
Output should be grouped but still compact:
|
|
30
|
+
|
|
31
|
+
```txt
|
|
32
|
+
Firevault doctor
|
|
33
|
+
|
|
34
|
+
OK Workspace found
|
|
35
|
+
OK Config valid
|
|
36
|
+
WARN No Git remote origin configured
|
|
37
|
+
FAIL Service account file missing
|
|
38
|
+
|
|
39
|
+
Next fixes:
|
|
40
|
+
1. Save your Firebase service account JSON to .firevault/serviceAccountKey.json
|
|
41
|
+
2. Add Git remote:
|
|
42
|
+
git -C .firevault remote add origin <private-repo-url>
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Use clear severity:
|
|
46
|
+
|
|
47
|
+
- `OK`: check passed.
|
|
48
|
+
- `WARN`: setup can work locally but recovery posture is weaker.
|
|
49
|
+
- `FAIL`: setup is incomplete or unsafe enough that normal recovery workflows may fail.
|
|
50
|
+
|
|
51
|
+
Exit codes:
|
|
52
|
+
|
|
53
|
+
- `0` if all checks are `OK`.
|
|
54
|
+
- `1` if warnings are present and no checks fail.
|
|
55
|
+
- `2` if any `FAIL`.
|
|
56
|
+
|
|
57
|
+
## Checks
|
|
58
|
+
|
|
59
|
+
### Workspace
|
|
60
|
+
|
|
61
|
+
Checks:
|
|
62
|
+
|
|
63
|
+
- `.firevault/config.json` can be discovered from the current directory.
|
|
64
|
+
|
|
65
|
+
Result:
|
|
66
|
+
|
|
67
|
+
- `OK Workspace found`
|
|
68
|
+
- `FAIL Workspace not found`
|
|
69
|
+
|
|
70
|
+
Fix:
|
|
71
|
+
|
|
72
|
+
```txt
|
|
73
|
+
Run `firevault init`
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Config
|
|
77
|
+
|
|
78
|
+
Checks:
|
|
79
|
+
|
|
80
|
+
- config file exists,
|
|
81
|
+
- JSON parses,
|
|
82
|
+
- required fields are present:
|
|
83
|
+
- `projectId`,
|
|
84
|
+
- `serviceAccountPath`,
|
|
85
|
+
- `outputDir`,
|
|
86
|
+
- `collections`,
|
|
87
|
+
- `collections` is a non-empty string array.
|
|
88
|
+
|
|
89
|
+
Reuse `loadConfig()` for validation.
|
|
90
|
+
|
|
91
|
+
Result:
|
|
92
|
+
|
|
93
|
+
- `OK Config valid`
|
|
94
|
+
- `FAIL Config invalid`
|
|
95
|
+
|
|
96
|
+
Fix:
|
|
97
|
+
|
|
98
|
+
```txt
|
|
99
|
+
Edit .firevault/config.json or rerun `firevault init --force`
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Service Account File
|
|
103
|
+
|
|
104
|
+
Checks:
|
|
105
|
+
|
|
106
|
+
- configured `serviceAccountPath` resolves inside `.firevault`,
|
|
107
|
+
- file exists.
|
|
108
|
+
|
|
109
|
+
Do not parse the service account JSON in the first version. Parsing is local, but it starts pulling doctor toward credential validation. Save that for a later `--verify` mode.
|
|
110
|
+
|
|
111
|
+
Result:
|
|
112
|
+
|
|
113
|
+
- `OK Service account file present`
|
|
114
|
+
- `FAIL Service account file missing`
|
|
115
|
+
|
|
116
|
+
Fix:
|
|
117
|
+
|
|
118
|
+
```txt
|
|
119
|
+
Save your Firebase service account JSON to .firevault/serviceAccountKey.json
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Use the actual configured relative path in output. Never print file contents.
|
|
123
|
+
|
|
124
|
+
### Backup Output Directory
|
|
125
|
+
|
|
126
|
+
Checks:
|
|
127
|
+
|
|
128
|
+
- configured output directory exists, or
|
|
129
|
+
- parent workspace exists and the path could be created by normal backup flow.
|
|
130
|
+
|
|
131
|
+
Because doctor is read-only, it should not create the directory.
|
|
132
|
+
|
|
133
|
+
Result:
|
|
134
|
+
|
|
135
|
+
- `OK Backup output directory exists`
|
|
136
|
+
- `WARN Backup output directory has not been created yet`
|
|
137
|
+
- `FAIL Backup output path is unsafe or outside .firevault`
|
|
138
|
+
|
|
139
|
+
Fix:
|
|
140
|
+
|
|
141
|
+
```txt
|
|
142
|
+
Run `firevault snapshot`
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Workspace Git Repository
|
|
146
|
+
|
|
147
|
+
Checks:
|
|
148
|
+
|
|
149
|
+
- `.firevault` is a Git repository.
|
|
150
|
+
|
|
151
|
+
Result:
|
|
152
|
+
|
|
153
|
+
- `OK .firevault Git repository found`
|
|
154
|
+
- `FAIL .firevault is not a Git repository`
|
|
155
|
+
|
|
156
|
+
Fix:
|
|
157
|
+
|
|
158
|
+
```txt
|
|
159
|
+
git -C .firevault init
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Remote Origin
|
|
163
|
+
|
|
164
|
+
Checks:
|
|
165
|
+
|
|
166
|
+
- `.firevault` has `origin` configured.
|
|
167
|
+
|
|
168
|
+
Do not call `git fetch`.
|
|
169
|
+
|
|
170
|
+
Result:
|
|
171
|
+
|
|
172
|
+
- `OK Git remote origin configured`
|
|
173
|
+
- `WARN No Git remote origin configured`
|
|
174
|
+
|
|
175
|
+
Fix:
|
|
176
|
+
|
|
177
|
+
```txt
|
|
178
|
+
git -C .firevault remote add origin <private-repo-url>
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### GitHub Actions Workflow
|
|
182
|
+
|
|
183
|
+
Checks:
|
|
184
|
+
|
|
185
|
+
- `.firevault/.github/workflows/firevault-snapshot.yml` exists,
|
|
186
|
+
- contains `schedule:`,
|
|
187
|
+
- contains `workflow_dispatch:`,
|
|
188
|
+
- contains `FIREVAULT_SERVICE_ACCOUNT_JSON`,
|
|
189
|
+
- contains `firevault snapshot`.
|
|
190
|
+
|
|
191
|
+
This should remain text-based in the first version. A YAML parser is not required yet unless false positives become a problem.
|
|
192
|
+
|
|
193
|
+
Result:
|
|
194
|
+
|
|
195
|
+
- `OK GitHub Actions workflow configured`
|
|
196
|
+
- `WARN GitHub Actions workflow missing`
|
|
197
|
+
- `WARN GitHub Actions workflow missing schedule trigger`
|
|
198
|
+
- `WARN GitHub Actions workflow missing manual dispatch`
|
|
199
|
+
- `WARN GitHub Actions workflow missing FIREVAULT_SERVICE_ACCOUNT_JSON`
|
|
200
|
+
- `WARN GitHub Actions workflow missing firevault snapshot`
|
|
201
|
+
|
|
202
|
+
Fix:
|
|
203
|
+
|
|
204
|
+
```txt
|
|
205
|
+
Run `firevault setup-github-action`
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
If the file exists but is incomplete:
|
|
209
|
+
|
|
210
|
+
```txt
|
|
211
|
+
Review .firevault/.github/workflows/firevault-snapshot.yml or rerun `firevault setup-github-action --force`
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### Service Account Ignored
|
|
215
|
+
|
|
216
|
+
Checks:
|
|
217
|
+
|
|
218
|
+
- `.firevault/.gitignore` exists,
|
|
219
|
+
- configured service account path is ignored by Git.
|
|
220
|
+
|
|
221
|
+
Best check:
|
|
222
|
+
|
|
223
|
+
```bash
|
|
224
|
+
git -C .firevault check-ignore <serviceAccountPath>
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
Fallback:
|
|
228
|
+
|
|
229
|
+
- read `.firevault/.gitignore`,
|
|
230
|
+
- look for exact configured service account path or basename.
|
|
231
|
+
|
|
232
|
+
Result:
|
|
233
|
+
|
|
234
|
+
- `OK Service account file ignored`
|
|
235
|
+
- `FAIL Service account file is not ignored`
|
|
236
|
+
|
|
237
|
+
Fix:
|
|
238
|
+
|
|
239
|
+
```txt
|
|
240
|
+
Add serviceAccountKey.json to .firevault/.gitignore
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
Use configured path in output.
|
|
244
|
+
|
|
245
|
+
### Parent App Repo Ignores .firevault
|
|
246
|
+
|
|
247
|
+
Checks:
|
|
248
|
+
|
|
249
|
+
- parent app repo exists,
|
|
250
|
+
- parent app repo ignores `.firevault/`.
|
|
251
|
+
|
|
252
|
+
Best check:
|
|
253
|
+
|
|
254
|
+
```bash
|
|
255
|
+
git -C <app-root> check-ignore .firevault
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
If parent app is not a Git repo, this can be a warning rather than failure.
|
|
259
|
+
|
|
260
|
+
Result:
|
|
261
|
+
|
|
262
|
+
- `OK Parent app repo ignores .firevault/`
|
|
263
|
+
- `WARN Parent app directory is not a Git repository`
|
|
264
|
+
- `FAIL Parent app repo does not ignore .firevault/`
|
|
265
|
+
|
|
266
|
+
Fix:
|
|
267
|
+
|
|
268
|
+
```txt
|
|
269
|
+
Add .firevault/ to .gitignore
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### Secret Files Tracked By Git
|
|
273
|
+
|
|
274
|
+
Checks:
|
|
275
|
+
|
|
276
|
+
- no obvious credential or environment files are tracked in `.firevault` Git.
|
|
277
|
+
|
|
278
|
+
Candidate tracked paths:
|
|
279
|
+
|
|
280
|
+
- configured `serviceAccountPath`,
|
|
281
|
+
- `serviceAccountKey.json`,
|
|
282
|
+
- `service-account.json`,
|
|
283
|
+
- `firebase-service-account.json`,
|
|
284
|
+
- `credentials/firebase.json`,
|
|
285
|
+
- `.env`,
|
|
286
|
+
- `.env.*`,
|
|
287
|
+
- `*.pem`,
|
|
288
|
+
- `*.key`.
|
|
289
|
+
|
|
290
|
+
Use local Git only:
|
|
291
|
+
|
|
292
|
+
```bash
|
|
293
|
+
git -C .firevault ls-files
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
Result:
|
|
297
|
+
|
|
298
|
+
- `OK No obvious secret files tracked`
|
|
299
|
+
- `FAIL Possible secret files tracked`
|
|
300
|
+
|
|
301
|
+
Fix:
|
|
302
|
+
|
|
303
|
+
```txt
|
|
304
|
+
Remove tracked secret files from Git history and rotate exposed credentials.
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
Be careful not to print secret contents. Printing suspicious file paths is acceptable.
|
|
308
|
+
|
|
309
|
+
### Backup Directory Not Ignored
|
|
310
|
+
|
|
311
|
+
Checks:
|
|
312
|
+
|
|
313
|
+
- configured backup output directory is not ignored inside `.firevault`.
|
|
314
|
+
|
|
315
|
+
Use:
|
|
316
|
+
|
|
317
|
+
```bash
|
|
318
|
+
git -C .firevault check-ignore <outputDir>
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
Result:
|
|
322
|
+
|
|
323
|
+
- `OK Backup directory is trackable`
|
|
324
|
+
- `FAIL Backup directory is ignored`
|
|
325
|
+
|
|
326
|
+
Fix:
|
|
327
|
+
|
|
328
|
+
```txt
|
|
329
|
+
Remove firestore-backups/ from .firevault/.gitignore
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
Use configured path in output.
|
|
333
|
+
|
|
334
|
+
### Working Tree State
|
|
335
|
+
|
|
336
|
+
Checks:
|
|
337
|
+
|
|
338
|
+
- `.firevault` working tree clean or dirty,
|
|
339
|
+
- uncommitted backup changes under `outputDir`.
|
|
340
|
+
|
|
341
|
+
Result:
|
|
342
|
+
|
|
343
|
+
- `OK Working tree clean`
|
|
344
|
+
- `WARN Working tree has uncommitted changes`
|
|
345
|
+
- `WARN Backup output has uncommitted changes`
|
|
346
|
+
|
|
347
|
+
Fix:
|
|
348
|
+
|
|
349
|
+
```txt
|
|
350
|
+
Run `firevault commit` after reviewing changes
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
Doctor should report dirty state clearly but not treat it as a failure.
|
|
354
|
+
|
|
355
|
+
## Suggested Implementation Shape
|
|
356
|
+
|
|
357
|
+
Likely files:
|
|
358
|
+
|
|
359
|
+
- `src/commands/doctor.ts`
|
|
360
|
+
- `src/index.ts`
|
|
361
|
+
- `src/git/git.ts`
|
|
362
|
+
- `package.json`
|
|
363
|
+
- `README.md`
|
|
364
|
+
- `docs/roadmap.md`
|
|
365
|
+
- `docs/doctor-design.md`
|
|
366
|
+
|
|
367
|
+
Useful shared types:
|
|
368
|
+
|
|
369
|
+
```ts
|
|
370
|
+
type DoctorSeverity = "OK" | "WARN" | "FAIL";
|
|
371
|
+
|
|
372
|
+
interface DoctorCheck {
|
|
373
|
+
severity: DoctorSeverity;
|
|
374
|
+
label: string;
|
|
375
|
+
fix?: string;
|
|
376
|
+
}
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
Formatting should be intentionally simple:
|
|
380
|
+
|
|
381
|
+
```txt
|
|
382
|
+
OK Config valid
|
|
383
|
+
WARN No Git remote origin configured
|
|
384
|
+
FAIL Service account file missing
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
## Relationship To status
|
|
388
|
+
|
|
389
|
+
`status` should stay compact and operational.
|
|
390
|
+
|
|
391
|
+
`doctor` can be more explicit:
|
|
392
|
+
|
|
393
|
+
- reports all setup issues,
|
|
394
|
+
- lists fixes,
|
|
395
|
+
- may have more checks,
|
|
396
|
+
- can return non-zero when failures exist.
|
|
397
|
+
|
|
398
|
+
`status` should not grow into doctor.
|
|
399
|
+
|
|
400
|
+
## Future Extensions
|
|
401
|
+
|
|
402
|
+
Later versions can add:
|
|
403
|
+
|
|
404
|
+
- `firevault doctor --verify`
|
|
405
|
+
- parse service account JSON,
|
|
406
|
+
- connect to Firestore,
|
|
407
|
+
- verify configured collections exist,
|
|
408
|
+
- verify read permissions,
|
|
409
|
+
- never write to Firestore.
|
|
410
|
+
- GitHub API-backed checks:
|
|
411
|
+
- repository visibility,
|
|
412
|
+
- Actions enabled,
|
|
413
|
+
- secret exists,
|
|
414
|
+
- latest workflow run status.
|
|
415
|
+
- structured output:
|
|
416
|
+
- `firevault doctor --json`.
|
|
417
|
+
|
|
418
|
+
These should not be part of the first doctor implementation.
|
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
# GitHub Actions Automation Design
|
|
2
|
+
|
|
3
|
+
Firevault should help users create scheduled offsite Firestore snapshots using GitHub Actions.
|
|
4
|
+
|
|
5
|
+
This is Phase 2 automation awareness and setup. It should stay local and explicit.
|
|
6
|
+
|
|
7
|
+
## Goal
|
|
8
|
+
|
|
9
|
+
Enable this model:
|
|
10
|
+
|
|
11
|
+
```txt
|
|
12
|
+
my-app/
|
|
13
|
+
.firevault/
|
|
14
|
+
config.json
|
|
15
|
+
firestore-backups/
|
|
16
|
+
.git/
|
|
17
|
+
.github/workflows/firevault-snapshot.yml
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
The `.firevault` workspace is its own Git repository. Users push that repository to a private GitHub repository for offsite recovery history.
|
|
21
|
+
|
|
22
|
+
The workflow should:
|
|
23
|
+
|
|
24
|
+
1. Run on a schedule.
|
|
25
|
+
2. Install Node.
|
|
26
|
+
3. Install Firevault.
|
|
27
|
+
4. Write service account JSON from a GitHub secret.
|
|
28
|
+
5. Run `firevault snapshot`.
|
|
29
|
+
6. Push a commit only if backup files changed.
|
|
30
|
+
|
|
31
|
+
## Command Name
|
|
32
|
+
|
|
33
|
+
Recommended command:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
firevault setup-github-action
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Reasoning:
|
|
40
|
+
|
|
41
|
+
- explicit that this is GitHub-specific,
|
|
42
|
+
- clear that it creates a GitHub Actions workflow,
|
|
43
|
+
- avoids implying broader automation support,
|
|
44
|
+
- leaves room for future commands like `setup-gitlab-ci` without hiding provider-specific behavior.
|
|
45
|
+
|
|
46
|
+
`firevault setup-action` is shorter, but too generic. Firevault should avoid multi-platform abstraction until the core recovery workflow is stable.
|
|
47
|
+
|
|
48
|
+
## Workflow Location
|
|
49
|
+
|
|
50
|
+
The workflow should be written inside the `.firevault` repository:
|
|
51
|
+
|
|
52
|
+
```txt
|
|
53
|
+
.firevault/.github/workflows/firevault-snapshot.yml
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
This keeps automation with the recovery repo, not the parent application repo.
|
|
57
|
+
|
|
58
|
+
## Firevault Version In Workflow
|
|
59
|
+
|
|
60
|
+
Default recommendation:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
npm install -g firevault@next
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
For early prerelease dogfooding, `@next` matches the current publishing model and avoids silently installing an older stable line once one exists.
|
|
67
|
+
|
|
68
|
+
Later, setup can support:
|
|
69
|
+
|
|
70
|
+
- `--version exact` to pin the currently installed CLI version,
|
|
71
|
+
- `--tag next` as the default prerelease tag,
|
|
72
|
+
- `--tag latest` once Firevault has a stable release.
|
|
73
|
+
|
|
74
|
+
The generated workflow currently installs `firevault@next`.
|
|
75
|
+
|
|
76
|
+
## Secret Name
|
|
77
|
+
|
|
78
|
+
Recommended secret:
|
|
79
|
+
|
|
80
|
+
```txt
|
|
81
|
+
FIREVAULT_SERVICE_ACCOUNT_JSON
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
This name is specific enough to avoid collision with application secrets and clear enough for GitHub repository settings.
|
|
85
|
+
|
|
86
|
+
The workflow should write it to the configured service account path:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
printf '%s' "$FIREVAULT_SERVICE_ACCOUNT_JSON" > .firevault/serviceAccountKey.json
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
In GitHub Actions syntax, prefer reading from `secrets.FIREVAULT_SERVICE_ACCOUNT_JSON` into an environment variable for one step only.
|
|
93
|
+
|
|
94
|
+
## Schedule
|
|
95
|
+
|
|
96
|
+
Default schedule:
|
|
97
|
+
|
|
98
|
+
```yaml
|
|
99
|
+
on:
|
|
100
|
+
schedule:
|
|
101
|
+
- cron: "0 3 * * *"
|
|
102
|
+
workflow_dispatch:
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Daily is the right default because:
|
|
106
|
+
|
|
107
|
+
- it is simple,
|
|
108
|
+
- it limits operational cost and noise,
|
|
109
|
+
- it is enough for initial dogfooding,
|
|
110
|
+
- users can run manually through `workflow_dispatch`.
|
|
111
|
+
|
|
112
|
+
Custom cron should be supported later with:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
firevault setup-github-action --cron "0 */6 * * *"
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Do not add cron customization in the first implementation unless it stays very small.
|
|
119
|
+
|
|
120
|
+
## Setup Behavior
|
|
121
|
+
|
|
122
|
+
Phase 2 setup should create only the local workflow file and print next steps.
|
|
123
|
+
|
|
124
|
+
It should not:
|
|
125
|
+
|
|
126
|
+
- create GitHub repositories,
|
|
127
|
+
- call GitHub APIs,
|
|
128
|
+
- create or set GitHub secrets,
|
|
129
|
+
- push,
|
|
130
|
+
- stage,
|
|
131
|
+
- commit,
|
|
132
|
+
- store secrets.
|
|
133
|
+
|
|
134
|
+
After writing the workflow, print concise next steps:
|
|
135
|
+
|
|
136
|
+
```txt
|
|
137
|
+
Created .firevault/.github/workflows/firevault-snapshot.yml
|
|
138
|
+
|
|
139
|
+
Next steps:
|
|
140
|
+
1. Push .firevault to a private GitHub repository.
|
|
141
|
+
2. Add GitHub secret FIREVAULT_SERVICE_ACCOUNT_JSON with the full service account JSON.
|
|
142
|
+
3. Review and commit the workflow file yourself.
|
|
143
|
+
4. Run the workflow manually once before relying on the schedule.
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## Manual Commit Policy
|
|
147
|
+
|
|
148
|
+
Firevault should not commit the workflow automatically.
|
|
149
|
+
|
|
150
|
+
Rationale:
|
|
151
|
+
|
|
152
|
+
- this is infrastructure configuration,
|
|
153
|
+
- users must review secret handling,
|
|
154
|
+
- Firevault and AI agents must not create commits automatically,
|
|
155
|
+
- the current product posture keeps Git writes explicit.
|
|
156
|
+
|
|
157
|
+
## Secret Safety
|
|
158
|
+
|
|
159
|
+
The workflow must avoid exposing service account JSON.
|
|
160
|
+
|
|
161
|
+
Rules:
|
|
162
|
+
|
|
163
|
+
- never echo the secret,
|
|
164
|
+
- never print the generated credential file,
|
|
165
|
+
- write the secret directly to the configured service account path,
|
|
166
|
+
- ensure `.firevault/.gitignore` ignores the service account path,
|
|
167
|
+
- remove the credential file at the end of the job if practical,
|
|
168
|
+
- do not upload backup artifacts containing credentials,
|
|
169
|
+
- do not put the JSON in workflow YAML.
|
|
170
|
+
|
|
171
|
+
The setup command should validate only local file paths and text generation. It should not inspect or store the secret value.
|
|
172
|
+
|
|
173
|
+
## GitHub-Specific Without GitHub API Dependency
|
|
174
|
+
|
|
175
|
+
Keep this as a local workflow-file generator.
|
|
176
|
+
|
|
177
|
+
Provider-specific assumptions are acceptable in the generated YAML and command name, but Firevault should not depend on GitHub APIs for setup.
|
|
178
|
+
|
|
179
|
+
This means:
|
|
180
|
+
|
|
181
|
+
- no GitHub token required,
|
|
182
|
+
- no `gh` dependency,
|
|
183
|
+
- no repository creation,
|
|
184
|
+
- no secret creation,
|
|
185
|
+
- no workflow run polling.
|
|
186
|
+
|
|
187
|
+
## Push Logic
|
|
188
|
+
|
|
189
|
+
The workflow should commit and push only when backup files changed.
|
|
190
|
+
|
|
191
|
+
Sketch:
|
|
192
|
+
|
|
193
|
+
```yaml
|
|
194
|
+
- name: Run snapshot
|
|
195
|
+
run: firevault snapshot
|
|
196
|
+
|
|
197
|
+
- name: Push backup commit
|
|
198
|
+
run: |
|
|
199
|
+
if git diff --quiet origin/main..HEAD; then
|
|
200
|
+
echo "No new backup commit to push."
|
|
201
|
+
exit 0
|
|
202
|
+
fi
|
|
203
|
+
|
|
204
|
+
git push
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
Implementation should be careful here because `firevault snapshot` may create a commit only when backup files changed. The workflow needs to distinguish:
|
|
208
|
+
|
|
209
|
+
- no changes: do nothing,
|
|
210
|
+
- local backup commit created: push,
|
|
211
|
+
- command failed: fail the workflow.
|
|
212
|
+
|
|
213
|
+
The exact push check should be verified in a temporary Git repository before shipping.
|
|
214
|
+
|
|
215
|
+
## Status Detection
|
|
216
|
+
|
|
217
|
+
`firevault status` should detect Phase 2 by local file existence first:
|
|
218
|
+
|
|
219
|
+
```txt
|
|
220
|
+
.firevault/.github/workflows/firevault-snapshot.yml
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
Phase 2 status awareness can later inspect workflow text and report:
|
|
224
|
+
|
|
225
|
+
- scheduled trigger present,
|
|
226
|
+
- `workflow_dispatch` present,
|
|
227
|
+
- `firevault snapshot` present,
|
|
228
|
+
- `FIREVAULT_SERVICE_ACCOUNT_JSON` referenced,
|
|
229
|
+
- workflow installed but not validated.
|
|
230
|
+
|
|
231
|
+
No GitHub API calls should be used by `status` in Phase 2.
|
|
232
|
+
|
|
233
|
+
## Initial Workflow Shape
|
|
234
|
+
|
|
235
|
+
Draft workflow:
|
|
236
|
+
|
|
237
|
+
```yaml
|
|
238
|
+
name: Firevault snapshot
|
|
239
|
+
|
|
240
|
+
on:
|
|
241
|
+
schedule:
|
|
242
|
+
- cron: "0 3 * * *"
|
|
243
|
+
workflow_dispatch:
|
|
244
|
+
|
|
245
|
+
permissions:
|
|
246
|
+
contents: write
|
|
247
|
+
|
|
248
|
+
jobs:
|
|
249
|
+
snapshot:
|
|
250
|
+
runs-on: ubuntu-latest
|
|
251
|
+
|
|
252
|
+
steps:
|
|
253
|
+
- name: Check out recovery repository
|
|
254
|
+
uses: actions/checkout@v4
|
|
255
|
+
with:
|
|
256
|
+
path: .firevault
|
|
257
|
+
fetch-depth: 0
|
|
258
|
+
|
|
259
|
+
- name: Set up Node
|
|
260
|
+
uses: actions/setup-node@v4
|
|
261
|
+
with:
|
|
262
|
+
node-version: "22"
|
|
263
|
+
|
|
264
|
+
- name: Install Firevault
|
|
265
|
+
run: npm install -g firevault@next
|
|
266
|
+
|
|
267
|
+
- name: Write Firebase service account
|
|
268
|
+
env:
|
|
269
|
+
FIREVAULT_SERVICE_ACCOUNT_JSON: ${{ secrets.FIREVAULT_SERVICE_ACCOUNT_JSON }}
|
|
270
|
+
run: |
|
|
271
|
+
mkdir -p "$(dirname ".firevault/serviceAccountKey.json")"
|
|
272
|
+
printf '%s' "$FIREVAULT_SERVICE_ACCOUNT_JSON" > ".firevault/serviceAccountKey.json"
|
|
273
|
+
|
|
274
|
+
- name: Configure Git author
|
|
275
|
+
working-directory: .firevault
|
|
276
|
+
run: |
|
|
277
|
+
git config user.name "firevault"
|
|
278
|
+
git config user.email "firevault@users.noreply.github.com"
|
|
279
|
+
|
|
280
|
+
- name: Run snapshot
|
|
281
|
+
run: firevault snapshot
|
|
282
|
+
|
|
283
|
+
- name: Push backup commit
|
|
284
|
+
working-directory: .firevault
|
|
285
|
+
run: |
|
|
286
|
+
branch="$(git rev-parse --abbrev-ref HEAD)"
|
|
287
|
+
|
|
288
|
+
if git rev-parse --verify "origin/$branch" >/dev/null 2>&1; then
|
|
289
|
+
commits_to_push="$(git rev-list --count "origin/$branch..HEAD")"
|
|
290
|
+
|
|
291
|
+
if [ "$commits_to_push" = "0" ]; then
|
|
292
|
+
echo "No new backup commit to push."
|
|
293
|
+
exit 0
|
|
294
|
+
fi
|
|
295
|
+
fi
|
|
296
|
+
|
|
297
|
+
git push origin "HEAD:$branch"
|
|
298
|
+
|
|
299
|
+
- name: Remove service account file
|
|
300
|
+
if: always()
|
|
301
|
+
run: rm -f ".firevault/serviceAccountKey.json"
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
The implementation avoids hardcoding `main` by using `git rev-parse --abbrev-ref HEAD` in the checked-out recovery repository.
|
|
305
|
+
|
|
306
|
+
## First Implementation Files
|
|
307
|
+
|
|
308
|
+
Likely files:
|
|
309
|
+
|
|
310
|
+
- `src/commands/setupGithubAction.ts`
|
|
311
|
+
- `src/index.ts`
|
|
312
|
+
- `package.json`
|
|
313
|
+
- `README.md`
|
|
314
|
+
- `docs/roadmap.md`
|
|
315
|
+
- `docs/status-design.md`
|
|
316
|
+
|
|
317
|
+
Tests should use temporary directories and local file reads only. No Firebase emulator is required for workflow generation.
|