@invarn/cibuild 2.5.5 → 2.5.8
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/dist/cli.cjs +10 -10
- package/dist/src/commands/build.d.ts +13 -2
- package/dist/src/commands/build.d.ts.map +1 -1
- package/dist/src/commands/build.js +32 -6
- package/dist/src/commands/build.test.js +62 -0
- package/dist/src/shared/git.d.ts +25 -0
- package/dist/src/shared/git.d.ts.map +1 -0
- package/dist/src/shared/git.js +53 -0
- package/dist/src/shared/git.test.d.ts +9 -0
- package/dist/src/shared/git.test.d.ts.map +1 -0
- package/dist/src/shared/git.test.js +66 -0
- package/dist/src/yaml/steps/cache.d.ts.map +1 -1
- package/dist/src/yaml/steps/cache.js +124 -32
- package/dist/src/yaml/steps/steps.test.js +60 -12
- package/dist/src/yaml/types.d.ts +6 -0
- package/dist/src/yaml/types.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -326,10 +326,26 @@ describe('Step Implementations', () => {
|
|
|
326
326
|
expect(result.script).toContain('ls -t "$CACHE_DIR"/"$__ci_fb_scope"-*.tar.zst');
|
|
327
327
|
expect(result.script).toContain('CACHE_SOURCE=fallback_');
|
|
328
328
|
expect(result.script).toContain('FALLBACK_KEY=');
|
|
329
|
-
// Fallback must NOT warm $CACHE_FILE (otherwise cache-push would skip)
|
|
330
|
-
|
|
329
|
+
// Fallback must NOT warm $CACHE_FILE (otherwise cache-push would skip).
|
|
330
|
+
// Both transports declare a scope, so anchor on the last one — the
|
|
331
|
+
// filesystem branch, which is the only one with a $CACHE_FILE to warm.
|
|
332
|
+
const sections = result.script.split('__ci_fb_scope=');
|
|
333
|
+
const fallbackSection = sections[sections.length - 1] ?? '';
|
|
331
334
|
expect(fallbackSection).not.toContain('mv "$CACHE_FILE.tmp" "$CACHE_FILE"');
|
|
332
335
|
});
|
|
336
|
+
test('asks the daemon for the scope fallback, dated, when there is no shared dir', async () => {
|
|
337
|
+
const executor = new CachePullStepExecutor();
|
|
338
|
+
const result = await executor.execute({ technology: 'kmm' }, {}, testConfig);
|
|
339
|
+
// The daemon answers the same two questions the directory listing did:
|
|
340
|
+
// which key, and how old.
|
|
341
|
+
expect(result.script).toContain('"$CIBUILD_CACHE_DAEMON/cache/scope/$__ci_fb_scope/latest"');
|
|
342
|
+
expect(result.script).toContain('CACHE_SOURCE=fallback_daemon');
|
|
343
|
+
// The 30-day cap has to survive losing `stat`, so it reads the daemon's
|
|
344
|
+
// mtime instead. Without this the cap silently disappears.
|
|
345
|
+
expect(result.script).toContain('__ci_fb_mtime');
|
|
346
|
+
expect(result.script).toContain('-le 30');
|
|
347
|
+
expect(result.script).toContain('FALLBACK_REJECTED=');
|
|
348
|
+
});
|
|
333
349
|
test('should try peer dir for fallback when local has no prior tarball', async () => {
|
|
334
350
|
const executor = new CachePullStepExecutor();
|
|
335
351
|
const result = await executor.execute({ technology: 'kmm' }, {}, testConfig);
|
|
@@ -386,22 +402,36 @@ describe('Step Implementations', () => {
|
|
|
386
402
|
// unauthenticated daemon isn't sent a bogus "Bearer " header.
|
|
387
403
|
expect(result.script).toContain('${CIBUILD_CACHE_TOKEN:+-H "Authorization: Bearer $CIBUILD_CACHE_TOKEN"}');
|
|
388
404
|
});
|
|
389
|
-
test('
|
|
405
|
+
test('picks its transport up front — daemon when configured, directory otherwise', async () => {
|
|
390
406
|
const executor = new CachePullStepExecutor();
|
|
391
407
|
const result = await executor.execute({ technology: 'kmm' }, {}, testConfig);
|
|
392
|
-
|
|
408
|
+
// The daemon is no longer a branch *within* the directory search; it is
|
|
409
|
+
// the alternative to it, chosen before any lookup happens. A runner has
|
|
410
|
+
// no cache directory to search once the mount is gone, and standalone
|
|
411
|
+
// cibuild has no daemon — the same script has to serve both.
|
|
412
|
+
const splitAt = result.script.indexOf('if [ -n "$CIBUILD_CACHE_DAEMON" ]; then');
|
|
393
413
|
const daemonAt = result.script.indexOf('CACHE_SOURCE=daemon');
|
|
394
|
-
const
|
|
395
|
-
expect(
|
|
396
|
-
expect(daemonAt).toBeGreaterThan(
|
|
397
|
-
expect(
|
|
414
|
+
const localAt = result.script.indexOf('CACHE_SOURCE=local');
|
|
415
|
+
expect(splitAt).toBeGreaterThanOrEqual(0);
|
|
416
|
+
expect(daemonAt).toBeGreaterThan(splitAt);
|
|
417
|
+
expect(localAt).toBeGreaterThan(daemonAt);
|
|
418
|
+
});
|
|
419
|
+
test('does not require the cache directory to exist when using the daemon', async () => {
|
|
420
|
+
const executor = new CachePullStepExecutor();
|
|
421
|
+
const result = await executor.execute({ technology: 'kmm' }, {}, testConfig);
|
|
422
|
+
// An unconditional mkdir aborts the step under errexit once the mount is
|
|
423
|
+
// gone, which is how this fails in production rather than in a test.
|
|
424
|
+
expect(result.script).toContain('[ -n "$CIBUILD_CACHE_DAEMON" ] || mkdir -p "$CACHE_DIR"');
|
|
425
|
+
expect(result.script).not.toContain('\nmkdir -p "$CACHE_DIR"');
|
|
398
426
|
});
|
|
399
427
|
test('routes a manual cache_key pull miss through the cache daemon', async () => {
|
|
400
428
|
const executor = new CachePullStepExecutor();
|
|
401
429
|
const result = await executor.execute({ cache_key: 'my-key' }, {}, testConfig);
|
|
402
430
|
expect(result.script).toContain('[ -n "$CIBUILD_CACHE_DAEMON" ]');
|
|
403
431
|
expect(result.script).toContain('"$CIBUILD_CACHE_DAEMON/cache/$CACHE_KEY.tar.zst"');
|
|
404
|
-
|
|
432
|
+
// An explicit-key step reports the bare source, matching its sibling
|
|
433
|
+
// markers; the key is already fixed and echoed by the step header.
|
|
434
|
+
expect(result.script).toContain('CACHE_SOURCE=daemon');
|
|
405
435
|
});
|
|
406
436
|
});
|
|
407
437
|
describe('CachePushStepExecutor', () => {
|
|
@@ -418,15 +448,33 @@ describe('Step Implementations', () => {
|
|
|
418
448
|
expect(result.script).toContain('node-modules-v1');
|
|
419
449
|
expect(result.script).toContain('.ci-cache');
|
|
420
450
|
});
|
|
421
|
-
test('
|
|
451
|
+
test('uploads to the daemon when one is configured, on both step forms', async () => {
|
|
422
452
|
const executor = new CachePushStepExecutor();
|
|
423
453
|
const manual = await executor.execute({ cache_key: 'my-key', cache_paths: ['build'] }, {}, testConfig);
|
|
424
454
|
const preset = await executor.execute({ technology: 'kmm' }, {}, testConfig);
|
|
455
|
+
// This is the half that used to be missing: push wrote only to the
|
|
456
|
+
// shared directory, so removing the mount would have silently dropped
|
|
457
|
+
// every cache while still reporting success.
|
|
425
458
|
for (const result of [manual, preset]) {
|
|
426
|
-
expect(result.script).
|
|
427
|
-
expect(result.script).
|
|
459
|
+
expect(result.script).toContain('-T - "$CIBUILD_CACHE_DAEMON/cache/$CACHE_KEY.tar.zst"');
|
|
460
|
+
expect(result.script).toContain('${CIBUILD_CACHE_TOKEN:+-H "Authorization: Bearer $CIBUILD_CACHE_TOKEN"}');
|
|
461
|
+
// Streamed straight out — nothing is staged on the guest, so there is
|
|
462
|
+
// no temp file to collide with a concurrent slot or orphan on failure.
|
|
463
|
+
expect(result.script).toContain('| zstd -3 | curl');
|
|
428
464
|
}
|
|
429
465
|
});
|
|
466
|
+
test('a failed upload warns instead of failing the build', async () => {
|
|
467
|
+
const executor = new CachePushStepExecutor();
|
|
468
|
+
const result = await executor.execute({ technology: 'kmm' }, {}, testConfig);
|
|
469
|
+
expect(result.script).toContain('Warning: failed to upload cache to the daemon');
|
|
470
|
+
});
|
|
471
|
+
test('still writes to the cache directory when no daemon is configured', async () => {
|
|
472
|
+
const executor = new CachePushStepExecutor();
|
|
473
|
+
const result = await executor.execute({ technology: 'kmm' }, {}, testConfig);
|
|
474
|
+
// Standalone cibuild has no daemon and must keep working unchanged.
|
|
475
|
+
expect(result.script).toContain('CACHE_TMP="$CACHE_FILE.$$.$RANDOM.tmp"');
|
|
476
|
+
expect(result.script).toContain('mv "$CACHE_TMP" "$CACHE_FILE"');
|
|
477
|
+
});
|
|
430
478
|
test('should skip gracefully when cache_key is missing', async () => {
|
|
431
479
|
const executor = new CachePushStepExecutor();
|
|
432
480
|
const inputs = {
|
package/dist/src/yaml/types.d.ts
CHANGED
|
@@ -42,6 +42,12 @@ export interface YAMLApp {
|
|
|
42
42
|
export interface YAMLTrigger {
|
|
43
43
|
push_branch?: string;
|
|
44
44
|
pull_request_source_branch?: string;
|
|
45
|
+
/**
|
|
46
|
+
* The branch a pull request is opened *against*. Matched by Invarn's
|
|
47
|
+
* trigger resolver alongside the source branch, and what the generated
|
|
48
|
+
* scaffold uses — a `"*"` here means "any pull request".
|
|
49
|
+
*/
|
|
50
|
+
pull_request_target_branch?: string;
|
|
45
51
|
workflow?: string;
|
|
46
52
|
}
|
|
47
53
|
export interface YAMLPipeline {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/yaml/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,OAAO,CAAC;AACzC,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG,aAAa,CAAC;AAGrD,MAAM,WAAW,UAAU;IACzB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;CACvB;AAGD,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,WAAW,CAAC;IAC3B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,KAAK,GAAG,SAAS,GAAG,KAAK,GAAG,OAAO,CAAC;IAC/C,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,QAAQ;IACvB,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,YAAY,CAAC,EAAE,eAAe,CAAC;IAC/B,YAAY,CAAC,EAAE,eAAe,CAAC;IAC/B,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB;AAGD,MAAM,WAAW,cAAc;IAC7B,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAGD,MAAM,WAAW,QAAQ;IACvB,CAAC,mBAAmB,EAAE,MAAM,GAAG;QAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,cAAc,CAAC;QACxB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,aAAa,CAAC,EAAE,OAAO,CAAC;QACxB,YAAY,CAAC,EAAE,OAAO,CAAC;KACxB,CAAC;CACH;AAGD,MAAM,WAAW,YAAY;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,UAAU,EAAE,CAAC;IACpB,KAAK,EAAE,QAAQ,EAAE,CAAC;CACnB;AAGD,MAAM,WAAW,OAAO;IACtB,IAAI,CAAC,EAAE,UAAU,EAAE,CAAC;CACrB;AAGD,MAAM,WAAW,WAAW;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0BAA0B,CAAC,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAGD,MAAM,WAAW,YAAY;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,SAAS,EAAE;QAAE,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAAA;KAAE,CAAC;IAC5C,WAAW,CAAC,EAAE,WAAW,EAAE,CAAC;CAC7B;AAGD,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,cAAc,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAGD,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,QAAQ,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/yaml/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,OAAO,CAAC;AACzC,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG,aAAa,CAAC;AAGrD,MAAM,WAAW,UAAU;IACzB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;CACvB;AAGD,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,WAAW,CAAC;IAC3B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,KAAK,GAAG,SAAS,GAAG,KAAK,GAAG,OAAO,CAAC;IAC/C,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,QAAQ;IACvB,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,YAAY,CAAC,EAAE,eAAe,CAAC;IAC/B,YAAY,CAAC,EAAE,eAAe,CAAC;IAC/B,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB;AAGD,MAAM,WAAW,cAAc;IAC7B,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAGD,MAAM,WAAW,QAAQ;IACvB,CAAC,mBAAmB,EAAE,MAAM,GAAG;QAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,cAAc,CAAC;QACxB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,aAAa,CAAC,EAAE,OAAO,CAAC;QACxB,YAAY,CAAC,EAAE,OAAO,CAAC;KACxB,CAAC;CACH;AAGD,MAAM,WAAW,YAAY;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,UAAU,EAAE,CAAC;IACpB,KAAK,EAAE,QAAQ,EAAE,CAAC;CACnB;AAGD,MAAM,WAAW,OAAO;IACtB,IAAI,CAAC,EAAE,UAAU,EAAE,CAAC;CACrB;AAGD,MAAM,WAAW,WAAW;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0BAA0B,CAAC,EAAE,MAAM,CAAC;IACpC;;;;OAIG;IACH,0BAA0B,CAAC,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAGD,MAAM,WAAW,YAAY;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,SAAS,EAAE;QAAE,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAAA;KAAE,CAAC;IAC5C,WAAW,CAAC,EAAE,WAAW,EAAE,CAAC;CAC7B;AAGD,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,cAAc,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAGD,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,QAAQ,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B"}
|