@invarn/cibuild 1.9.8 → 1.9.9

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;AAmFF;;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;YA0GzF,iBAAiB;CAqMhC;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;YAgKzF,iBAAiB;CAmIhC"}
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;AAwFF;;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;YA0GzF,iBAAiB;CAqMhC;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;YAgKzF,iBAAiB;CAmIhC"}
@@ -97,7 +97,12 @@ function resolvePresetChain(technology) {
97
97
  */
98
98
  function emitDaemonPullBranch() {
99
99
  return [
100
- 'elif [ -n "$CIBUILD_CACHE_DAEMON" ] && curl -fsS ${CIBUILD_CACHE_TOKEN:+-H "Authorization: Bearer $CIBUILD_CACHE_TOKEN"} "$CIBUILD_CACHE_DAEMON/cache/$CACHE_KEY.tar.zst" | zstd -dc | tar -xf - -C /; then',
100
+ // stderr is silenced on the probe: a cache miss is the normal case and
101
+ // makes curl emit "(22) ... 404" (and the empty body makes zstd print
102
+ // "unexpected end of file"). Those are non-actionable — the branch just
103
+ // falls through to the cold path — so they're pure log noise. Exit
104
+ // status is preserved (pipefail), so the fall-through still works.
105
+ 'elif [ -n "$CIBUILD_CACHE_DAEMON" ] && { curl -fsS ${CIBUILD_CACHE_TOKEN:+-H "Authorization: Bearer $CIBUILD_CACHE_TOKEN"} "$CIBUILD_CACHE_DAEMON/cache/$CACHE_KEY.tar.zst" | zstd -dc | tar -xf - -C /; } 2>/dev/null; then',
101
106
  ' echo "Cache found (daemon), extracting..."',
102
107
  // LRU bump the tarball the daemon just persisted to ~/cache (same dir as
103
108
  // the --dir mount); tolerate its absence in case the daemon served it
@@ -175,39 +175,70 @@ describe('Step Implementations', () => {
175
175
  // Package.resolved either way). So actually execute the generated
176
176
  // key-derivation in a fixture repo and read the resolved key back.
177
177
  describe('ios fallback chain (executed in a fixture repo)', () => {
178
- async function resolveIosCacheKey(build) {
178
+ // Run the generated ios cache-pull in a fixture repo and capture
179
+ // BOTH streams (the daemon probe writes its noise to stderr).
180
+ async function runIosPull(build, env = {}) {
179
181
  const script = (await new CachePullStepExecutor().execute({ technology: 'ios' }, {}, testConfigNoPeer)).script;
180
182
  const dir = mkdtempSync(join(tmpdir(), 'cibuild-cache-'));
181
183
  try {
182
184
  build(dir);
183
185
  const scriptPath = join(dir, '__cache_pull.sh');
184
186
  writeFileSync(scriptPath, script);
185
- let out = '';
187
+ let stdout = '';
188
+ let stderr = '';
186
189
  try {
187
- out = execFileSync('bash', [scriptPath], {
190
+ stdout = execFileSync('bash', [scriptPath], {
188
191
  cwd: dir,
189
192
  encoding: 'utf-8',
190
193
  stdio: ['ignore', 'pipe', 'pipe'],
194
+ env: { ...process.env, ...env },
195
+ timeout: 20000,
191
196
  });
192
197
  }
193
198
  catch (e) {
194
199
  const err = e;
195
- out = `${err.stdout ?? ''}${err.stderr ?? ''}`;
200
+ stdout = String(err.stdout ?? '');
201
+ stderr = String(err.stderr ?? '');
196
202
  }
197
- const m = out.match(/CACHE_KEY=(\S+)/);
198
- if (!m)
199
- throw new Error(`No CACHE_KEY in output:\n${out}`);
200
- return m[1];
203
+ return { stdout, stderr, combined: stdout + stderr };
201
204
  }
202
205
  finally {
203
206
  rmSync(dir, { recursive: true, force: true });
204
207
  }
205
208
  }
209
+ async function resolveIosCacheKey(build) {
210
+ const { combined } = await runIosPull(build);
211
+ const m = combined.match(/CACHE_KEY=(\S+)/);
212
+ if (!m)
213
+ throw new Error(`No CACHE_KEY in output:\n${combined}`);
214
+ return m[1];
215
+ }
216
+ function writeSpmFixture(dir) {
217
+ const swiftpm = join(dir, 'App.xcodeproj/project.xcworkspace/xcshareddata/swiftpm');
218
+ mkdirSync(swiftpm, { recursive: true });
219
+ writeFileSync(join(swiftpm, 'Package.resolved'), '{"pins":[],"version":3}');
220
+ }
221
+ test('a cold daemon miss does not print curl/zstd noise', async () => {
222
+ // Reproduce the runner setup: a configured cache daemon whose
223
+ // probe fails for an uncached key. (We point at a closed port so
224
+ // curl errors instantly with no server handle to leak — the fix
225
+ // silences curl's stderr regardless of the failure mode, exactly
226
+ // as it does for the 404 seen in production.) The probe must fall
227
+ // through to cold quietly: no "curl:" or "unexpected end of file".
228
+ const { stdout, combined } = await runIosPull(writeSpmFixture, {
229
+ CIBUILD_CACHE_DAEMON: 'http://127.0.0.1:1',
230
+ });
231
+ expect(combined).not.toContain('curl:');
232
+ expect(combined).not.toContain('unexpected end of file');
233
+ // Still resolves the SPM key and reports a cold miss.
234
+ expect(stdout).toContain('CACHE_SOURCE=cold');
235
+ expect(stdout).toMatch(/CACHE_KEY=spm-/);
236
+ });
206
237
  test('SPM project (Package.resolved, no Podfile.lock) resolves an spm- key', async () => {
207
238
  const key = await resolveIosCacheKey((dir) => {
208
239
  // Real Xcode SPM location — Package.resolved committed under
209
240
  // the shared xcworkspace data, no Podfile.lock anywhere.
210
- const swiftpm = join(dir, 'Everli.xcodeproj/project.xcworkspace/xcshareddata/swiftpm');
241
+ const swiftpm = join(dir, 'App.xcodeproj/project.xcworkspace/xcshareddata/swiftpm');
211
242
  mkdirSync(swiftpm, { recursive: true });
212
243
  writeFileSync(join(swiftpm, 'Package.resolved'), '{"pins":[],"version":3}');
213
244
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@invarn/cibuild",
3
- "version": "1.9.8",
3
+ "version": "1.9.9",
4
4
  "description": "CI Build CLI — local pipeline orchestration and validation",
5
5
  "type": "module",
6
6
  "main": "dist/cli.cjs",