Commit 59a71ffa authored by IlarionHalushka's avatar IlarionHalushka Committed by Diego Mello
Browse files

[CHORE] Bugsnag logging setup (#1145)

* initial bugsnag setup

* upload sourcemaps to bugsnag during ios-build job

* fix: spacing in config.yml

* add yarn global add react-native

* add separate step: Upload sourcemaps to Bugsnag

* add brew install watchman

* install react-native-cli, remove install watchman

* upload source maps for android build

* add yarn add global react-native react-native-cli for android-build ci job

* add working_directory to android-build

* install npm i -g react-native react-native-cli

* add Install Node step to android-build job

* export path to node to bash_profile

* add step Install React Native CLI to android build job

* use yarn generate-source-maps in ci; exchange firebase log -> bugsnag log

* implement send(toggle) crash reports button

* move BUGSNAG_API_KEY to config file; remove generated source maps files

* unlink bugsnag

* add ios/Pods files connected to Bugsnag; fix ci android build job

* export firebase analytics also from /utils/log

* use `log(e)` instead of `log(error)`

* API Key changes

* pod install

* Fix iOS build

* Simulate error

* lint

* Add navigation

* Use projectRoot

* Revert project root

* - Don't run on forks
- Upload dSYMs

* Remove error sim

* Remove automatic dSYMs upload

* Remove fastlane-plugin-bugsnag
parent f58f744e
......@@ -116,10 +116,26 @@ jobs:
steps:
- checkout
- run:
name: Install Node 8
command: |
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.6/install.sh | bash
source ~/.nvm/nvm.sh
# https://github.com/creationix/nvm/issues/1394
set +e
nvm install 8
echo 'export PATH="/home/circleci/.nvm/versions/node/v8.16.0/bin:$PATH"' >> ~/.bash_profile
source ~/.bash_profile
- restore_cache:
name: Restore NPM cache
key: node-modules-{{ checksum "yarn.lock" }}
- run:
name: Install React Native CLI
command: |
npm i -g react-native-cli
- run:
name: Install NPM modules
command: |
......@@ -148,12 +164,32 @@ jobs:
fi
echo -e "VERSIONCODE=$CIRCLE_BUILD_NUM" >> ./gradle.properties
echo -e "BugsnagAPIKey=$BUGSNAG_KEY" >> ./gradle.properties
- run:
name: Set Google Services
command: |
cd android/app
cp google-services.prod.json google-services.json
working_directory: android/app
- run:
name: Upload sourcemaps to Bugsnag
command: |
if [[ $BUGSNAG_KEY ]]; then
yarn generate-source-maps-android
curl https://upload.bugsnag.com/react-native-source-map \
-F apiKey=$BUGSNAG_KEY \
-F appVersionCode=$CIRCLE_BUILD_NUM \
-F dev=false \
-F platform=android \
-F sourceMap=@android-release.bundle.map \
-F bundle=@android-release.bundle
fi
- run:
name: Config variables
command: |
echo -e "export default { BUGSNAG_API_KEY: '$BUGSNAG_KEY' };" > ./config.js
- run:
name: Build Android App
......@@ -215,6 +251,7 @@ jobs:
- run:
name: Install NPM modules
command: |
yarn global add react-native react-native-cli
yarn
- run:
......@@ -229,11 +266,26 @@ jobs:
cp GoogleService-Info.prod.plist GoogleService-Info.plist
working_directory: ios
- run:
name: Upload sourcemaps to Bugsnag
command: |
if [[ $BUGSNAG_KEY ]]; then
yarn generate-source-maps-ios
curl https://upload.bugsnag.com/react-native-source-map \
-F apiKey=$BUGSNAG_KEY \
-F appBundleVersion=$CIRCLE_BUILD_NUM \
-F dev=false \
-F platform=ios \
-F sourceMap=@ios-release.bundle.map \
-F bundle=@ios-release.bundle
fi
- run:
name: Fastlane Build
no_output_timeout: 1200
command: |
agvtool new-version -all $CIRCLE_BUILD_NUM
/usr/libexec/PlistBuddy -c "Set BugsnagAPIKey $BUGSNAG_KEY" ./RocketChatRN/Info.plist
if [[ $MATCH_KEYCHAIN_NAME ]]; then
bundle exec fastlane ios release
......@@ -288,7 +340,7 @@ jobs:
- run:
name: Fastlane Tesflight Upload
command: |
bundle exec fastlane pilot upload --ipa ios/RocketChatRN.ipa --changelog "$(sh ../.circleci/changelog.sh)"
bundle exec fastlane ios beta
working_directory: ios
- save_cache:
......
apply plugin: "com.android.application"
apply plugin: "io.fabric"
apply plugin: "com.google.firebase.firebase-perf"
apply plugin: 'com.bugsnag.android.gradle'
import com.android.build.OutputFile
......@@ -137,6 +138,7 @@ android {
versionCode VERSIONCODE as Integer
versionName "1.19.0"
vectorDrawables.useSupportLibrary = true
manifestPlaceholders = [BugsnagAPIKey: BugsnagAPIKey as String]
}
signingConfigs {
......
......@@ -5,7 +5,7 @@
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" />
......@@ -52,6 +52,9 @@
<data android:mimeType="*/*" />
</intent-filter>
</activity>
<meta-data
android:name="com.bugsnag.android.API_KEY"
android:value="${BugsnagAPIKey}" />
</application>
</manifest>
......@@ -24,6 +24,7 @@ buildscript {
classpath 'com.google.gms:google-services:4.2.0'
classpath 'io.fabric.tools:gradle:1.28.1'
classpath 'com.google.firebase:perf-plugin:1.2.1'
classpath 'com.bugsnag:bugsnag-android-gradle-plugin:4.+'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
......@@ -50,16 +51,16 @@ allprojects {
}
}
// subprojects { subproject ->
// afterEvaluate {
// if ((subproject.plugins.hasPlugin('android') || subproject.plugins.hasPlugin('android-library'))) {
// android {
// compileSdkVersion 28
// buildToolsVersion "28.0.3"
// defaultConfig {
// targetSdkVersion 28
// }
// }
// }
// }
// }
\ No newline at end of file
// subprojects { subproject ->
// afterEvaluate {
// if ((subproject.plugins.hasPlugin('android') || subproject.plugins.hasPlugin('android-library'))) {
// android {
// compileSdkVersion 28
// buildToolsVersion "28.0.3"
// defaultConfig {
// targetSdkVersion 28
// }
// }
// }
// }
// }
......@@ -22,3 +22,4 @@ org.gradle.jvmargs=-Xmx2048M -XX\:MaxHeapSize\=32g
android.useAndroidX=true
android.enableJetifier=true
VERSIONCODE=999999999
BugsnagAPIKey=""
......@@ -18,4 +18,5 @@ if (__DEV__) {
Reactotron.clear();
console.warn = Reactotron.log;
console.log = Reactotron.log;
console.disableYellowBox = true;
}
......@@ -74,3 +74,4 @@ export const DEEP_LINKING = createRequestTypes('DEEP_LINKING', ['OPEN']);
export const SORT_PREFERENCES = createRequestTypes('SORT_PREFERENCES', ['SET_ALL', 'SET']);
export const NOTIFICATION = createRequestTypes('NOTIFICATION', ['RECEIVED', 'REMOVE']);
export const TOGGLE_MARKDOWN = 'TOGGLE_MARKDOWN';
export const TOGGLE_CRASH_REPORT = 'TOGGLE_CRASH_REPORT';
import * as types from './actionsTypes';
export function toggleCrashReport(value) {
return {
type: types.TOGGLE_CRASH_REPORT,
payload: value
};
}
......@@ -311,7 +311,7 @@ class MessageActions extends React.Component {
await RocketChat.reportMessage(actionMessage._id);
Alert.alert(I18n.t('Message_Reported'));
} catch (err) {
log('err_report_message', err);
log(err);
}
}
......@@ -328,7 +328,7 @@ class MessageActions extends React.Component {
await RocketChat.translateMessage(actionMessage, room.autoTranslateLanguage);
}
} catch (err) {
log('err_toggle_translation', err);
log(err);
}
}
......
......@@ -362,7 +362,7 @@ class MessageBox extends Component {
try {
database.create('users', user, true);
} catch (e) {
log('err_create_users', e);
log(e);
}
});
});
......@@ -504,7 +504,7 @@ class MessageBox extends Component {
try {
await RocketChat.sendFileMessage(rid, fileInfo, tmid, server, user);
} catch (e) {
log('err_send_media_message', e);
log(e);
}
}
......@@ -513,7 +513,7 @@ class MessageBox extends Component {
const image = await ImagePicker.openCamera(this.imagePickerConfig);
this.showUploadModal(image);
} catch (e) {
log('err_take_photo', e);
log(e);
}
}
......@@ -522,7 +522,7 @@ class MessageBox extends Component {
const video = await ImagePicker.openCamera(this.videoPickerConfig);
this.showUploadModal(video);
} catch (e) {
log('err_take_video', e);
log(e);
}
}
......@@ -531,7 +531,7 @@ class MessageBox extends Component {
const image = await ImagePicker.openPicker(this.libraryPickerConfig);
this.showUploadModal(image);
} catch (e) {
log('err_choose_from_library', e);
log(e);
}
}
......@@ -618,7 +618,7 @@ class MessageBox extends Component {
if (e && e.error === 'error-file-too-large') {
return Alert.alert(I18n.t(e.error));
}
log('err_finish_audio_message', e);
log(e);
}
}
}
......
......@@ -407,5 +407,5 @@ export default {
Version_no: 'Version: {{version}}',
You_will_not_be_able_to_recover_this_message: 'You will not be able to recover this message!',
Change_Language: 'Change Language',
Crash_report_disclaimer: 'We never track the content of your chats. The crash report only contains relevant information for us in order '
Crash_report_disclaimer: 'We never track the content of your chats. The crash report only contains relevant information for us in order to identify problems and fix it.'
};
......@@ -16,7 +16,9 @@ import { initializePushNotifications, onNotification } from './notifications/pus
import store from './lib/createStore';
import NotificationBadge from './notifications/inApp';
import { defaultHeader, onNavigationStateChange } from './utils/navigation';
import { loggerConfig, analytics } from './utils/log';
import Toast from './containers/Toast';
import RocketChat from './lib/rocketchat';
useScreens();
......@@ -256,6 +258,7 @@ export default class Root extends React.Component {
constructor(props) {
super(props);
this.init();
this.initCrashReport();
}
componentDidMount() {
......@@ -285,6 +288,17 @@ export default class Root extends React.Component {
}
}
initCrashReport = () => {
RocketChat.getAllowCrashReport()
.then((allowCrashReport) => {
if (!allowCrashReport) {
loggerConfig.autoNotify = false;
loggerConfig.registerBeforeSendCallback(() => false);
analytics().setAnalyticsCollectionEnabled(false);
}
});
}
render() {
return (
<Provider store={store}>
......
......@@ -68,7 +68,7 @@ export default function() {
database.delete(emojiRecord);
}
} catch (e) {
log('err_get_emojis_delete', e);
log(e);
}
});
}
......@@ -77,7 +77,7 @@ export default function() {
);
}
} catch (e) {
log('err_get_custom_emojis', e);
log(e);
return resolve();
}
});
......
......@@ -16,7 +16,7 @@ const create = (permissions) => {
try {
database.create('permissions', permission, true);
} catch (e) {
log('err_get_permissions_create', e);
log(e);
}
});
}
......@@ -65,7 +65,7 @@ export default function() {
database.delete(permission);
}
} catch (e) {
log('err_get_permissions_delete', e);
log(e);
}
});
}
......@@ -74,7 +74,7 @@ export default function() {
);
}
} catch (e) {
log('err_get_permissions', e);
log(e);
return resolve();
}
});
......
......@@ -21,14 +21,14 @@ export default function() {
try {
database.create('roles', role, true);
} catch (e) {
log('err_get_roles_create', e);
log(e);
}
}));
return resolve();
});
}
} catch (e) {
log('err_get_roles', e);
log(e);
return resolve();
}
});
......
......@@ -11,7 +11,7 @@ function updateServer(param) {
try {
database.databases.serversDB.create('servers', { id: reduxStore.getState().server.server, ...param }, true);
} catch (e) {
log('err_get_settings_update_server', e);
log(e);
}
});
}
......@@ -34,7 +34,7 @@ export default async function() {
try {
database.create('settings', { ...setting, _updatedAt: new Date() }, true);
} catch (e) {
log('err_get_settings_create', e);
log(e);
}
if (setting._id === 'Site_Name') {
......@@ -61,6 +61,6 @@ export default async function() {
updateServer.call(this, { iconURL });
}
} catch (e) {
log('err_get_settings', e);
log(e);
}
}
......@@ -29,7 +29,7 @@ export default function() {
});
}
} catch (e) {
log('err_get_slash_command', e);
log(e);
return resolve();
}
});
......
......@@ -13,8 +13,8 @@ async function load({ rid: roomId, latest, t }) {
return [];
}
return data.messages;
} catch (error) {
console.log(error);
} catch (e) {
log(e);
return [];
}
}
......@@ -52,7 +52,7 @@ export default function loadMessagesForRoom(...args) {
database.create('threadMessages', message, true);
}
} catch (e) {
log('err_load_messages_for_room_create', e);
log(e);
}
}));
return resolve(data);
......@@ -61,7 +61,7 @@ export default function loadMessagesForRoom(...args) {
return resolve([]);
}
} catch (e) {
log('err_load_messages_for_room', e);
log(e);
reject(e);
}
});
......
......@@ -45,7 +45,7 @@ export default function loadMissedMessages(...args) {
database.create('threadMessages', message, true);
}
} catch (e) {
log('err_load_missed_messages_create', e);
log(e);
}
}));
});
......@@ -65,14 +65,14 @@ export default function loadMissedMessages(...args) {
});
});
} catch (e) {
log('err_load_missed_messages_delete', e);
log(e);
}
});
}
}
resolve();
} catch (e) {
log('err_load_missed_messages', e);
log(e);
reject(e);
}
});
......
......@@ -34,7 +34,7 @@ export default function loadThreadMessages({ tmid, offset = 0 }) {
message.rid = tmid;
database.create('threadMessages', message, true);
} catch (e) {
log('err_load_thread_messages_create', e);
log(e);
}
}));
return resolve(data);
......@@ -43,7 +43,7 @@ export default function loadThreadMessages({ tmid, offset = 0 }) {
return resolve([]);
}
} catch (e) {
log('err_load_thread_messages', e);
log(e);
reject(e);
}
});
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment