Skip to content

Commit 7e4e64e

Browse files
DavidMina96ymabdallah
authored andcommitted
[MOB-9960] Create CLI for Source Maps Upload (#879)
Create a binary that gets shipped with the package to support uploading source maps via CLI using upload-sourcemaps command.
1 parent 51dd4a3 commit 7e4e64e

9 files changed

+376
-7
lines changed

.circleci/config.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ jobs:
173173
command: yarn
174174
- run:
175175
name: Build Project
176-
command: yarn build
176+
command: yarn build:lib
177177
- run:
178178
name: Install Example's Node Packages
179179
working_directory: example
@@ -210,7 +210,7 @@ jobs:
210210
command: yarn
211211
- run:
212212
name: Build Project
213-
command: yarn build
213+
command: yarn build:lib
214214
- run:
215215
name: Install Example's Node Packages
216216
working_directory: example

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,5 @@ coverage/
3838
*Podfile.lock
3939

4040
# Typescript build
41-
dist/
41+
dist/
42+
bin/

cli/UploadSourcemaps.ts

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import axios from 'axios';
2+
import { Command, Option } from 'commander';
3+
import FormData from 'form-data';
4+
import fs from 'fs';
5+
import path from 'path';
6+
7+
interface UploadSourcemapsOptions {
8+
platform: 'android' | 'ios';
9+
dir: string;
10+
token: string;
11+
name: string;
12+
code: string;
13+
label?: string;
14+
}
15+
16+
export const uploadSourcemapsCommand = new Command();
17+
18+
uploadSourcemapsCommand
19+
.name('upload-sourcemaps')
20+
.addOption(
21+
new Option('-p, --platform <value>', 'Platform')
22+
.choices(['ios', 'android'])
23+
.makeOptionMandatory(),
24+
)
25+
.addOption(
26+
new Option(
27+
'-d, --dir <value>',
28+
'The path of the directory including the source map file',
29+
).makeOptionMandatory(),
30+
)
31+
.addOption(
32+
new Option('-t, --token <value>', 'Your App Token')
33+
.env('INSTABUG_APP_TOKEN')
34+
.makeOptionMandatory(),
35+
)
36+
.addOption(
37+
new Option('-n, --name <value>', 'The app version name')
38+
.env('INSTABUG_APP_VERSION_NAME')
39+
.makeOptionMandatory(),
40+
)
41+
.addOption(
42+
new Option('-c, --code <value>', 'The app version code')
43+
.env('INSTABUG_APP_VERSION_CODE')
44+
.makeOptionMandatory(),
45+
)
46+
.addOption(
47+
new Option('-l, --label <value>', "The CodePush label if it's a CodePush release").env(
48+
'INSTABUG_APP_VERSION_LABEL',
49+
),
50+
)
51+
.action(function (this: Command) {
52+
const options = this.opts<UploadSourcemapsOptions>();
53+
uploadSourcemaps(options);
54+
})
55+
.showHelpAfterError();
56+
57+
const uploadSourcemaps = async (opts: UploadSourcemapsOptions) => {
58+
const fileName = `${opts.platform}-sourcemap.json`;
59+
const filePath = path.join(opts.dir, fileName);
60+
const fileBlob = fs.readFileSync(filePath);
61+
62+
const version = {
63+
code: opts.code,
64+
name: opts.name,
65+
codePush: opts.label,
66+
};
67+
68+
const form = new FormData();
69+
form.append('app_version', JSON.stringify(version));
70+
form.append('symbols_file', fileBlob, fileName);
71+
form.append('application_token', opts.token);
72+
form.append('platform', 'react_native');
73+
form.append('os', opts.platform);
74+
75+
console.log('Uploading Source map file...');
76+
77+
try {
78+
const response = await axios.post('https://api.instabug.com/api/sdk/v3/symbols_files', form, {
79+
headers: form.getHeaders(),
80+
});
81+
82+
const appVersion = version.codePush
83+
? `${version.name} (${version.code})+codepush:${version.codePush}`
84+
: `${version.name} (${version.code})`;
85+
86+
console.log(`Successfully uploaded Source maps for version: ${appVersion}`);
87+
console.log(response.data);
88+
} catch (err) {
89+
console.error(
90+
'Failed to upload source maps:',
91+
axios.isAxiosError(err) ? err.response?.data : err,
92+
);
93+
}
94+
};

cli/index.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#!/usr/bin/env node
2+
import { Command } from 'commander';
3+
4+
import { uploadSourcemapsCommand } from './UploadSourcemaps';
5+
6+
const program = new Command();
7+
8+
program
9+
.name('instaubg')
10+
.version('1.0.0-beta1')
11+
.description('A CLI for uploading source maps to Instabug dashboard.')
12+
.usage('[command]')
13+
.addCommand(uploadSourcemapsCommand);
14+
15+
program.parse(process.argv);

package.json

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
"main": "dist/index",
1111
"types": "dist/index.d.ts",
1212
"react-native": "src/index.ts",
13+
"bin": {
14+
"instabug": "bin/index.js"
15+
},
1316
"keywords": [
1417
"react-native",
1518
"instabug",
@@ -27,7 +30,9 @@
2730
"format": "prettier --check . --ignore-path .gitignore",
2831
"format:fix": "prettier --write . --ignore-path .gitignore",
2932
"test": "jest",
30-
"build": "tsc"
33+
"build": "yarn build:lib && yarn build:cli",
34+
"build:lib": "tsc",
35+
"build:cli": "npx rollup -c rollup.config.js --bundleConfigAsCjs"
3136
},
3237
"peerDependencies": {
3338
"react": ">=16.8.6",
@@ -37,15 +42,22 @@
3742
"@apollo/client": "^3.7.0",
3843
"@react-native-community/eslint-config": "^3.1.0",
3944
"@react-navigation/native": "^5.9.8",
45+
"@rollup/plugin-commonjs": "^24.0.0",
46+
"@rollup/plugin-json": "^6.0.0",
47+
"@rollup/plugin-node-resolve": "^15.0.1",
48+
"@rollup/plugin-typescript": "^11.0.0",
4049
"@trivago/prettier-plugin-sort-imports": "^3.3.0",
4150
"@types/jest": "^24.0.0",
4251
"@types/node": "^18.7.23",
4352
"@types/react-native": "^0.66.0",
53+
"axios": "^1.2.2",
4454
"babel-core": "7.0.0-bridge.0",
4555
"babel-jest": "^24.8.0",
56+
"commander": "^9.4.1",
4657
"eslint": "^8.24.0",
4758
"eslint-plugin-prettier": "^4.2.1",
4859
"esprima": "^4.0.1",
60+
"form-data": "^4.0.0",
4961
"jest": "^24.8.0",
5062
"metro-react-native-babel-preset": "0.73.3",
5163
"nock": "^13.2.9",
@@ -54,6 +66,9 @@
5466
"react-native": "^0.60.0",
5567
"react-native-navigation": "7.29.1",
5668
"react-navigation": "^4.4.4",
69+
"rollup": "^3.9.1",
70+
"rollup-plugin-cleanup": "^3.2.1",
71+
"rollup-plugin-preserve-shebang": "^1.0.1",
5772
"ts-jest": "^24.0.0",
5873
"typescript": "^4.8.4",
5974
"wait-for-expect": "^1.2.0",

rollup.config.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import commonjs from '@rollup/plugin-commonjs';
2+
import json from '@rollup/plugin-json';
3+
import nodeResolve from '@rollup/plugin-node-resolve';
4+
import typescript from '@rollup/plugin-typescript';
5+
import cleanup from 'rollup-plugin-cleanup';
6+
import shebang from 'rollup-plugin-preserve-shebang';
7+
8+
/** @type import('rollup').RollupOptions */
9+
export default {
10+
input: ['cli/index.ts'],
11+
output: {
12+
dir: 'bin',
13+
format: 'cjs',
14+
},
15+
plugins: [
16+
typescript({ tsconfig: './tsconfig.cli.json' }),
17+
shebang(),
18+
json(),
19+
nodeResolve({ preferBuiltins: true }),
20+
commonjs(),
21+
cleanup(),
22+
],
23+
};

tsconfig.cli.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"extends": "./tsconfig.json",
3+
"include": ["cli/**/*"],
4+
"exclude": [],
5+
"compilerOptions": {
6+
"lib": ["dom"],
7+
"outDir": "bin",
8+
"module": "esnext"
9+
}
10+
}

tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
{
2+
"include": ["src/**/*"],
23
"compilerOptions": {
34
"module": "esnext",
45
"target": "esnext",

0 commit comments

Comments
 (0)