diff --git a/config/docs.php b/config/docs.php index 92c545a15..671d731a4 100644 --- a/config/docs.php +++ b/config/docs.php @@ -59,7 +59,7 @@ 1 => ['1.0', '1.1'], 2 => ['2.0'], 3 => ['3.0', '3.1', '3.2', '3.3'], - 4 => ['4.0', '4.1', '4.2'], + 4 => ['4.0', '4.1', '4.2', '4.5'], ], ], diff --git a/resources/views/docs/mobile/4/getting-started/upgrade-guide.md b/resources/views/docs/mobile/4/getting-started/upgrade-guide.md index ea88aa4a7..0ee11579d 100644 --- a/resources/views/docs/mobile/4/getting-started/upgrade-guide.md +++ b/resources/views/docs/mobile/4/getting-started/upgrade-guide.md @@ -3,6 +3,18 @@ title: Upgrade Guide order: 3 --- +## Upgrading To 4.5 From 4.4 + +### Public releases need `APP_ENV=production` + +From 4.5, only a build packaged with `APP_ENV=production` can be released to the public. Any other `APP_ENV` makes a +testing build: Google Play holds it to the internal and closed testing tracks, and the App Store limits it to +TestFlight's internal testers. + +If you've been packaging store releases with Laravel's default `APP_ENV=local`, set `APP_ENV=production` in your +`.env` before you package your next release. See +[Production and testing builds](../publishing/introduction#production-and-testing-builds). + ## Upgrading To 4.0 From 3.x v4's headline is [SuperNative](../architecture/super-native) — fully native UI. Most of the release is additive, diff --git a/resources/views/docs/mobile/4/publishing/android.md b/resources/views/docs/mobile/4/publishing/android.md index a36d43523..7889717f8 100644 --- a/resources/views/docs/mobile/4/publishing/android.md +++ b/resources/views/docs/mobile/4/publishing/android.md @@ -98,10 +98,19 @@ php artisan native:package android \ The `--play-store-track` option controls where the build is released: - `internal` - Internal testing (default, fastest review) -- `alpha` - Closed alpha testing -- `beta` - Closed beta testing +- `alpha` - Closed testing +- `beta` - Open testing - `production` - Production release +### Releasing to production + + + +Only a build packaged with `APP_ENV=production` can be released on the `beta` or `production` tracks. A build packaged +with any other `APP_ENV` is a [testing build](introduction#production-and-testing-builds), which Google Play holds to +the `internal` and `alpha` tracks. If you ask for the `production` track, `native:package` stops before uploading and +tells you which `APP_ENV` the build was made with. + ## Testing Play Store Uploads If you already have an AAB file and want to test uploading without rebuilding, use `--test-push`: @@ -209,6 +218,7 @@ php artisan native:package android \ - Verify the Google Service Account has access to your app in Play Console - Ensure the service account key file is valid and readable - Check that your bundle ID matches your Play Console app ID +- For the `beta` or `production` tracks, package with `APP_ENV=production` (see [Releasing to production](#releasing-to-production)) ## Artifact Locations diff --git a/resources/views/docs/mobile/4/publishing/introduction.md b/resources/views/docs/mobile/4/publishing/introduction.md index a1d8a7530..c99b148ef 100644 --- a/resources/views/docs/mobile/4/publishing/introduction.md +++ b/resources/views/docs/mobile/4/publishing/introduction.md @@ -102,6 +102,38 @@ submit it to the stores for approval and distribution. - [Google Play Store submission guidelines](https://support.google.com/googleplay/android-developer/answer/9859152?hl=en-GB#zippy=%2Cmaximum-size-limit) - [Apple App Store submission guidelines](https://developer.apple.com/ios/submit/) +## Production and testing builds + + + +The `APP_ENV` in your `.env` when you package your app decides how far that build can be released. Only a build +packaged with `APP_ENV=production` can be released to the public. Any other value, such as `local` or `staging`, makes +it a testing build, and NativePHP tells both stores so: + +- **Play Store:** the build declares closed testing as the largest audience it may reach. It can go to the internal and + closed testing tracks, but Google Play won't release it on the open testing or production tracks. +- **App Store:** the build is marked for TestFlight internal testing only. Your internal testers can install it, but it + can't be sent to external testers or submitted for App Store review. + +This is written into the build itself, so a testing build can't be promoted to a public release later. + +New Laravel apps start with `APP_ENV=local`, so set it before you package a release: + +```env +APP_ENV=production +``` + +Your `.env` is bundled into the app, so it runs in the same environment on the device. + + + ## Packaging Your App The `native:package` command creates signed, production-ready apps for distribution to the App Store and Play Store. @@ -118,3 +150,4 @@ Before you can package your app for distribution, ensure: 3. For Android: You have a signing keystore with a valid key alias 4. For iOS: You have the necessary signing certificates and provisioning profiles from Apple Developer 5. All configuration is complete (see the [configuration guide](../getting-started/configuration)) +6. For a public release, your `.env` has `APP_ENV=production` (see [Production and testing builds](#production-and-testing-builds)) diff --git a/resources/views/docs/mobile/4/publishing/ios.md b/resources/views/docs/mobile/4/publishing/ios.md index 5d258e6ba..30e3cef69 100644 --- a/resources/views/docs/mobile/4/publishing/ios.md +++ b/resources/views/docs/mobile/4/publishing/ios.md @@ -55,6 +55,17 @@ php artisan native:package ios \ --team-id=ABC1234567 ``` +### Testing builds + + + +An `app-store` build packaged with any `APP_ENV` other than `production` is a +[testing build](introduction#production-and-testing-builds), marked for TestFlight internal testing only. It uploads to +App Store Connect as usual and your internal testers can install it, but it can't be sent to external testers or +submitted for App Store review. Package it again with `APP_ENV=production` when you're ready to release. + +Ad-hoc, enterprise and development builds don't go through TestFlight, so `APP_ENV` doesn't limit them. + ## Building for Ad-Hoc Distribution For distributing to specific devices without going through the App Store: diff --git a/tests/Feature/Docs/PublishingAppEnvTest.php b/tests/Feature/Docs/PublishingAppEnvTest.php new file mode 100644 index 000000000..f4b4ecce6 --- /dev/null +++ b/tests/Feature/Docs/PublishingAppEnvTest.php @@ -0,0 +1,66 @@ + 'test-token']); + Http::fake([ + '*' => Http::response(['blocks' => []], 200), + ]); + } + + public function test_publishing_introduction_explains_that_only_production_builds_reach_the_public(): void + { + $this->withoutVite() + ->get('/docs/mobile/4/publishing/introduction') + ->assertOk() + ->assertSee('id="production-and-testing-builds"', false) + ->assertSee('>4.5<', false) + ->assertSee('APP_ENV=production') + ->assertSee('TestFlight internal testing only') + ->assertSee('#production-and-testing-builds', false); + } + + public function test_android_page_keeps_testing_builds_off_the_open_and_production_tracks(): void + { + $this->withoutVite() + ->get('/docs/mobile/4/publishing/android') + ->assertOk() + ->assertSee('id="releasing-to-production"', false) + ->assertSee('introduction#production-and-testing-builds', false) + ->assertSee('Open testing') + ->assertDontSee('Closed beta testing'); + } + + public function test_ios_page_explains_that_app_store_testing_builds_stay_in_internal_testflight(): void + { + $this->withoutVite() + ->get('/docs/mobile/4/publishing/ios') + ->assertOk() + ->assertSee('id="testing-builds"', false) + ->assertSee('introduction#production-and-testing-builds', false) + ->assertSee('TestFlight internal testing only'); + } + + public function test_upgrade_guide_tells_4_4_apps_to_package_releases_with_production(): void + { + $this->withoutVite() + ->get('/docs/mobile/4/getting-started/upgrade-guide') + ->assertOk() + ->assertSeeInOrder(['Upgrading To 4.5 From 4.4', 'APP_ENV=production', 'Upgrading To 4.0 From 3.x']) + ->assertSee('publishing/introduction#production-and-testing-builds', false); + } +}