Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Build with obfuscated bundle #447

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
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
6 changes: 6 additions & 0 deletions config/nativephp-internal.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,10 @@
* The URL to the NativePHP API.
*/
'api_url' => env('NATIVEPHP_API_URL', 'http://localhost:4000/api/'),

'zephpyr' => [
'host' => env('ZEPHPYR_HOST', 'zephpyr.com'),
'token' => env('ZEPHPYR_TOKEN'),
'key' => env('ZEPHPYR_KEY'),
],
];
3 changes: 2 additions & 1 deletion config/nativephp.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* It is used to determine if the app needs to be updated.
* Increment this value every time you release a new version of your app.
*/
'version' => env('NATIVEPHP_APP_VERSION', '1.0.0'),
'version' => env('NATIVEPHP_APP_VERSION', 1),

/**
* The ID of your application. This should be a unique identifier
Expand Down Expand Up @@ -47,6 +47,7 @@
'AWS_*',
'GITHUB_*',
'DO_SPACES_*',
'ZEPHPYR_*',
'*_SECRET',
'NATIVEPHP_UPDATER_PATH',
'NATIVEPHP_APPLE_ID',
Expand Down
167 changes: 167 additions & 0 deletions src/Commands/BundleCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
<?php

namespace Native\Laravel\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\Http;
use Native\Electron\Traits\CleansEnvFile;
use Symfony\Component\Finder\Finder;
use ZipArchive;

class BundleCommand extends Command
{
use CleansEnvFile;

protected $signature = 'native:bundle {--fetch}';

protected $description = 'Bundle your application for distribution.';

private ?string $key;

private string $zipPath;

private string $zipName;

public function handle()
{
$this->key = config('nativephp-internal.zephpyr.key');

if (! $this->key) {
$this->line('');
$this->warn('No ZEPHPYR_KEY found. Cannot bundle!');
$this->line('');
$this->line('Add this app\'s ZEPHPYR_KEY to its .env file:');
$this->line(base_path('.env'));
$this->line('');
$this->info('Not set up with Zephpyr yet? Secure your NativePHP app builds and more!');
$this->info('Check out https://zephpyr.com');
$this->line('');

return static::FAILURE;
}

if ($this->option('fetch')) {
if (! $this->fetchLatestBundle()) {
$this->warn('Latest bundle not yet available. Try again soon.');

return static::FAILURE;
}

$this->info('Latest bundle downloaded.');

return static::SUCCESS;
}

// Package the app up into a zip
if (! $this->zipApplication()) {
$this->error("Failed to create zip archive at {$this->zipPath}.");

return static::FAILURE;
}

// Send the zip file
dd($result = $this->sendToZephpyr());

if ($result->failed()) {
$this->error("Failed to upload zip [{$this->zipPath}] to Zephpyr.");

return static::FAILURE;
}

@unlink($this->zipPath);

$this->info('Successfully uploaded to Zephpyr.');
$this->line('Use native:bundle --fetch to retrieve the latest bundle.');

return static::SUCCESS;
}

private function zipApplication(): bool
{
$this->zipName = 'app_'.str()->random(8).'.zip';
$this->zipPath = storage_path($this->zipName);

$zip = new ZipArchive;

if ($zip->open($this->zipPath, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== true) {
return false;
}

$this->prepareNativeEnv();

$this->addFilesToZip($zip);

$zip->close();

$this->restoreWebEnv();

return true;
}

private function addFilesToZip(ZipArchive $zip): void
{
// TODO: Check the composer.json to make sure there are no symlinked or private packages as these will be a
// pain later

$app = (new Finder)->files()
->followLinks()
->ignoreVCSIgnored(true)
->in(base_path())
->exclude([
'vendor',
'dist',
'build',
'tests',
...config('nativephp.cleanup_exclude_files', []),
]);

$this->finderToZip($app, $zip);

$vendor = (new Finder)->files()
->exclude([
'nativephp/php-bin',
'nativephp/electron/resources/js',
'nativephp/*/vendor',
])
->in(base_path('vendor'));

$this->finderToZip($vendor, $zip, 'vendor');

$nodeModules = (new Finder)->files()
->in(base_path('node_modules'));

$this->finderToZip($nodeModules, $zip, 'node_modules');
}

private function finderToZip(Finder $finder, ZipArchive $zip, ?string $path = null): void
{
foreach ($finder as $file) {
if ($file->getRealPath() === false) {
continue;
}

$zip->addFile($file->getRealPath(), str($path)->finish(DIRECTORY_SEPARATOR).$file->getRelativePathname());
}
}

private function sendToZephpyr()
{
return Http::withToken(config('nativephp-internal.zephpyr.token'))
->attach('archive', fopen($this->zipPath, 'r'), $this->zipName)
->post(str(config('nativephp-internal.zephpyr.host'))->finish('/').'api/build/'.$this->key);
}

private function fetchLatestBundle(): bool
{
$response = Http::withToken(config('nativephp-internal.zephpyr.token'))
->get(str(config('nativephp-internal.zephpyr.host'))->finish('/').'api/download/'.$this->key);

if ($response->failed()) {
return false;
}

file_put_contents(base_path('build/__nativephp_app_bundle'), $response->body());

return true;
}
}
111 changes: 0 additions & 111 deletions src/Commands/MinifyApplicationCommand.php

This file was deleted.

4 changes: 2 additions & 2 deletions src/NativeServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\DB;
use Native\Laravel\ChildProcess as ChildProcessImplementation;
use Native\Laravel\Commands\BundleCommand;
use Native\Laravel\Commands\FreshCommand;
use Native\Laravel\Commands\LoadPHPConfigurationCommand;
use Native\Laravel\Commands\LoadStartupConfigurationCommand;
use Native\Laravel\Commands\MigrateCommand;
use Native\Laravel\Commands\MinifyApplicationCommand;
use Native\Laravel\Commands\SeedDatabaseCommand;
use Native\Laravel\Contracts\ChildProcess as ChildProcessContract;
use Native\Laravel\Contracts\GlobalShortcut as GlobalShortcutContract;
Expand All @@ -35,7 +35,7 @@ public function configurePackage(Package $package): void
MigrateCommand::class,
FreshCommand::class,
SeedDatabaseCommand::class,
MinifyApplicationCommand::class,
BundleCommand::class,
])
->hasConfigFile()
->hasRoute('api')
Expand Down