{"id":"l-rn-5-3","courseId":"react-native-apps","lang":"en","kind":"lesson","summary":"Configure Trailhead’s identity and versions, create development, preview and production builds with EAS Build, send them to TestFlight and Google Play with EAS Submit, and prepare for app review.","html":"<p>So far Trailhead has run through Expo Go and development builds, with your laptop serving the JavaScript. Real users need something else: an app that installs from a store, starts without a dev server, and is signed so their phone trusts it. <strong>EAS Build</strong> makes those builds in the cloud, so you don’t need a Mac for iOS, and <strong>EAS Submit</strong> uploads them to the stores.</p>\n<h2 id=\"sec-1\" tabindex=\"-1\">Identity and versions in app.json</h2>\n<p>Before the first build, settle a few fields:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"json\" data-index=\"0\"><div class=\"code-head\"><span class=\"code-title\">app.json</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"Copy code\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>Copy</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">{</span></span>\n<span class=\"line\"><span style=\"color:#116329;--shiki-dark:#7EE787\">  \"expo\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: {</span></span>\n<span class=\"line\"><span style=\"color:#116329;--shiki-dark:#7EE787\">    \"name\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Trailhead\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">,</span></span>\n<span class=\"line\"><span style=\"color:#116329;--shiki-dark:#7EE787\">    \"slug\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"trailhead\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">,</span></span>\n<span class=\"line\"><span style=\"color:#116329;--shiki-dark:#7EE787\">    \"version\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"1.0.0\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">,</span></span>\n<span class=\"line\"><span style=\"color:#116329;--shiki-dark:#7EE787\">    \"scheme\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"trailhead\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">,</span></span>\n<span class=\"line\"><span style=\"color:#116329;--shiki-dark:#7EE787\">    \"icon\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"./assets/images/icon.png\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">,</span></span>\n<span class=\"line\"><span style=\"color:#116329;--shiki-dark:#7EE787\">    \"ios\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: { </span><span style=\"color:#116329;--shiki-dark:#7EE787\">\"bundleIdentifier\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"com.example.trailhead\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> },</span></span>\n<span class=\"line\"><span style=\"color:#116329;--shiki-dark:#7EE787\">    \"android\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: { </span><span style=\"color:#116329;--shiki-dark:#7EE787\">\"package\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"com.example.trailhead\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> }</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">  }</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">}</span></span></code></pre></div>\n<p>The <strong>bundle identifier</strong> (iOS) and <strong>package name</strong> (Android) are your app’s permanent identity in the stores. Change them after publishing and the store sees a different app: no updates for existing users, no reviews carried over. Use a reverse domain you control.</p>\n<p>There are two kinds of version. <code dir=\"ltr\">version</code> is what users see (“1.0.0”); you raise it for each public release. Each upload also needs a unique, increasing internal number (the iOS build number and Android version code). Let EAS manage those for you, as shown below.</p>\n<h2 id=\"sec-2\" tabindex=\"-1\">Build profiles</h2>\n<p>Install the CLI, sign in to your Expo account and generate the config:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"bash\" data-index=\"1\"><div class=\"code-head\"><span class=\"code-title\">Terminal</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"Copy code\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>Copy</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#953800;--shiki-dark:#FFA657\">npm</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> install</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> -g</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> eas-cli</span></span>\n<span class=\"line\"><span style=\"color:#953800;--shiki-dark:#FFA657\">eas</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> login</span></span>\n<span class=\"line\"><span style=\"color:#953800;--shiki-dark:#FFA657\">eas</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> build:configure</span></span></code></pre></div>\n<p>That creates <code dir=\"ltr\">eas.json</code> with three profiles:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"json\" data-index=\"2\"><div class=\"code-head\"><span class=\"code-title\">eas.json</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"Copy code\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>Copy</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">{</span></span>\n<span class=\"line\"><span style=\"color:#116329;--shiki-dark:#7EE787\">  \"cli\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: { </span><span style=\"color:#116329;--shiki-dark:#7EE787\">\"appVersionSource\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"remote\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> },</span></span>\n<span class=\"line\"><span style=\"color:#116329;--shiki-dark:#7EE787\">  \"build\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: {</span></span>\n<span class=\"line\"><span style=\"color:#116329;--shiki-dark:#7EE787\">    \"development\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: { </span><span style=\"color:#116329;--shiki-dark:#7EE787\">\"developmentClient\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">true</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#116329;--shiki-dark:#7EE787\">\"distribution\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"internal\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> },</span></span>\n<span class=\"line\"><span style=\"color:#116329;--shiki-dark:#7EE787\">    \"preview\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: { </span><span style=\"color:#116329;--shiki-dark:#7EE787\">\"distribution\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"internal\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> },</span></span>\n<span class=\"line\"><span style=\"color:#116329;--shiki-dark:#7EE787\">    \"production\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: { </span><span style=\"color:#116329;--shiki-dark:#7EE787\">\"autoIncrement\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">true</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> }</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">  },</span></span>\n<span class=\"line\"><span style=\"color:#116329;--shiki-dark:#7EE787\">  \"submit\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: { </span><span style=\"color:#116329;--shiki-dark:#7EE787\">\"production\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: {} }</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">}</span></span></code></pre></div>\n<ul>\n<li><strong>development</strong> builds your own dev client (the development build from section 1), with the dev menu, loading JavaScript from Metro.</li>\n<li><strong>preview</strong> builds a standalone app for testers, installed from a link or QR code (internal distribution). On iOS, testers’ devices must be registered first with <code dir=\"ltr\">eas device:create</code>, because these are ad hoc builds.</li>\n<li><strong>production</strong> builds for the stores. With <code dir=\"ltr\">appVersionSource: &quot;remote&quot;</code> and <code dir=\"ltr\">autoIncrement</code>, EAS stores and raises the build number on every production build.</li>\n</ul>\n<p>Then build:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"bash\" data-index=\"3\"><div class=\"code-head\"><span class=\"code-title\">Terminal</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"Copy code\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>Copy</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#953800;--shiki-dark:#FFA657\">eas</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> build</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> --platform</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> android</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> --profile</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> preview</span></span>\n<span class=\"line\"><span style=\"color:#953800;--shiki-dark:#FFA657\">eas</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> build</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> --platform</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> all</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> --profile</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> production</span></span></code></pre></div>\n<p>The build runs on EAS servers; the CLI prints a link to the logs and, at the end, to the build itself.</p>\n<figure class=\"diagram\"><svg class=\"diagram-svg\" focusable=\"false\" viewBox=\"0 0 690 220\" role=\"img\" aria-labelledby=\"l-rn-5-3-t1\"><defs><marker id=\"arrow-l-rn-5-3-1\" viewBox=\"0 0 10 10\" refX=\"9\" refY=\"5\" markerWidth=\"7\" markerHeight=\"7\" orient=\"auto-start-reverse\"><path d=\"M0 0 L10 5 L0 10 z\" class=\"d-arrowhead\"/></marker></defs>\n  <title id=\"l-rn-5-3-t1\">Source code goes through eas build to a signed binary. Preview builds go to testers by link. Production builds go through eas submit to TestFlight or a Google Play testing track, then app review, then release.</title>\n  <rect class=\"d-box\" x=\"10\" y=\"80\" width=\"100\" height=\"56\" rx=\"10\"/>\n  <text class=\"d-label-strong\" x=\"60\" y=\"113\" text-anchor=\"middle\">code</text>\n  <path class=\"d-arrow\" d=\"M110 108 L150 108\" marker-end=\"url(#arrow-l-rn-5-3-1)\"/>\n  <rect class=\"d-box-primary\" x=\"155\" y=\"80\" width=\"120\" height=\"56\" rx=\"10\"/>\n  <text class=\"d-code\" x=\"215\" y=\"113\" text-anchor=\"middle\">eas build</text>\n  <path class=\"d-arrow\" d=\"M275 95 L330 45\" marker-end=\"url(#arrow-l-rn-5-3-1)\"/>\n  <rect class=\"d-box-accent\" x=\"335\" y=\"18\" width=\"150\" height=\"50\" rx=\"10\"/>\n  <text class=\"d-label\" x=\"410\" y=\"48\" text-anchor=\"middle\">preview → testers</text>\n  <path class=\"d-arrow\" d=\"M275 120 L330 160\" marker-end=\"url(#arrow-l-rn-5-3-1)\"/>\n  <rect class=\"d-box-primary\" x=\"335\" y=\"140\" width=\"120\" height=\"50\" rx=\"10\"/>\n  <text class=\"d-code\" x=\"395\" y=\"170\" text-anchor=\"middle\">eas submit</text>\n  <path class=\"d-arrow\" d=\"M455 165 L490 165\" marker-end=\"url(#arrow-l-rn-5-3-1)\"/>\n  <rect class=\"d-box-warn\" x=\"495\" y=\"140\" width=\"85\" height=\"50\" rx=\"10\"/>\n  <text class=\"d-label\" x=\"537\" y=\"162\" text-anchor=\"middle\">TestFlight</text>\n  <text class=\"d-label\" x=\"537\" y=\"180\" text-anchor=\"middle\">/ track</text>\n  <path class=\"d-arrow\" d=\"M580 165 L605 165\" marker-end=\"url(#arrow-l-rn-5-3-1)\"/>\n  <rect class=\"d-box-success\" x=\"610\" y=\"140\" width=\"75\" height=\"50\" rx=\"10\"/>\n  <text class=\"d-label\" x=\"647\" y=\"162\" text-anchor=\"middle\">review</text>\n  <text class=\"d-label\" x=\"647\" y=\"180\" text-anchor=\"middle\">→ live</text>\n</svg><figcaption>From source to the stores</figcaption></figure>\n<h2 id=\"sec-3\" tabindex=\"-1\">Credentials</h2>\n<p>Every installable build is <strong>signed</strong>. iOS needs a distribution certificate and provisioning profile; Android needs an upload keystore. EAS can generate these, store them, and reuse them for every build; the CLI asks the first time. For iOS you need a paid Apple Developer Program membership; for Google Play, a one-time developer registration fee. Treat the Android keystore with care: EAS keeps it for you, but if you manage your own and lose it, updating the app gets painful.</p>\n<h2 id=\"sec-4\" tabindex=\"-1\">Submitting to the stores</h2>\n<p>First create the app’s record in App Store Connect and in Google Play Console. Then upload the latest production build:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"bash\" data-index=\"4\"><div class=\"code-head\"><span class=\"code-title\">Terminal</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"Copy code\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>Copy</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#953800;--shiki-dark:#FFA657\">eas</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> submit</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> --platform</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> ios</span></span>\n<span class=\"line\"><span style=\"color:#953800;--shiki-dark:#FFA657\">eas</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> submit</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> --platform</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> android</span></span></code></pre></div>\n<p>On iOS the build goes to App Store Connect, where it becomes available in <strong>TestFlight</strong> for testers after processing. On Android it lands on a testing track (internal by default); EAS needs a Google service account key to upload for you. You can combine both steps with <code dir=\"ltr\">eas build --auto-submit</code>.</p>\n<aside class=\"callout callout-tip\" role=\"note\"><p class=\"callout-title\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5\"/><path d=\"M9 18h6\"/><path d=\"M10 22h4\"/></svg><span><span class=\"callout-kind\">Tip</span><span class=\"callout-sep\" aria-hidden=\"true\"> · </span>Test the production build, not just the dev build</span></p>\n<p>Release builds behave differently: no dev menu, minified code, real permission strings, and no Metro to paper over a missing asset. Install the TestFlight or internal-track build on a real phone and walk through the main flows before you press release.</p>\n</aside>\n<h2 id=\"sec-5\" tabindex=\"-1\">Getting through review</h2>\n<p>Both stores review apps, Apple more strictly. You’ll fill in a store listing (name, description, screenshots for required device sizes), a privacy policy URL, and privacy details: Apple’s App Privacy section and Google Play’s Data safety form, which must match what Trailhead actually collects, such as location and photos.</p>\n<aside class=\"callout callout-mistake\" role=\"note\"><p class=\"callout-title\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3\"/><path d=\"M12 9v4\"/><path d=\"M12 17h.01\"/></svg><span><span class=\"callout-kind\">Common mistake</span><span class=\"callout-sep\" aria-hidden=\"true\"> · </span>Submitting without a reviewer’s way in</span></p>\n<p>Trailhead requires an account. If the reviewer can’t sign in, the app is rejected, however polished it is. Provide a demo account in the review notes. The other common first-time rejections: crashes on launch, permission descriptions that don’t say why, and features that don’t work, such as broken links or placeholder screens.</p>\n</aside>\n<p>Reviews usually take from a few hours to a couple of days. Once approved, you choose when to release. Then the cycle repeats for every native change: new version, build, submit, review. For JavaScript-only fixes there’s a faster path, which is the final lesson.</p>\n","toc":[{"id":"sec-1","text":"Identity and versions in app.json","level":2},{"id":"sec-2","text":"Build profiles","level":2},{"id":"sec-3","text":"Credentials","level":2},{"id":"sec-4","text":"Submitting to the stores","level":2},{"id":"sec-5","text":"Getting through review","level":2}],"takeaways":["A release build compiles the native app, bundles and minifies your JavaScript, and signs it with credentials the stores trust.","The iOS bundle identifier and Android package name are permanent once you publish; choose them deliberately.","eas.json profiles describe builds: <code dir=\"ltr\">development</code> for your dev client, <code dir=\"ltr\">preview</code> for testers, <code dir=\"ltr\">production</code> for the stores.","<code dir=\"ltr\">eas submit</code> uploads a production build to App Store Connect or Google Play; testers get it through TestFlight or a testing track before review.","Most first rejections come from crashes, vague permission text, missing privacy details or no demo account for a sign-in-only app."],"further":[{"title":"EAS Build","url":"https://docs.expo.dev/build/introduction/"},{"title":"Configure EAS Build with eas.json","url":"https://docs.expo.dev/build/eas-json/"},{"title":"EAS Submit","url":"https://docs.expo.dev/submit/introduction/"},{"title":"App Store Review Guidelines","url":"https://developer.apple.com/app-store/review/guidelines/"}],"quiz":[{"q":"<p>After Trailhead is on the App Store, a teammate wants to change the iOS bundle identifier to match a new company name. What happens if you do?</p>","options":[{"text":"The store treats it as a brand-new app, so existing users don’t get the update and your reviews and ratings stay with the old listing.","why":"Correct. The bundle identifier (and Android package name) is the app’s permanent identity in the stores."},{"text":"The App Store renames the listing automatically after review.","why":"Display names can change; identifiers can’t. A new identifier means a new app."},{"text":"Nothing, as long as the version number goes up.","why":"Versions order releases of the same app. A different identifier isn’t the same app."}],"answer":0},{"q":"<p>You want five hikers in your club to try Trailhead before it goes to the stores, installing it from a link. Which build fits?</p>","options":[{"text":"A <code dir=\"ltr\">development</code> build, since it has the dev menu for feedback.","why":"Development builds need your Metro server running to load JavaScript, so testers can’t use them on their own."},{"text":"A <code dir=\"ltr\">production</code> build installed from the App Store.","why":"Production builds go through store review and public release; that’s the step after testing."},{"text":"Expo Go with your project’s QR code.","why":"Expo Go can’t include Trailhead’s native configuration, like its URL scheme and permission strings, and testers would need your dev server."},{"text":"A <code dir=\"ltr\">preview</code> build with internal distribution, shared through the link EAS gives you.","why":"Correct. Internal distribution is designed for this; on iOS, testers’ devices must first be registered for ad hoc builds."}],"answer":3},{"q":"<p>What does <code dir=\"ltr\">autoIncrement</code> in the production profile take care of?</p>","options":[{"text":"It raises the user-facing version, like 1.2.0 to 1.3.0, on every build.","why":"The user-facing version is yours to choose; <code dir=\"ltr\">autoIncrement</code> handles the internal build number."},{"text":"It bumps the iOS build number and Android version code for each build, which the stores require to be unique.","why":"Correct. Each upload needs a higher build number even when the visible version stays the same."},{"text":"It increments the Expo SDK version on each build.","why":"SDK upgrades are deliberate changes to your dependencies, never automatic."}],"answer":1}],"exercise":{"kind":"order","items":["set-identity","configure","preview","production-build","submit","store-test","review","release"],"title":"Put Trailhead's first release in order","prompt":"<p>Trailhead 1.0.0 is feature-complete and tested. Arrange the steps of its first release to the App Store and Google Play in the order you’d do them.</p>\n","hints":["You can’t build anything until the app knows its permanent identity and EAS knows which profiles exist.","Testers see a preview build before anything goes to the stores.","Store review happens after the production build has been uploaded and checked on real phones."],"explanation":"<p>Identity comes first because it’s permanent, then <code dir=\"ltr\">eas build:configure</code> creates the profiles every later command uses. A preview build lets real hikers find problems before the stores are involved. The production build is uploaded with <code dir=\"ltr\">eas submit</code>, checked once more as a real release build through TestFlight or the internal track, and only then sent for review with the listing, privacy details and demo account in place. Release is the last, deliberate step: approval doesn’t have to mean shipping that minute.</p>\n","checkLabels":{},"itemText":{"set-identity":"Set <code dir=\"ltr\">ios.bundleIdentifier</code>, <code dir=\"ltr\">android.package</code> and <code dir=\"ltr\">version</code> in app.json","configure":"Run <code dir=\"ltr\">eas build:configure</code> to create eas.json with build profiles","preview":"Make a <code dir=\"ltr\">preview</code> build and share it with a few hikers through internal distribution","production-build":"Run <code dir=\"ltr\">eas build --platform all --profile production</code>","submit":"Run <code dir=\"ltr\">eas submit</code> to upload the builds to App Store Connect and Google Play","store-test":"Install the TestFlight and internal-track builds on real phones and walk through the main flows","review":"Complete the store listing, privacy details and demo account, then submit for review","release":"Release the approved version to users"}},"words":661,"readMinutes":3}