<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>BrowserStack &#8211; Zhijun Chen</title>
	<atom:link href="https://zhijunchen.com/tag/browserstack/feed/" rel="self" type="application/rss+xml" />
	<link>https://zhijunchen.com</link>
	<description></description>
	<lastBuildDate>Fri, 07 Jun 2024 06:29:46 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.5.4</generator>

<image>
	<url>https://zhijunchen.com/wp-content/uploads/2021/03/cropped-my-site-icon-1-32x32.png</url>
	<title>BrowserStack &#8211; Zhijun Chen</title>
	<link>https://zhijunchen.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Using CircleCI, Expo EAS, BrowserStack to build React Native Application Deployment Pipeline</title>
		<link>https://zhijunchen.com/using-circleci-expo-eas-browserstack-to-build-react-native-application-deployment-pipeline/</link>
		
		<dc:creator><![CDATA[Zhijun Chen]]></dc:creator>
		<pubDate>Tue, 16 Aug 2022 08:32:47 +0000</pubDate>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[BrowserStack]]></category>
		<category><![CDATA[CircleCI]]></category>
		<category><![CDATA[Expo]]></category>
		<category><![CDATA[React Native]]></category>
		<guid isPermaLink="false">https://zhijunchen.com/?p=186</guid>

					<description><![CDATA[I recently got a chance to work within a Frontend team which delivers iOS and Android applications to our customers. One of the pain point in the team was the difficulty in app testing and release so I spent some time on investigating the best approach for the team. The team is using React Native [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p style="font-size:18px">I recently got a chance to work within a Frontend team which delivers iOS and Android applications to our customers. One of the pain point in the team was the difficulty in app testing and release so I spent some time on investigating the best approach for the team. The team is using <a rel="noreferrer noopener" href="https://reactnative.dev/" target="_blank">React Native</a> based <a rel="noreferrer noopener" href="https://expo.dev/" target="_blank">Expo</a> and at this stage highly replying on manual testing on physical devices. They are currently putting efforts on automated testing based on <a rel="noreferrer noopener" href="https://wix.github.io/Detox/" target="_blank">Detox</a>.</p>



<h2 class="wp-block-heading">Expo EAS</h2>



<p style="font-size:18px">Expo provides a React Native build tool called <a rel="noreferrer noopener" href="https://expo.dev/eas" target="_blank">Expo Application Services (EAS)</a>, it allows you to build and submit applications easily. By default when you run <code>eas build</code>, it will create a build on their cloud services and you will have to pay for priority pipeline execution. The Free plan at the time of writing only allows you to build one pipeline at a time. In our case we already have <a rel="noreferrer noopener" href="https://circleci.com/" target="_blank">CircleCI</a> subscription so it would be better if we can build app bundles there. Fortunately there is a <code>--local</code> option which allows building app bundles locally. You will still need to set up EAS on Expo, for detail guide, please refer to their <a rel="noreferrer noopener" href="https://docs.expo.dev/build/setup/" target="_blank">setup guide</a>. Here is an example command we use to build our app bundles using CircleCI MacOS and JVM executor.</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash">eas build --profile preview --platform ios --clear-cache --local --non-interactive --output "my-app.ipa"</code></pre>



<p style="font-size:18px">We use <code>eas submit</code> to automatically push master/production build to app store and play store after manual approval. The key here is that for BrowserStack we need to use internal distribution profile so that we can install on their devices. You don&#8217;t have to add their remote devices to Expo as BrowserStack re-signs the bundles upon upload so that they can be installed on their devices.</p>



<h2 class="wp-block-heading">BrowserStack</h2>



<p style="font-size:18px">To make current manual testing easier I decided to introduce <a rel="noreferrer noopener" href="https://www.browserstack.com/docs/app-live" target="_blank">BrowserStack App Live</a>, it allows the team to test the app using remote real devices and it offers quite a lot of iOS and Android options. It also comes with <a rel="noreferrer noopener" href="https://www.browserstack.com/docs/local-testing" target="_blank">local testing</a> which allows us to connect to our backend services hosted behind our vpn. There are some options for getting access to the app. You can upload app <code>.ipa</code> and <code>.apk</code> bundles, or install via <a href="https://apps.apple.com/us/app/testflight/id899247664">Apple TestFlight</a> and <a rel="noreferrer noopener" href="https://play.google.com/store/" target="_blank">Google Play</a>. To test push notification, please refer to guide <a rel="noreferrer noopener" href="https://www.browserstack.com/question/40307" target="_blank">here</a>. If you are uploading the <code>.ipa</code> Apple bundle, unfortunately it is not supported at the time of writing, the only way to test push notification on iOS is installation via TestFlight.</p>



<h2 class="wp-block-heading">Overall Pipeline View</h2>



<p style="font-size:18px">Here is what our overall pipeline looks like:</p>



<figure class="wp-block-image size-large"><img fetchpriority="high" decoding="async" width="1024" height="441" src="https://zhijunchen.com/wp-content/uploads/2022/08/tutor-app-pipeline-1024x441.png" alt="" class="wp-image-193" srcset="https://zhijunchen.com/wp-content/uploads/2022/08/tutor-app-pipeline-1024x441.png 1024w, https://zhijunchen.com/wp-content/uploads/2022/08/tutor-app-pipeline-300x129.png 300w, https://zhijunchen.com/wp-content/uploads/2022/08/tutor-app-pipeline-768x331.png 768w, https://zhijunchen.com/wp-content/uploads/2022/08/tutor-app-pipeline.png 1372w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p style="font-size:18px">For branch build we have a manual trigger to push bundles to BrowserStack as we don&#8217;t want every commit to go through manual QA process. We only trigger this once the PR has been reviewed and ready for QA. The bundles are also uploaded to S3 so that we can retrieve them and install locally easily. You will need to register your test physical devices with Expo using <code>eas device:create</code> so that the bundles can be installed. See internal distribution setup <a href="https://docs.expo.dev/build/internal-distribution/" target="_blank" rel="noreferrer noopener">here</a>.</p>



<p style="font-size:18px">For master/main branch build we went through the similar process with the only difference that builds are automatically pushed to BrowserStack with a manual trigger to push to production following production profile build. We use <a rel="noreferrer noopener" href="https://github.com/conventional-changelog/standard-version" target="_blank">standard-version</a> to automatically increase our app version so that every build is able to be released. The BrowserStack preview here is quite useful during our review session and following that we will decide whether the candidate version is good enough for release.</p>



<h2 class="wp-block-heading">CircleCI config</h2>



<p style="font-size:18px">Here are some useful CircleCI steps for the pipeline described above:</p>



<h5 class="wp-block-heading">Build Android Using OpenJDK executor</h5>



<pre class="wp-block-code"><code lang="yaml" class="language-yaml">eas-build-android:
    executor: android
    parameters:
      profile: 
        description: distribution profile
        type: string
        default: preview
    environment:
      PROFILE: &lt;&lt; parameters.profile &gt;&gt;
    steps:
      - attach_workspace:
          at: ~/
      - node/install:
          install-yarn: true
          node-version: '16.9.1'
      - run: echo -n $PLAY_STORE_SERVICE_ACCOUNT_KEY | base64 -d  &gt; serviceAccountKey.json        
      - run:
          name: android build
          command: |
            mkdir android_sdk
            curl -O https://dl.google.com/android/repository/commandlinetools-linux-8512546_latest.zip
            unzip commandlinetools-linux-8512546_latest.zip
            mv cmdline-tools android_sdk
            mkdir -p android_sdk/cmdline-tools/tools
            mv -t android_sdk/cmdline-tools/tools android_sdk/cmdline-tools/lib android_sdk/cmdline-tools/bin android_sdk/cmdline-tools/source.properties android_sdk/cmdline-tools/NOTICE.txt
            export ANDROID_SDK_ROOT=$HOME/project/android_sdk
            yes | $ANDROID_SDK_ROOT/cmdline-tools/tools/bin/sdkmanager --licenses || if [[ $? -eq 141 ]]; then true; else exit $?; fi
            npm install -g expo-cli eas-cli
            npm ci
            eas build --profile &lt;&lt; parameters.profile &gt;&gt; --platform android --clear-cache --local --non-interactive --output "${CIRCLE_BRANCH//\//-}-${PROFILE}-${CIRCLE_SHA1:0:7}.apk"</code></pre>



<h5 class="wp-block-heading">Build iOS using MacOS executor</h5>



<pre class="wp-block-code"><code lang="yaml" class="language-yaml">  eas-build-ios:
    executor: ios
    parameters:
      profile: 
        description: eas profile
        type: string
        default: preview
    environment:
      PROFILE: &lt;&lt; parameters.profile &gt;&gt;
    steps:
      - attach_workspace:
          at: ~/
      - node/install:
          install-yarn: true
          node-version: '16.9.1'
      - run:
          name: ios build
          command: |
            npm install -g expo-cli eas-cli
            npm ci
            eas build --profile &lt;&lt; parameters.profile &gt;&gt; --platform ios --clear-cache --local --non-interactive --output "${CIRCLE_BRANCH//\//-}-${PROFILE}-${CIRCLE_SHA1:0:7}.ipa"</code></pre>



<p style="font-size:18px">We are using <a href="https://circleci.com/developer/orbs/orb/circleci/node">CircleCI NodeJS Orbs</a> to install NodeJS on the executors. For Android we pass in service account key from pipeline secret and need to download <a rel="noreferrer noopener" href="https://developer.android.com/studio/command-line" target="_blank">Command Line Tools</a> too.</p>



<p style="font-size:18px">Overall the pipeline works quite well for us and we have significant improvements on development process. Now product manager/designer and manual QA could easily download the bundle and play with the app on either BrowserStack or our test physical devices.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
