@invarn/cibuild 1.5.1 → 1.5.2
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../../../src/yaml/steps/cache.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAkBxD;;;;;;GAMG;AACH,MAAM,WAAW,WAAW;IAC1B,4HAA4H;IAC5H,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sHAAsH;IACtH,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,yGAAyG;IACzG,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAUrD,CAAC;AA8DF;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC;AAED;;;GAGG;AACH,qBAAa,qBAAsB,SAAQ,gBAAgB;IACnD,OAAO,CAAC,MAAM,EAAE,eAAe,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;YAsGzF,iBAAiB;
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../../../src/yaml/steps/cache.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAkBxD;;;;;;GAMG;AACH,MAAM,WAAW,WAAW;IAC1B,4HAA4H;IAC5H,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sHAAsH;IACtH,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,yGAAyG;IACzG,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAUrD,CAAC;AA8DF;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC;AAED;;;GAGG;AACH,qBAAa,qBAAsB,SAAQ,gBAAgB;IACnD,OAAO,CAAC,MAAM,EAAE,eAAe,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;YAsGzF,iBAAiB;CA2KhC;AAED;;;GAGG;AACH,qBAAa,qBAAsB,SAAQ,gBAAgB;IACnD,OAAO,CAAC,MAAM,EAAE,eAAe,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;YA4JzF,iBAAiB;CA2HhC"}
|
|
@@ -288,14 +288,23 @@ export class CachePullStepExecutor extends BaseStepExecutor {
|
|
|
288
288
|
}
|
|
289
289
|
commands.push(' if [ -n "$__ci_fb" ] && [ -f "$__ci_fb" ]; then');
|
|
290
290
|
commands.push(' __ci_fb_key=$(basename "$__ci_fb" .tar.zst)');
|
|
291
|
-
|
|
291
|
+
// Age cap: a fallback older than 30d likely carries obsolete .konan
|
|
292
|
+
// installs or Gradle entries from a pre-wrapper-bump world. Go cold
|
|
293
|
+
// rather than seed from ancient state. Exact-key hits are unaffected.
|
|
294
|
+
commands.push(' __ci_fb_age_days=$(( ($(date +%s) - $(stat -f %m "$__ci_fb")) / 86400 ))');
|
|
295
|
+
commands.push(' if [ "$__ci_fb_age_days" -le 30 ]; then');
|
|
296
|
+
commands.push(' echo "Cache fallback ($__ci_fb_src): using prior tarball $__ci_fb_key (${__ci_fb_age_days}d old)"');
|
|
292
297
|
if (isDebugMode) {
|
|
293
|
-
commands.push('
|
|
294
|
-
}
|
|
295
|
-
commands.push('
|
|
296
|
-
commands.push('
|
|
298
|
+
commands.push(' echo "Fallback size: $(du -h "$__ci_fb" | cut -f1)"');
|
|
299
|
+
}
|
|
300
|
+
commands.push(' zstd -dc "$__ci_fb" | tar -xf - -C /');
|
|
301
|
+
commands.push(' echo "CACHE_SOURCE=fallback_$__ci_fb_src CACHE_KEY=$CACHE_KEY FALLBACK_KEY=$__ci_fb_key"');
|
|
302
|
+
commands.push(' else');
|
|
303
|
+
commands.push(' echo "Cache fallback candidate $__ci_fb_key is ${__ci_fb_age_days}d old, exceeds 30d cap — going cold"');
|
|
304
|
+
commands.push(' echo "CACHE_SOURCE=cold CACHE_KEY=$CACHE_KEY FALLBACK_REJECTED=$__ci_fb_key"');
|
|
305
|
+
commands.push(' fi');
|
|
297
306
|
commands.push(' else');
|
|
298
|
-
// 4. Cold miss — no exact key, no fallback
|
|
307
|
+
// 4. Cold miss — no exact key, no fallback candidate
|
|
299
308
|
commands.push(' echo "No cache found for key: $CACHE_KEY"');
|
|
300
309
|
commands.push(' echo "CACHE_SOURCE=cold CACHE_KEY=$CACHE_KEY"');
|
|
301
310
|
commands.push(' fi');
|
|
@@ -543,6 +552,18 @@ export class CachePushStepExecutor extends BaseStepExecutor {
|
|
|
543
552
|
if (isDebugMode) {
|
|
544
553
|
commands.push(' echo "Cache size: $(du -h "$CACHE_FILE" | cut -f1)"');
|
|
545
554
|
}
|
|
555
|
+
// Retention: keep 5 newest tarballs per <keyPrefix>-<projectId> scope,
|
|
556
|
+
// delete older ones to bound disk usage. Runs inline after every push;
|
|
557
|
+
// no cron required.
|
|
558
|
+
commands.push(' __ci_ret_scope="${CACHE_KEY%-*}"');
|
|
559
|
+
commands.push(' __ci_ret_old=$(ls -t "$CACHE_DIR"/"$__ci_ret_scope"-*.tar.zst 2>/dev/null | tail -n +6)');
|
|
560
|
+
commands.push(' if [ -n "$__ci_ret_old" ]; then');
|
|
561
|
+
commands.push(' __ci_ret_count=$(printf "%s\\n" "$__ci_ret_old" | wc -l | tr -d " ")');
|
|
562
|
+
commands.push(' echo "Retention: removing $__ci_ret_count older tarball(s) from scope $__ci_ret_scope"');
|
|
563
|
+
commands.push(' printf "%s\\n" "$__ci_ret_old" | while IFS= read -r __ci_ret_f; do');
|
|
564
|
+
commands.push(' [ -f "$__ci_ret_f" ] && rm -f "$__ci_ret_f"');
|
|
565
|
+
commands.push(' done');
|
|
566
|
+
commands.push(' fi');
|
|
546
567
|
commands.push(' else');
|
|
547
568
|
commands.push(' echo "Warning: Failed to create cache file"');
|
|
548
569
|
commands.push(' fi');
|
|
@@ -259,6 +259,15 @@ describe('Step Implementations', () => {
|
|
|
259
259
|
expect(result.script).toContain('__ci_proj=$');
|
|
260
260
|
expect(result.script).toContain('CACHE_KEY="pods-${__ci_proj}-${CHECKSUM}"');
|
|
261
261
|
});
|
|
262
|
+
test('should enforce 30-day age cap on fallback, going cold when older', async () => {
|
|
263
|
+
const executor = new CachePullStepExecutor();
|
|
264
|
+
const result = await executor.execute({ technology: 'kmm' }, {}, testConfig);
|
|
265
|
+
// Computes age in days from stat mtime, rejects if over 30
|
|
266
|
+
expect(result.script).toContain('__ci_fb_age_days=$(( ($(date +%s) - $(stat -f %m "$__ci_fb")) / 86400 ))');
|
|
267
|
+
expect(result.script).toContain('if [ "$__ci_fb_age_days" -le 30 ]');
|
|
268
|
+
expect(result.script).toContain('exceeds 30d cap — going cold');
|
|
269
|
+
expect(result.script).toContain('FALLBACK_REJECTED=');
|
|
270
|
+
});
|
|
262
271
|
});
|
|
263
272
|
describe('CachePushStepExecutor', () => {
|
|
264
273
|
test('should generate cache push script', async () => {
|
|
@@ -370,6 +379,21 @@ describe('Step Implementations', () => {
|
|
|
370
379
|
expect(result.script).toContain('> "$CACHE_FILE.tmp"');
|
|
371
380
|
expect(result.script).toContain('mv "$CACHE_FILE.tmp" "$CACHE_FILE"');
|
|
372
381
|
});
|
|
382
|
+
test('should sweep retention (keep 5 newest per scope) after successful push', async () => {
|
|
383
|
+
const executor = new CachePushStepExecutor();
|
|
384
|
+
const result = await executor.execute({ technology: 'kmm' }, {}, testConfig);
|
|
385
|
+
// Scope = prefix + projectId; retention globs that scope and keeps 5 newest
|
|
386
|
+
expect(result.script).toContain('__ci_ret_scope="${CACHE_KEY%-*}"');
|
|
387
|
+
expect(result.script).toContain('ls -t "$CACHE_DIR"/"$__ci_ret_scope"-*.tar.zst');
|
|
388
|
+
expect(result.script).toContain('tail -n +6');
|
|
389
|
+
expect(result.script).toContain('rm -f "$__ci_ret_f"');
|
|
390
|
+
});
|
|
391
|
+
test('should not run retention for manual cache_key push (no scope)', async () => {
|
|
392
|
+
const executor = new CachePushStepExecutor();
|
|
393
|
+
const result = await executor.execute({ cache_key: 'my-key', cache_paths: ['build'] }, {}, testConfig);
|
|
394
|
+
expect(result.script).not.toContain('__ci_ret_scope');
|
|
395
|
+
expect(result.script).not.toContain('tail -n +6');
|
|
396
|
+
});
|
|
373
397
|
test('should use atomic write (tmp + mv) for manual cache_key push', async () => {
|
|
374
398
|
const executor = new CachePushStepExecutor();
|
|
375
399
|
const result = await executor.execute({ cache_key: 'my-key', cache_paths: ['build'] }, {}, testConfig);
|