diff --git a/astro.config.mjs b/astro.config.mjs index c280a615..16e27dd4 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -109,6 +109,12 @@ export default defineConfig({ directory: 'ci', }, }, + { + label: 'Crash Reporting', + autogenerate: { + directory: 'guides/crash-reporting', + }, + }, { label: 'Flutter Version', link: '/flutter-version', @@ -170,6 +176,7 @@ export default defineConfig({ 'guides/add-to-app/ios': 'guides/hybrid-apps/ios', 'guides/code_push_add_to_app': 'guides/hybrid-apps/android', 'guides/code_push_quickstart': 'guides/code-push-quickstart', + 'guides/crash-reporting': 'guides/crash-reporting/uploading-symbols', 'guides/fastlane': 'ci/fastlane', 'guides/flavors': 'guides/flavors/android', 'guides/hybrid-app': 'guides/hybrid-apps/android', diff --git a/package-lock.json b/package-lock.json index f67b8599..382bc112 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2628,11 +2628,12 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "license": "MIT", "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -3516,9 +3517,10 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -4322,6 +4324,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "license": "MIT", "engines": { "node": ">=0.12.0" } @@ -7951,6 +7954,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, diff --git a/src/content/docs/code-push/initialize.mdx b/src/content/docs/code-push/initialize.mdx index 864b8946..a208a592 100644 --- a/src/content/docs/code-push/initialize.mdx +++ b/src/content/docs/code-push/initialize.mdx @@ -54,6 +54,15 @@ Reference the following commands to get started: For more information about Shorebird, visit https://shorebird.dev ``` +:::note +You can supply a display name directly via the command line by passing the `--display-name` flag: + +```sh +shorebird init --display-name "My App" +``` + +::: + The generated `shorebird.yaml` should look similar to: ```yaml diff --git a/src/content/docs/concepts.mdx b/src/content/docs/concepts.mdx index dc9e4c14..ac919a9e 100644 --- a/src/content/docs/concepts.mdx +++ b/src/content/docs/concepts.mdx @@ -37,7 +37,8 @@ This does **not** include: - Asset files (images, fonts, etc.), although we have plans to support this in the near future (see https://github.com/shorebirdtech/shorebird/issues/318). - Native code (e.g. Java/Kotlin on Android or Objective-C/Swift on iOS). -- Flutter engine changes (i.e., changes the Flutter version of your app). +- Flutter engine changes (i.e., you cannot change the Flutter version of your + app using Code Push). ## Glossary @@ -69,6 +70,10 @@ When your application starts, it checks for available patches and applies the la Patches are created by running `shorebird patch [platform]`, where `platform` is `android`, `aar`, or `ios`. +:::note +For more information regarding when to create a patch, refer to our [FAQs](/faq#when-should-i-create-a-patch) +::: + ### Artifact An artifact is the output of a build or patch operation. For example: diff --git a/src/content/docs/faq.mdx b/src/content/docs/faq.mdx index 672af171..d559e182 100644 --- a/src/content/docs/faq.mdx +++ b/src/content/docs/faq.mdx @@ -36,7 +36,8 @@ The following URLs are used by Shorebird: - https://download.shorebird.dev -- used by the `shorebird` command line tool to download Flutter artifacts for building releases and patches. - https://storage.googleapis.com -- used by the `shorebird` command line tool to - upload and download release and patch artifacts. + upload and download release and patch artifacts, and by the Shorebird updater + on user's devices to download the patches. If all of those URLs are accessible from your country, then Shorebird should work. @@ -335,16 +336,14 @@ Shorebird command line tools (e.g. `shorebird patch`) require network connectivity to function. If you are using Shorebird to distribute your app, you should ensure that your CI system has network connectivity. -### What happens if a user doesn't update for a long time and misses an update? +### What happens if a user doesn't update for a long time? -Our implementation always sends an update specifically tailored for the device -that is requesting it updating the requestor always to the latest version -available. Thus if a user doesn't update for a while they will "miss" -intermediate updates. - -The update server could be changed to support responding with either the next -incremental version or the latest version depending on your application's needs. -Please let us know if alternative update behaviors are important to you. +A user will always get the latest patch available for their version of the app, +regardless of which patch (if any) they currently have installed. A patch will +always reflect the state of the codebase at the time when the patch was built so +as long as newer patches also contain the changes from older patches, users will +always be up to date and there is no need to worry about users "missing" +patches. ### How does Shorebird relate to Flutter? @@ -462,6 +461,12 @@ If you'd like to segment availability of Shorebird patches, there are 4 potentia Yes. Apps built with Shorebird will continue to function normally (as if they had been built without Shorebird), including those that have had patches installed. +### When should I create a patch? + +Generally, you should create patches when fixing bugs that **DO NOT** contain native changes or asset changes. For all other changes, you should likely create a new release. + +If distributing through stores, please refer to store policies for additional guidelines. + ## Billing ### How do I upgrade or downgrade my plan? diff --git a/src/content/docs/guides/crash-reporting/Integrations/crashlytics.mdx b/src/content/docs/guides/crash-reporting/Integrations/crashlytics.mdx new file mode 100644 index 00000000..c4c22240 --- /dev/null +++ b/src/content/docs/guides/crash-reporting/Integrations/crashlytics.mdx @@ -0,0 +1,47 @@ +--- +title: Crashlytics Integration +description: Integrate Shorebird into your Crashlytics crash reporting +sidebar: + label: Crashlytics + order: 2 +--- + +If you're using Crashlytics for crash reporting, it will work out-of-the-box +with Shorebird releases and patches. However, if you have multiple patches, it +can be unclear which patch caused the crash. This document shows how you can use +Crashlytics to differentiate between patches. + +## Add the `shorebird_code_push` package to your project. + +[shorebird_code_push](https://pub.dev/packages/shorebird_code_push) is available +on pub.dev and lets you programmatically determine your app's current patch +number. To add it to your project, follow the instructions on the package's +pub.dev page. + +## Configure Crashlytics + +If you haven't already, follow the Crashlytics [getting started with +Flutter](https://firebase.google.com/docs/crashlytics/get-started?platform=flutter) guide. + +Update the Firebase init code to include the patch number as a custom key. This will look +something like: + +```dart +Future main() async { + WidgetsFlutterBinding.ensureInitialized(); + await Firebase.initializeApp( + options: DefaultFirebaseOptions.currentPlatform, + ); + + final patchNumber = await ShorebirdCodePush().currentPatchNumber(); + + // Add the patch number as a tag. You can use whatever name you would like + // as the key. `$patchNumber` will be "null" if there is no patch. You may + // wish to handle this case differently. + FirebaseCrashlytics.instance.setCustomKey( + 'shorebird_patch_number', + '$patchNumber', + ); + runApp(const MyApp()); +} +``` diff --git a/src/content/docs/guides/crash-reporting/Integrations/sentry.mdx b/src/content/docs/guides/crash-reporting/Integrations/sentry.mdx new file mode 100644 index 00000000..2be84537 --- /dev/null +++ b/src/content/docs/guides/crash-reporting/Integrations/sentry.mdx @@ -0,0 +1,49 @@ +--- +title: Sentry Integration +description: Integrate Shorebird into your Sentry crash reporting +sidebar: + label: Sentry + order: 1 +--- + +If you're using Sentry for crash reporting, it will work out-of-the-box with +Shorebird releases and patches. However, if you have multiple patches, it can be +unclear which patch caused the crash. This document shows how you can use Sentry +tags to differentiate between patches. + +## Add the `shorebird_code_push` package to your project. + +[shorebird_code_push](https://pub.dev/packages/shorebird_code_push) is available +on pub.dev and lets you programmatically determine your app's current patch +number. To add it to your project, follow the instructions on the package's +pub.dev page. + +## Configure Sentry + +If you haven't already, follow the Sentry [getting started with +Flutter](https://docs.sentry.io/platforms/flutter/) guide. + +Update the Sentry init code to include the patch number as a tag. This will look +something like: + +```dart +Future main() async { + // Get the current patch number. This will be null if no patch is installed. + final patchNumber = await ShorebirdCodePush().currentPatchNumber(); + + await SentryFlutter.init( + (options) { + options.dsn = 'YOUR_DSN'; + }, + appRunner: () { + // Add the patch number as a tag. You can use whatever name you would like + // as the key. `$patchNumber` will be "null" if there is no patch. You may + // wish to handle this case differently. + Sentry.configureScope((scope) { + scope.setTag('shorebird_patch_number', '$patchNumber'); + }); + return runApp(const MyApp()); + }, + ); +} +``` diff --git a/src/content/docs/guides/crash-reporting.mdx b/src/content/docs/guides/crash-reporting/uploading-symbols.mdx similarity index 96% rename from src/content/docs/guides/crash-reporting.mdx rename to src/content/docs/guides/crash-reporting/uploading-symbols.mdx index 45007b88..3ecdfd74 100644 --- a/src/content/docs/guides/crash-reporting.mdx +++ b/src/content/docs/guides/crash-reporting/uploading-symbols.mdx @@ -1,6 +1,6 @@ --- -title: Crash Reporting -description: Integrating Shorebird with Crash Reporting Tools +title: Uploading Symbols +description: Locating and uploading symbols for crash reporting --- Shorebird uses a fork of Flutter to build your app. This means we've built our diff --git a/src/content/docs/troubleshooting.mdx b/src/content/docs/troubleshooting.mdx index d7738d51..c5e19c56 100644 --- a/src/content/docs/troubleshooting.mdx +++ b/src/content/docs/troubleshooting.mdx @@ -18,6 +18,14 @@ Common causes of this problem are: Patches are only compatible with the release version they were created for. If you create a patch for version `1.0.0+1`, it will not work on version `1.0.0+2`. +:::note +This can happen unexpectedly on iOS due to Xcode's automatic incrementing of +build numbers. If you are seeing this issue on iOS, ensure that the build number +of the release and the patch match. See [our iOS releasing +guide](/guides/release/ios/#upload-to-the-app-store) for instructions on how to +disable automatic build number incrementing. +::: + #### How to tell if this is the problem You will see `Shorebird updater: no active patch` in your device logs. @@ -139,7 +147,7 @@ version and build numbers in order to target patches at specific releases. You can fix this problem by either setting `manageAppVersionAndBuildNumber` to false or removing the value from your export options .plist file. -## I see a `The release artifact contains asset changes` warning when running `shorebird release` (#asset-changes) +## I see a `Your app contains asset changes` warning when running `shorebird patch` The `shorebird patch` command will print a warning if it detects changes to files in your compiled app that correspond to asset changes (e.g. added or @@ -189,10 +197,13 @@ warning, you should be very careful about publishing your patch, as it may cause your app to crash when the Dart code tries to call into native code which operates differently than expected. See {/* cspell:disable-next-line */} -[the next section](#i-see-a-the-release-artifact-contains-native-changes-warning-when-running-shorebird-patch-even-though-i-havent-changed-swiftobjective-ckotlinjava-code). +[the next section](#i-see-a-your-app-contains-native-changes-warning-when-running-shorebird-patch-even-though-i-havent-changed-swiftobjective-ckotlinjava-code). ### What happens if I ignore this warning? +You can bypass this warning by passing the `--allow-asset-diffs` flag to the +`shorebird patch` command. + The consequences of ignoring this warning depend on the changes that were made. In the tree-shaking example above, if you ignore the warning, your app will render incorrectly if you use an icon that was not included in the release @@ -203,7 +214,7 @@ If you are not sure whether your change is safe, you can [stage your patch](/guides/staging-patches) and test locally before deploying it to users. -## I see a `The release artifact contains native changes` warning when running `shorebird patch`, even though I haven't changed Swift/Objective-C/Kotlin/Java code +## I see a `Your app contains native changes` warning when running `shorebird patch`, even though I haven't changed Swift/Objective-C/Kotlin/Java code The `shorebird patch` command will print a warning if it detects changes to files in your compiled app that correspond to native code changes (`.dex` files @@ -229,6 +240,16 @@ This can be caused by a number of things. The most common causes are: use caution when publishing patches that include changes to native code from plugins. In the worst case, these changes may cause your patched app to crash.** + :::tip + Add your `pubspec.lock` file to version control so you're always aware of + updates to your dependencies. + + Versioning your `pubspec.lock` file ensures changes to transitive + dependencies are explicit. Each time the dependencies change due to + `dart pub upgrade` or a change in `pubspec.yaml`, the difference will be + apparent in the lock file. + ::: + 2. A dependency/plugin produces a different output on every build. This can happen if the dependency it includes a timestamp indicating when it was built, for example. This kind of change is usually safe to publish, but you @@ -250,6 +271,9 @@ This can be caused by a number of things. The most common causes are: ### What happens if I ignore this warning? +You can bypass this warning by passing the `--allow-native-diffs` flag to the +`shorebird patch` command. + If the changes are to native code that interacts with your Flutter app or with Flutter itself, **your app will crash**. If the native code that changed does not interact with your Dart code or Flutter at all, the patch should run without