Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion config/docs.php
Original file line number Diff line number Diff line change
Expand Up @@ -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'],
],
],

Expand Down
12 changes: 12 additions & 0 deletions resources/views/docs/mobile/4/getting-started/upgrade-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
14 changes: 12 additions & 2 deletions resources/views/docs/mobile/4/publishing/android.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

<x-docs.version-badge since="4.5" />

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`:
Expand Down Expand Up @@ -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

Expand Down
33 changes: 33 additions & 0 deletions resources/views/docs/mobile/4/publishing/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

<x-docs.version-badge since="4.5" />

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.

<aside>

#### Share builds with testers safely

Package with `APP_ENV=staging` when you want to hand a build to testers. It can reach your internal TestFlight testers
and the Play Store's internal and closed testing tracks, and it can never be released to the public by mistake.

</aside>

## Packaging Your App

The `native:package` command creates signed, production-ready apps for distribution to the App Store and Play Store.
Expand All @@ -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))
11 changes: 11 additions & 0 deletions resources/views/docs/mobile/4/publishing/ios.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,17 @@ php artisan native:package ios \
--team-id=ABC1234567
```

### Testing builds

<x-docs.version-badge since="4.5" />

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:
Expand Down
66 changes: 66 additions & 0 deletions tests/Feature/Docs/PublishingAppEnvTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php

namespace Tests\Feature\Docs;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Http;
use Tests\TestCase;

class PublishingAppEnvTest extends TestCase
{
use RefreshDatabase;

protected function setUp(): void
{
parent::setUp();

// These pages render fenced code blocks; Torchlight throws outside
// production without a token, so fake its offline fallback.
config(['torchlight.token' => '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);
}
}
Loading