@goliapkg/sentori-cli 0.4.0 → 0.5.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/lib/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { parseArgs } from 'node:util';
3
3
  import { formatIssueLine, issueList, issuePatch } from './issue.js';
4
+ import { uploadDsym, uploadMapping } from './native-artifacts.js';
4
5
  import { reactNativeUpload } from './react-native.js';
5
6
  import { uploadSourcemaps } from './upload.js';
6
7
  const HELP = `sentori-cli — Sentori command-line interface
@@ -17,6 +18,18 @@ Source-map upload:
17
18
  and upload it (plus the bundle). Use this for a Hermes release
18
19
  build. Requires --metro-map and --hermes-map.
19
20
 
21
+ Native artifacts (project-scoped, need --project + admin token):
22
+ sentori-cli upload dsym --project <uuid> [--release <r>] [--object-name <n>] [--debug-id <uuid> --arch <a>] <path>
23
+ Upload iOS dSYM debug info. By default walks a Foo.dSYM bundle
24
+ and uses "dwarfdump --uuid" to enumerate slices, uploading each.
25
+ Pass --debug-id and --arch to upload a single slice without
26
+ dwarfdump (useful in Linux CI where the toolchain isn't there).
27
+
28
+ sentori-cli upload mapping --project <uuid> [--release <r>] [--debug-id <uuid>] <mapping.txt>
29
+ Upload an R8 / ProGuard mapping (raw bytes). If the file starts
30
+ with a "# pg_map_id:" line the server sniffs the debug-id from
31
+ it; otherwise you can pass it explicitly.
32
+
20
33
  CI triage:
21
34
  sentori-cli issue list --project <uuid> [--status active|silenced|resolved|closed] [--limit N] [--error-type <t>]
22
35
  sentori-cli issue resolve <issue-uuid> --project <uuid> [--in-release <r>]
@@ -307,6 +320,119 @@ async function cmdIssuePatch(argv, body, verb) {
307
320
  return 1;
308
321
  }
309
322
  }
323
+ // ── native artifact upload ────────────────────────────────────────
324
+ async function cmdUploadDsym(argv) {
325
+ let parsed;
326
+ try {
327
+ parsed = parseArgs({
328
+ allowPositionals: true,
329
+ args: argv,
330
+ options: {
331
+ 'api-url': { type: 'string' },
332
+ arch: { type: 'string' },
333
+ 'debug-id': { type: 'string' },
334
+ help: { short: 'h', type: 'boolean' },
335
+ 'ingest-url': { type: 'string' },
336
+ 'object-name': { type: 'string' },
337
+ project: { type: 'string' },
338
+ release: { type: 'string' },
339
+ token: { type: 'string' },
340
+ },
341
+ });
342
+ }
343
+ catch (e) {
344
+ console.error(`error: ${e.message}\n${HELP}`);
345
+ return 2;
346
+ }
347
+ if (parsed.values.help) {
348
+ console.log(HELP);
349
+ return 0;
350
+ }
351
+ const cfg = parseAdminCfg(parsed.values);
352
+ if (!cfg)
353
+ return 2;
354
+ const path = parsed.positionals[0];
355
+ if (!path) {
356
+ console.error('error: a path to a .dSYM bundle or DWARF binary is required');
357
+ return 2;
358
+ }
359
+ const debugId = parsed.values['debug-id'];
360
+ const arch = parsed.values.arch;
361
+ if ((debugId && !arch) || (arch && !debugId)) {
362
+ console.error('error: --debug-id and --arch must be passed together (or both omitted)');
363
+ return 2;
364
+ }
365
+ try {
366
+ const r = await uploadDsym({
367
+ apiUrl: cfg.apiUrl,
368
+ arch: typeof arch === 'string' ? arch : undefined,
369
+ debugId: typeof debugId === 'string' ? debugId : undefined,
370
+ objectName: typeof parsed.values['object-name'] === 'string' ? parsed.values['object-name'] : undefined,
371
+ path,
372
+ projectId: cfg.projectId,
373
+ release: typeof parsed.values.release === 'string' ? parsed.values.release : undefined,
374
+ token: cfg.token,
375
+ });
376
+ console.log(`uploaded ${r.slices.length} dSYM slice(s):`);
377
+ for (const s of r.slices)
378
+ console.log(` ${s.debugId} (${s.arch})`);
379
+ return 0;
380
+ }
381
+ catch (e) {
382
+ console.error(`dsym upload failed: ${e.message}`);
383
+ return 1;
384
+ }
385
+ }
386
+ async function cmdUploadMapping(argv) {
387
+ let parsed;
388
+ try {
389
+ parsed = parseArgs({
390
+ allowPositionals: true,
391
+ args: argv,
392
+ options: {
393
+ 'api-url': { type: 'string' },
394
+ 'debug-id': { type: 'string' },
395
+ help: { short: 'h', type: 'boolean' },
396
+ 'ingest-url': { type: 'string' },
397
+ project: { type: 'string' },
398
+ release: { type: 'string' },
399
+ token: { type: 'string' },
400
+ },
401
+ });
402
+ }
403
+ catch (e) {
404
+ console.error(`error: ${e.message}\n${HELP}`);
405
+ return 2;
406
+ }
407
+ if (parsed.values.help) {
408
+ console.log(HELP);
409
+ return 0;
410
+ }
411
+ const cfg = parseAdminCfg(parsed.values);
412
+ if (!cfg)
413
+ return 2;
414
+ const path = parsed.positionals[0];
415
+ if (!path) {
416
+ console.error('error: a path to mapping.txt is required');
417
+ return 2;
418
+ }
419
+ try {
420
+ await uploadMapping({
421
+ apiUrl: cfg.apiUrl,
422
+ debugId: typeof parsed.values['debug-id'] === 'string' ? parsed.values['debug-id'] : undefined,
423
+ path,
424
+ projectId: cfg.projectId,
425
+ release: typeof parsed.values.release === 'string' ? parsed.values.release : undefined,
426
+ token: cfg.token,
427
+ });
428
+ console.log(`uploaded mapping for project ${cfg.projectId}${parsed.values.release ? ` / ${parsed.values.release}` : ''}`);
429
+ return 0;
430
+ }
431
+ catch (e) {
432
+ console.error(`mapping upload failed: ${e.message}`);
433
+ return 1;
434
+ }
435
+ }
310
436
  async function main(argv) {
311
437
  if (argv.length === 0 || argv[0] === '-h' || argv[0] === '--help') {
312
438
  console.log(HELP);
@@ -315,6 +441,10 @@ async function main(argv) {
315
441
  const [a, b, ...rest] = argv;
316
442
  if (a === 'upload' && b === 'sourcemap')
317
443
  return cmdUploadSourcemap(rest);
444
+ if (a === 'upload' && b === 'dsym')
445
+ return cmdUploadDsym(rest);
446
+ if (a === 'upload' && b === 'mapping')
447
+ return cmdUploadMapping(rest);
318
448
  if (a === 'react-native' && b === 'upload')
319
449
  return cmdReactNativeUpload(rest);
320
450
  if (a === 'issue' && b === 'list')
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ export type AdminUpload = {
2
+ apiUrl: string;
3
+ projectId: string;
4
+ release?: string;
5
+ token: string;
6
+ };
7
+ export type DsymSlice = {
8
+ arch: string;
9
+ debugId: string;
10
+ file: string;
11
+ };
12
+ /**
13
+ * Use `dwarfdump --uuid <path>` to enumerate `(arch, debug_id, file)`
14
+ * for each Mach-O slice. Returns [] if dwarfdump isn't installed or the
15
+ * output couldn't be parsed; callers should fall back to explicit
16
+ * `--debug-id` / `--arch` flags in that case.
17
+ */
18
+ export declare function dsymSlicesFromDwarfdump(path: string): DsymSlice[];
19
+ /** Walk a `.dSYM` bundle and return the DWARF binary files inside
20
+ * `Contents/Resources/DWARF/`. If `path` already points at a binary
21
+ * (not a bundle), returns `[path]`. */
22
+ export declare function dwarfBinariesIn(path: string): string[];
23
+ export type DsymUploadOptions = AdminUpload & {
24
+ /** Explicit overrides when dwarfdump isn't available. */
25
+ arch?: string;
26
+ debugId?: string;
27
+ /** A `Foo.dSYM` bundle or a raw DWARF binary. */
28
+ path: string;
29
+ objectName?: string;
30
+ };
31
+ export type DsymUploadResult = {
32
+ slices: {
33
+ arch: string;
34
+ debugId: string;
35
+ }[];
36
+ };
37
+ export declare function uploadDsym(opts: DsymUploadOptions): Promise<DsymUploadResult>;
38
+ export type MappingUploadOptions = AdminUpload & {
39
+ debugId?: string;
40
+ path: string;
41
+ };
42
+ export declare function uploadMapping(opts: MappingUploadOptions): Promise<void>;
43
+ //# sourceMappingURL=native-artifacts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"native-artifacts.d.ts","sourceRoot":"","sources":["../src/native-artifacts.ts"],"names":[],"mappings":"AASA,MAAM,MAAM,WAAW,GAAG;IACxB,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;CACd,CAAA;AAkCD,MAAM,MAAM,SAAS,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAA;AAcvE;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,CAejE;AAED;;wCAEwC;AACxC,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAiBtD;AAED,MAAM,MAAM,iBAAiB,GAAG,WAAW,GAAG;IAC5C,yDAAyD;IACzD,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,iDAAiD;IACjD,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG;IAAE,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;CAAE,CAAA;AAE9E,wBAAsB,UAAU,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAqCnF;AAID,MAAM,MAAM,oBAAoB,GAAG,WAAW,GAAG;IAC/C,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAiB7E"}
@@ -0,0 +1,148 @@
1
+ // `sentori-cli upload dsym` (iOS) + `sentori-cli upload mapping` (Android).
2
+ // Both endpoints take the raw artifact bytes (NOT multipart) with a few
3
+ // headers / query params.
4
+ import { spawnSync } from 'node:child_process';
5
+ import { readFile } from 'node:fs/promises';
6
+ import { basename, extname, join } from 'node:path';
7
+ import { statSync, readdirSync } from 'node:fs';
8
+ async function postBytes(url, body, token, headers = {}) {
9
+ const resp = await fetch(url, {
10
+ body,
11
+ headers: {
12
+ Authorization: `Bearer ${token}`,
13
+ 'Content-Type': 'application/octet-stream',
14
+ ...headers,
15
+ },
16
+ method: 'POST',
17
+ });
18
+ if (!resp.ok) {
19
+ let detail = '';
20
+ try {
21
+ detail = await resp.text();
22
+ }
23
+ catch {
24
+ // ignore
25
+ }
26
+ throw new Error(`${resp.status} ${resp.statusText}${detail ? ` — ${detail.slice(0, 300)}` : ''}`);
27
+ }
28
+ const txt = await resp.text();
29
+ return txt ? JSON.parse(txt) : null;
30
+ }
31
+ const ARCHES = new Set([
32
+ 'arm64',
33
+ 'arm64_32',
34
+ 'arm64e',
35
+ 'armv7',
36
+ 'armv7k',
37
+ 'armv7s',
38
+ 'i386',
39
+ 'x86_64',
40
+ 'x86_64h',
41
+ ]);
42
+ /**
43
+ * Use `dwarfdump --uuid <path>` to enumerate `(arch, debug_id, file)`
44
+ * for each Mach-O slice. Returns [] if dwarfdump isn't installed or the
45
+ * output couldn't be parsed; callers should fall back to explicit
46
+ * `--debug-id` / `--arch` flags in that case.
47
+ */
48
+ export function dsymSlicesFromDwarfdump(path) {
49
+ const r = spawnSync('dwarfdump', ['--uuid', path]);
50
+ if (r.status !== 0 || !r.stdout)
51
+ return [];
52
+ const out = [];
53
+ // Output lines look like:
54
+ // UUID: 1234ABCD-... (arm64) /path/to/Foo.dSYM/Contents/Resources/DWARF/Foo
55
+ const re = /^UUID:\s+([0-9A-Fa-f-]{32,36})\s+\(([^)]+)\)\s+(.+)\s*$/m;
56
+ for (const line of r.stdout.toString().split('\n')) {
57
+ const m = re.exec(line);
58
+ if (!m)
59
+ continue;
60
+ const [, debugId, arch, file] = m;
61
+ if (!ARCHES.has(arch))
62
+ continue;
63
+ out.push({ arch, debugId: debugId.toUpperCase(), file: file.trim() });
64
+ }
65
+ return out;
66
+ }
67
+ /** Walk a `.dSYM` bundle and return the DWARF binary files inside
68
+ * `Contents/Resources/DWARF/`. If `path` already points at a binary
69
+ * (not a bundle), returns `[path]`. */
70
+ export function dwarfBinariesIn(path) {
71
+ let st;
72
+ try {
73
+ st = statSync(path);
74
+ }
75
+ catch {
76
+ return [];
77
+ }
78
+ if (st.isFile())
79
+ return [path];
80
+ const dwarfDir = join(path, 'Contents/Resources/DWARF');
81
+ try {
82
+ return readdirSync(dwarfDir)
83
+ .filter((n) => !n.startsWith('.'))
84
+ .map((n) => join(dwarfDir, n));
85
+ }
86
+ catch {
87
+ // not a .dSYM bundle layout — try the top-level path
88
+ return [path];
89
+ }
90
+ }
91
+ export async function uploadDsym(opts) {
92
+ const slices = [];
93
+ if (opts.debugId && opts.arch) {
94
+ // Explicit single-slice upload — no parsing needed.
95
+ const binaries = dwarfBinariesIn(opts.path);
96
+ if (binaries.length === 0)
97
+ throw new Error(`no DWARF binary at: ${opts.path}`);
98
+ slices.push({ arch: opts.arch, debugId: opts.debugId.toUpperCase(), file: binaries[0] });
99
+ }
100
+ else {
101
+ // Auto-discover via dwarfdump.
102
+ const found = dsymSlicesFromDwarfdump(opts.path);
103
+ if (found.length === 0) {
104
+ throw new Error('couldn’t enumerate dSYM slices — install Xcode command-line tools ' +
105
+ '(for `dwarfdump`), or pass --debug-id and --arch explicitly');
106
+ }
107
+ slices.push(...found);
108
+ }
109
+ const base = opts.apiUrl.replace(/\/+$/, '');
110
+ const q = new URLSearchParams();
111
+ if (opts.release)
112
+ q.set('release', opts.release);
113
+ if (opts.objectName ?? basename(opts.path).replace(/\.dSYM$/, ''))
114
+ q.set('objectName', opts.objectName ?? basename(opts.path).replace(/\.dSYM$/, ''));
115
+ const qs = q.toString();
116
+ const url = `${base}/admin/api/projects/${encodeURIComponent(opts.projectId)}/dsyms${qs ? '?' + qs : ''}`;
117
+ const uploaded = [];
118
+ for (const s of slices) {
119
+ const body = await readFile(s.file);
120
+ await postBytes(url, body, opts.token, {
121
+ 'x-sentori-arch': s.arch,
122
+ 'x-sentori-debug-id': s.debugId,
123
+ });
124
+ uploaded.push({ arch: s.arch, debugId: s.debugId });
125
+ }
126
+ return { slices: uploaded };
127
+ }
128
+ export async function uploadMapping(opts) {
129
+ const ext = extname(opts.path).toLowerCase();
130
+ if (ext && ext !== '.txt' && ext !== '.map') {
131
+ // R8 emits `mapping.txt` by default; accept anything but warn.
132
+ console.warn(`[sentori-cli] upload mapping: unexpected extension ${ext} — uploading anyway`);
133
+ }
134
+ const body = await readFile(opts.path);
135
+ if (body.length === 0)
136
+ throw new Error(`empty mapping file: ${opts.path}`);
137
+ const base = opts.apiUrl.replace(/\/+$/, '');
138
+ const q = new URLSearchParams();
139
+ if (opts.release)
140
+ q.set('release', opts.release);
141
+ const qs = q.toString();
142
+ const url = `${base}/admin/api/projects/${encodeURIComponent(opts.projectId)}/mappings${qs ? '?' + qs : ''}`;
143
+ const headers = {};
144
+ if (opts.debugId)
145
+ headers['x-sentori-debug-id'] = opts.debugId;
146
+ await postBytes(url, body, opts.token, headers);
147
+ }
148
+ //# sourceMappingURL=native-artifacts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"native-artifacts.js","sourceRoot":"","sources":["../src/native-artifacts.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@goliapkg/sentori-cli",
3
- "version": "0.4.0",
3
+ "version": "0.5.1",
4
4
  "description": "Sentori CLI \u2014 upload source maps so dashboard stack traces resolve to your original source.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://sentori.golia.jp",
@@ -41,7 +41,7 @@
41
41
  "devDependencies": {
42
42
  "@types/bun": "latest",
43
43
  "@types/node": "*",
44
- "typescript": "^5"
44
+ "typescript": "^6"
45
45
  },
46
46
  "publishConfig": {
47
47
  "access": "public"
@@ -0,0 +1,132 @@
1
+ import { mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises'
2
+ import { tmpdir } from 'node:os'
3
+ import { join } from 'node:path'
4
+
5
+ import { afterEach, beforeEach, describe, expect, test } from 'bun:test'
6
+
7
+ import {
8
+ dsymSlicesFromDwarfdump,
9
+ dwarfBinariesIn,
10
+ uploadDsym,
11
+ uploadMapping,
12
+ } from '../native-artifacts.js'
13
+
14
+ const ADMIN = {
15
+ apiUrl: 'https://api.example.com/',
16
+ projectId: 'proj-1',
17
+ token: 'sk_test',
18
+ }
19
+
20
+ let dir = ''
21
+ const origFetch = globalThis.fetch
22
+ let calls: { body: Buffer | null; headers: Headers; method: string; url: string }[]
23
+ beforeEach(async () => {
24
+ dir = await mkdtemp(join(tmpdir(), 'sentori-cli-native-'))
25
+ calls = []
26
+ })
27
+ afterEach(async () => {
28
+ globalThis.fetch = origFetch
29
+ await rm(dir, { force: true, recursive: true })
30
+ })
31
+
32
+ function mockFetch(status = 200, respBody = ''): void {
33
+ globalThis.fetch = (async (url: Request | string | URL, init?: RequestInit) => {
34
+ const body = init?.body
35
+ calls.push({
36
+ body: body instanceof Uint8Array ? Buffer.from(body) : null,
37
+ headers: new Headers(init?.headers),
38
+ method: init?.method ?? 'GET',
39
+ url: String(url),
40
+ })
41
+ return new Response(respBody, { status })
42
+ }) as typeof fetch
43
+ }
44
+
45
+ describe('uploadMapping', () => {
46
+ test('POSTs raw bytes to /mappings with Bearer + release query', async () => {
47
+ mockFetch()
48
+ const path = join(dir, 'mapping.txt')
49
+ await writeFile(path, '# pg_map_id: abc\nfoo.bar -> a.b:\n')
50
+ await uploadMapping({ ...ADMIN, path, release: 'app@1.0.0+1' })
51
+ expect(calls).toHaveLength(1)
52
+ expect(calls[0]?.method).toBe('POST')
53
+ expect(calls[0]?.url).toBe(
54
+ 'https://api.example.com/admin/api/projects/proj-1/mappings?release=app%401.0.0%2B1',
55
+ )
56
+ expect(calls[0]?.headers.get('authorization')).toBe('Bearer sk_test')
57
+ expect(calls[0]?.headers.get('content-type')).toBe('application/octet-stream')
58
+ expect(calls[0]?.body?.toString()).toContain('pg_map_id')
59
+ })
60
+
61
+ test('sets x-sentori-debug-id when given', async () => {
62
+ mockFetch()
63
+ const path = join(dir, 'mapping.txt')
64
+ await writeFile(path, 'x')
65
+ await uploadMapping({ ...ADMIN, debugId: '1234-uuid', path })
66
+ expect(calls[0]?.headers.get('x-sentori-debug-id')).toBe('1234-uuid')
67
+ })
68
+
69
+ test('throws on empty file', async () => {
70
+ const path = join(dir, 'empty.txt')
71
+ await writeFile(path, '')
72
+ await expect(uploadMapping({ ...ADMIN, path })).rejects.toThrow('empty mapping file')
73
+ })
74
+
75
+ test('throws on non-2xx with server detail', async () => {
76
+ mockFetch(403, 'forbidden')
77
+ const path = join(dir, 'mapping.txt')
78
+ await writeFile(path, 'x')
79
+ await expect(uploadMapping({ ...ADMIN, path })).rejects.toThrow('403')
80
+ })
81
+ })
82
+
83
+ describe('uploadDsym (explicit single-slice)', () => {
84
+ test('POSTs to /dsyms with x-sentori-debug-id, x-sentori-arch, release + objectName', async () => {
85
+ mockFetch()
86
+ const path = join(dir, 'Foo.dSYM/Contents/Resources/DWARF/Foo')
87
+ await mkdir(join(dir, 'Foo.dSYM/Contents/Resources/DWARF'), { recursive: true })
88
+ await writeFile(path, 'macho-bytes')
89
+ const r = await uploadDsym({
90
+ ...ADMIN,
91
+ arch: 'arm64',
92
+ debugId: '1234abcd-1234-1234-1234-1234567890ab',
93
+ objectName: 'Foo',
94
+ path,
95
+ release: 'app@1.0.0+1',
96
+ })
97
+ expect(calls).toHaveLength(1)
98
+ expect(calls[0]?.method).toBe('POST')
99
+ expect(calls[0]?.url).toContain('/admin/api/projects/proj-1/dsyms')
100
+ expect(calls[0]?.url).toContain('release=app%401.0.0%2B1')
101
+ expect(calls[0]?.url).toContain('objectName=Foo')
102
+ expect(calls[0]?.headers.get('x-sentori-debug-id')).toBe('1234ABCD-1234-1234-1234-1234567890AB')
103
+ expect(calls[0]?.headers.get('x-sentori-arch')).toBe('arm64')
104
+ expect(r.slices).toEqual([{ arch: 'arm64', debugId: '1234ABCD-1234-1234-1234-1234567890AB' }])
105
+ })
106
+ })
107
+
108
+ describe('helpers', () => {
109
+ test('dwarfBinariesIn walks a .dSYM bundle', async () => {
110
+ const bundle = join(dir, 'Foo.dSYM')
111
+ const dwarfDir = join(bundle, 'Contents/Resources/DWARF')
112
+ await mkdir(dwarfDir, { recursive: true })
113
+ await writeFile(join(dwarfDir, 'Foo'), 'x')
114
+ await writeFile(join(dwarfDir, '.DS_Store'), 'noise')
115
+ const found = dwarfBinariesIn(bundle)
116
+ expect(found.map((p) => p.replace(bundle + '/', ''))).toEqual([
117
+ 'Contents/Resources/DWARF/Foo',
118
+ ])
119
+ })
120
+
121
+ test('dwarfBinariesIn on a plain file returns just that file', async () => {
122
+ const f = join(dir, 'binary')
123
+ await writeFile(f, 'x')
124
+ expect(dwarfBinariesIn(f)).toEqual([f])
125
+ })
126
+
127
+ test('dsymSlicesFromDwarfdump returns [] when dwarfdump fails (or is absent)', () => {
128
+ // pass a path that doesn't exist; dwarfdump exits non-zero (or isn't installed)
129
+ const slices = dsymSlicesFromDwarfdump(join(dir, 'nope.dSYM'))
130
+ expect(slices).toEqual([])
131
+ })
132
+ })
package/src/index.ts CHANGED
@@ -2,6 +2,7 @@
2
2
  import { parseArgs } from 'node:util'
3
3
 
4
4
  import { formatIssueLine, issueList, issuePatch } from './issue.js'
5
+ import { uploadDsym, uploadMapping } from './native-artifacts.js'
5
6
  import { reactNativeUpload } from './react-native.js'
6
7
  import { uploadSourcemaps } from './upload.js'
7
8
 
@@ -19,6 +20,18 @@ Source-map upload:
19
20
  and upload it (plus the bundle). Use this for a Hermes release
20
21
  build. Requires --metro-map and --hermes-map.
21
22
 
23
+ Native artifacts (project-scoped, need --project + admin token):
24
+ sentori-cli upload dsym --project <uuid> [--release <r>] [--object-name <n>] [--debug-id <uuid> --arch <a>] <path>
25
+ Upload iOS dSYM debug info. By default walks a Foo.dSYM bundle
26
+ and uses "dwarfdump --uuid" to enumerate slices, uploading each.
27
+ Pass --debug-id and --arch to upload a single slice without
28
+ dwarfdump (useful in Linux CI where the toolchain isn't there).
29
+
30
+ sentori-cli upload mapping --project <uuid> [--release <r>] [--debug-id <uuid>] <mapping.txt>
31
+ Upload an R8 / ProGuard mapping (raw bytes). If the file starts
32
+ with a "# pg_map_id:" line the server sniffs the debug-id from
33
+ it; otherwise you can pass it explicitly.
34
+
22
35
  CI triage:
23
36
  sentori-cli issue list --project <uuid> [--status active|silenced|resolved|closed] [--limit N] [--error-type <t>]
24
37
  sentori-cli issue resolve <issue-uuid> --project <uuid> [--in-release <r>]
@@ -328,6 +341,115 @@ async function cmdIssuePatch(
328
341
  }
329
342
  }
330
343
 
344
+ // ── native artifact upload ────────────────────────────────────────
345
+
346
+ async function cmdUploadDsym(argv: string[]): Promise<number> {
347
+ let parsed
348
+ try {
349
+ parsed = parseArgs({
350
+ allowPositionals: true,
351
+ args: argv,
352
+ options: {
353
+ 'api-url': { type: 'string' },
354
+ arch: { type: 'string' },
355
+ 'debug-id': { type: 'string' },
356
+ help: { short: 'h', type: 'boolean' },
357
+ 'ingest-url': { type: 'string' },
358
+ 'object-name': { type: 'string' },
359
+ project: { type: 'string' },
360
+ release: { type: 'string' },
361
+ token: { type: 'string' },
362
+ },
363
+ })
364
+ } catch (e) {
365
+ console.error(`error: ${(e as Error).message}\n${HELP}`)
366
+ return 2
367
+ }
368
+ if (parsed.values.help) {
369
+ console.log(HELP)
370
+ return 0
371
+ }
372
+ const cfg = parseAdminCfg(parsed.values)
373
+ if (!cfg) return 2
374
+ const path = parsed.positionals[0]
375
+ if (!path) {
376
+ console.error('error: a path to a .dSYM bundle or DWARF binary is required')
377
+ return 2
378
+ }
379
+ const debugId = parsed.values['debug-id']
380
+ const arch = parsed.values.arch
381
+ if ((debugId && !arch) || (arch && !debugId)) {
382
+ console.error('error: --debug-id and --arch must be passed together (or both omitted)')
383
+ return 2
384
+ }
385
+ try {
386
+ const r = await uploadDsym({
387
+ apiUrl: cfg.apiUrl,
388
+ arch: typeof arch === 'string' ? arch : undefined,
389
+ debugId: typeof debugId === 'string' ? debugId : undefined,
390
+ objectName: typeof parsed.values['object-name'] === 'string' ? parsed.values['object-name'] : undefined,
391
+ path,
392
+ projectId: cfg.projectId,
393
+ release: typeof parsed.values.release === 'string' ? parsed.values.release : undefined,
394
+ token: cfg.token,
395
+ })
396
+ console.log(`uploaded ${r.slices.length} dSYM slice(s):`)
397
+ for (const s of r.slices) console.log(` ${s.debugId} (${s.arch})`)
398
+ return 0
399
+ } catch (e) {
400
+ console.error(`dsym upload failed: ${(e as Error).message}`)
401
+ return 1
402
+ }
403
+ }
404
+
405
+ async function cmdUploadMapping(argv: string[]): Promise<number> {
406
+ let parsed
407
+ try {
408
+ parsed = parseArgs({
409
+ allowPositionals: true,
410
+ args: argv,
411
+ options: {
412
+ 'api-url': { type: 'string' },
413
+ 'debug-id': { type: 'string' },
414
+ help: { short: 'h', type: 'boolean' },
415
+ 'ingest-url': { type: 'string' },
416
+ project: { type: 'string' },
417
+ release: { type: 'string' },
418
+ token: { type: 'string' },
419
+ },
420
+ })
421
+ } catch (e) {
422
+ console.error(`error: ${(e as Error).message}\n${HELP}`)
423
+ return 2
424
+ }
425
+ if (parsed.values.help) {
426
+ console.log(HELP)
427
+ return 0
428
+ }
429
+ const cfg = parseAdminCfg(parsed.values)
430
+ if (!cfg) return 2
431
+ const path = parsed.positionals[0]
432
+ if (!path) {
433
+ console.error('error: a path to mapping.txt is required')
434
+ return 2
435
+ }
436
+ try {
437
+ await uploadMapping({
438
+ apiUrl: cfg.apiUrl,
439
+ debugId: typeof parsed.values['debug-id'] === 'string' ? parsed.values['debug-id'] : undefined,
440
+ path,
441
+ projectId: cfg.projectId,
442
+ release: typeof parsed.values.release === 'string' ? parsed.values.release : undefined,
443
+ token: cfg.token,
444
+ })
445
+ console.log(`uploaded mapping for project ${cfg.projectId}${parsed.values.release ? ` / ${parsed.values.release}` : ''}`)
446
+ return 0
447
+ } catch (e) {
448
+ console.error(`mapping upload failed: ${(e as Error).message}`)
449
+ return 1
450
+ }
451
+ }
452
+
331
453
  async function main(argv: string[]): Promise<number> {
332
454
  if (argv.length === 0 || argv[0] === '-h' || argv[0] === '--help') {
333
455
  console.log(HELP)
@@ -335,6 +457,8 @@ async function main(argv: string[]): Promise<number> {
335
457
  }
336
458
  const [a, b, ...rest] = argv
337
459
  if (a === 'upload' && b === 'sourcemap') return cmdUploadSourcemap(rest)
460
+ if (a === 'upload' && b === 'dsym') return cmdUploadDsym(rest)
461
+ if (a === 'upload' && b === 'mapping') return cmdUploadMapping(rest)
338
462
  if (a === 'react-native' && b === 'upload') return cmdReactNativeUpload(rest)
339
463
  if (a === 'issue' && b === 'list') return cmdIssueList(rest)
340
464
  if (a === 'issue' && b === 'resolve') return cmdIssuePatch(rest, { status: 'resolved' }, 'resolved')
@@ -0,0 +1,182 @@
1
+ // `sentori-cli upload dsym` (iOS) + `sentori-cli upload mapping` (Android).
2
+ // Both endpoints take the raw artifact bytes (NOT multipart) with a few
3
+ // headers / query params.
4
+
5
+ import { spawnSync } from 'node:child_process'
6
+ import { readFile } from 'node:fs/promises'
7
+ import { basename, extname, join } from 'node:path'
8
+ import { statSync, readdirSync } from 'node:fs'
9
+
10
+ export type AdminUpload = {
11
+ apiUrl: string
12
+ projectId: string
13
+ release?: string
14
+ token: string
15
+ }
16
+
17
+ async function postBytes(
18
+ url: string,
19
+ body: Buffer,
20
+ token: string,
21
+ headers: Record<string, string> = {},
22
+ ): Promise<unknown> {
23
+ const resp = await fetch(url, {
24
+ body,
25
+ headers: {
26
+ Authorization: `Bearer ${token}`,
27
+ 'Content-Type': 'application/octet-stream',
28
+ ...headers,
29
+ },
30
+ method: 'POST',
31
+ })
32
+ if (!resp.ok) {
33
+ let detail = ''
34
+ try {
35
+ detail = await resp.text()
36
+ } catch {
37
+ // ignore
38
+ }
39
+ throw new Error(
40
+ `${resp.status} ${resp.statusText}${detail ? ` — ${detail.slice(0, 300)}` : ''}`,
41
+ )
42
+ }
43
+ const txt = await resp.text()
44
+ return txt ? JSON.parse(txt) : null
45
+ }
46
+
47
+ // ── dSYM ──────────────────────────────────────────────────────────
48
+
49
+ export type DsymSlice = { arch: string; debugId: string; file: string }
50
+
51
+ const ARCHES = new Set([
52
+ 'arm64',
53
+ 'arm64_32',
54
+ 'arm64e',
55
+ 'armv7',
56
+ 'armv7k',
57
+ 'armv7s',
58
+ 'i386',
59
+ 'x86_64',
60
+ 'x86_64h',
61
+ ])
62
+
63
+ /**
64
+ * Use `dwarfdump --uuid <path>` to enumerate `(arch, debug_id, file)`
65
+ * for each Mach-O slice. Returns [] if dwarfdump isn't installed or the
66
+ * output couldn't be parsed; callers should fall back to explicit
67
+ * `--debug-id` / `--arch` flags in that case.
68
+ */
69
+ export function dsymSlicesFromDwarfdump(path: string): DsymSlice[] {
70
+ const r = spawnSync('dwarfdump', ['--uuid', path])
71
+ if (r.status !== 0 || !r.stdout) return []
72
+ const out: DsymSlice[] = []
73
+ // Output lines look like:
74
+ // UUID: 1234ABCD-... (arm64) /path/to/Foo.dSYM/Contents/Resources/DWARF/Foo
75
+ const re = /^UUID:\s+([0-9A-Fa-f-]{32,36})\s+\(([^)]+)\)\s+(.+)\s*$/m
76
+ for (const line of r.stdout.toString().split('\n')) {
77
+ const m = re.exec(line)
78
+ if (!m) continue
79
+ const [, debugId, arch, file] = m as unknown as [string, string, string, string]
80
+ if (!ARCHES.has(arch)) continue
81
+ out.push({ arch, debugId: debugId.toUpperCase(), file: file.trim() })
82
+ }
83
+ return out
84
+ }
85
+
86
+ /** Walk a `.dSYM` bundle and return the DWARF binary files inside
87
+ * `Contents/Resources/DWARF/`. If `path` already points at a binary
88
+ * (not a bundle), returns `[path]`. */
89
+ export function dwarfBinariesIn(path: string): string[] {
90
+ let st
91
+ try {
92
+ st = statSync(path)
93
+ } catch {
94
+ return []
95
+ }
96
+ if (st.isFile()) return [path]
97
+ const dwarfDir = join(path, 'Contents/Resources/DWARF')
98
+ try {
99
+ return readdirSync(dwarfDir)
100
+ .filter((n) => !n.startsWith('.'))
101
+ .map((n) => join(dwarfDir, n))
102
+ } catch {
103
+ // not a .dSYM bundle layout — try the top-level path
104
+ return [path]
105
+ }
106
+ }
107
+
108
+ export type DsymUploadOptions = AdminUpload & {
109
+ /** Explicit overrides when dwarfdump isn't available. */
110
+ arch?: string
111
+ debugId?: string
112
+ /** A `Foo.dSYM` bundle or a raw DWARF binary. */
113
+ path: string
114
+ objectName?: string
115
+ }
116
+
117
+ export type DsymUploadResult = { slices: { arch: string; debugId: string }[] }
118
+
119
+ export async function uploadDsym(opts: DsymUploadOptions): Promise<DsymUploadResult> {
120
+ const slices: DsymSlice[] = []
121
+ if (opts.debugId && opts.arch) {
122
+ // Explicit single-slice upload — no parsing needed.
123
+ const binaries = dwarfBinariesIn(opts.path)
124
+ if (binaries.length === 0) throw new Error(`no DWARF binary at: ${opts.path}`)
125
+ slices.push({ arch: opts.arch, debugId: opts.debugId.toUpperCase(), file: binaries[0]! })
126
+ } else {
127
+ // Auto-discover via dwarfdump.
128
+ const found = dsymSlicesFromDwarfdump(opts.path)
129
+ if (found.length === 0) {
130
+ throw new Error(
131
+ 'couldn’t enumerate dSYM slices — install Xcode command-line tools ' +
132
+ '(for `dwarfdump`), or pass --debug-id and --arch explicitly',
133
+ )
134
+ }
135
+ slices.push(...found)
136
+ }
137
+
138
+ const base = opts.apiUrl.replace(/\/+$/, '')
139
+ const q = new URLSearchParams()
140
+ if (opts.release) q.set('release', opts.release)
141
+ if (opts.objectName ?? basename(opts.path).replace(/\.dSYM$/, ''))
142
+ q.set('objectName', opts.objectName ?? basename(opts.path).replace(/\.dSYM$/, ''))
143
+ const qs = q.toString()
144
+ const url = `${base}/admin/api/projects/${encodeURIComponent(opts.projectId)}/dsyms${qs ? '?' + qs : ''}`
145
+
146
+ const uploaded: { arch: string; debugId: string }[] = []
147
+ for (const s of slices) {
148
+ const body = await readFile(s.file)
149
+ await postBytes(url, body, opts.token, {
150
+ 'x-sentori-arch': s.arch,
151
+ 'x-sentori-debug-id': s.debugId,
152
+ })
153
+ uploaded.push({ arch: s.arch, debugId: s.debugId })
154
+ }
155
+ return { slices: uploaded }
156
+ }
157
+
158
+ // ── ProGuard / R8 mapping ─────────────────────────────────────────
159
+
160
+ export type MappingUploadOptions = AdminUpload & {
161
+ debugId?: string
162
+ path: string
163
+ }
164
+
165
+ export async function uploadMapping(opts: MappingUploadOptions): Promise<void> {
166
+ const ext = extname(opts.path).toLowerCase()
167
+ if (ext && ext !== '.txt' && ext !== '.map') {
168
+ // R8 emits `mapping.txt` by default; accept anything but warn.
169
+ console.warn(`[sentori-cli] upload mapping: unexpected extension ${ext} — uploading anyway`)
170
+ }
171
+ const body = await readFile(opts.path)
172
+ if (body.length === 0) throw new Error(`empty mapping file: ${opts.path}`)
173
+
174
+ const base = opts.apiUrl.replace(/\/+$/, '')
175
+ const q = new URLSearchParams()
176
+ if (opts.release) q.set('release', opts.release)
177
+ const qs = q.toString()
178
+ const url = `${base}/admin/api/projects/${encodeURIComponent(opts.projectId)}/mappings${qs ? '?' + qs : ''}`
179
+ const headers: Record<string, string> = {}
180
+ if (opts.debugId) headers['x-sentori-debug-id'] = opts.debugId
181
+ await postBytes(url, body, opts.token, headers)
182
+ }