Skip to content

Commit

Permalink
Merge pull request #486 from jesusantguerrero/staging
Browse files Browse the repository at this point in the history
Staging
  • Loading branch information
jesusantguerrero authored Oct 3, 2024
2 parents 2fd6634 + 62c1d2e commit 73100ad
Show file tree
Hide file tree
Showing 5 changed files with 389 additions and 0 deletions.
31 changes: 31 additions & 0 deletions app/Console/Commands/CheckUpdate.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\Artisan;


class CheckUpdate extends Command
{
protected $signature = 'app:check-update';
protected $description = 'Check if there is any update available in the server';

public function handle()
{
$currentVersion = json_decode(file_get_contents(base_path('version.json')), true)['version'];
$latestRelease = json_decode(file_get_contents('https://api.github.com/repos/jesusantguerrero/atmosphere/releases/latest', false, stream_context_create([
'http' => [
'method' => 'GET',
'header' => [
'User-Agent: PHP'
]
]
])), true);
$latestVersion = $latestRelease['tag_name'];

if (version_compare($latestVersion, $currentVersion, '>')) {
Artisan::call('update:run', ['--tag' => $latestVersion, '--endpoint' => $latestRelease['zipball_url']]);
}
}
}
108 changes: 108 additions & 0 deletions app/Console/Commands/UpdateVersion.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
<?php

namespace App\Console\Commands;

use ZipArchive;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Artisan;

class UpdateVersion extends Command
{
protected $signature = 'update:run {--tag=} {--endpoint=} ';
protected $description = 'Check if there is any update available in the server';

/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
$version = $this->option('tag');
$endpoint = $this->option('endpoint');

$this->info("Starting update to version $version...");

// Download the ZIP file from the GitHub release
$updatePath = storage_path('app/update-package.zip');
$this->downloadUpdate($endpoint, $updatePath);

$tempPath = storage_path('app/update-temp');
$this->extractUpdate($updatePath, $tempPath);

$this->applyUpdate($tempPath);

Artisan::call('migrate --force');
$this->info('Migrations completed.');

// Clear cache
Artisan::call('cache:clear');
Artisan::call('config:cache');
$this->info('Cache cleared and configurations rebuilt.');

// Update the version file
file_put_contents(base_path('version.json'), json_encode(['version' => $version]));
$this->info("Version updated to $version successfully.");

}

private function downloadUpdate($url, $path)
{
$fileContent = file_get_contents($url, false, stream_context_create([
'http' => [
'method' => 'GET',
'header' => [
'User-Agent: PHP'
]
]
]));
file_put_contents($path, $fileContent);
$this->info('Update package downloaded.');
}

private function extractUpdate($zipPath, $extractTo)
{
$zip = new ZipArchive;
if ($zip->open($zipPath) === TRUE) {
$zip->extractTo($extractTo);
$zip->close();
$this->info('Update files extracted successfully.');
} else {
$this->error('Failed to extract the update package.');
}
}

private function applyUpdate($tempPath)
{
$this->info('Applying update files...');

// Find the first directory inside the temp path (usually the repo name folder)
$directories = File::directories($tempPath);
if (empty($directories)) {
$this->error('No directories found in the extracted update.');
return;
}

// Assume the first directory is the main one containing the update files
$updateDir = $directories[0];

// Get all the files from the update directory and replace the app's files
$files = File::allFiles($updateDir);
foreach ($files as $file) {
// Compute the relative path of each file inside the update folder
$relativePath = $file->getRelativePathname();

// Create the destination path in the Laravel app's root directory
$destination = base_path($relativePath);

// Create the directory if it doesn't exist
File::ensureDirectoryExists(dirname($destination));

// Copy the file to the correct location in the app
File::copy($file->getRealPath(), $destination);
}

$this->info('Update applied successfully.');
}
}
36 changes: 36 additions & 0 deletions app/Providers/HorizonServiceProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

namespace App\Providers;

use Illuminate\Support\Facades\Gate;
use Laravel\Horizon\Horizon;
use Laravel\Horizon\HorizonApplicationServiceProvider;

class HorizonServiceProvider extends HorizonApplicationServiceProvider
{
/**
* Bootstrap any application services.
*/
public function boot(): void
{
parent::boot();

// Horizon::routeSmsNotificationsTo('15556667777');
// Horizon::routeMailNotificationsTo('[email protected]');
// Horizon::routeSlackNotificationsTo('slack-webhook-url', '#channel');
}

/**
* Register the Horizon gate.
*
* This gate determines who can access Horizon in non-local environments.
*/
protected function gate(): void
{
Gate::define('viewHorizon', function ($user) {
return in_array($user->email, [
//
]);
});
}
}
213 changes: 213 additions & 0 deletions config/horizon.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
<?php

use Illuminate\Support\Str;

return [

/*
|--------------------------------------------------------------------------
| Horizon Domain
|--------------------------------------------------------------------------
|
| This is the subdomain where Horizon will be accessible from. If this
| setting is null, Horizon will reside under the same domain as the
| application. Otherwise, this value will serve as the subdomain.
|
*/

'domain' => env('HORIZON_DOMAIN'),

/*
|--------------------------------------------------------------------------
| Horizon Path
|--------------------------------------------------------------------------
|
| This is the URI path where Horizon will be accessible from. Feel free
| to change this path to anything you like. Note that the URI will not
| affect the paths of its internal API that aren't exposed to users.
|
*/

'path' => env('HORIZON_PATH', 'horizon'),

/*
|--------------------------------------------------------------------------
| Horizon Redis Connection
|--------------------------------------------------------------------------
|
| This is the name of the Redis connection where Horizon will store the
| meta information required for it to function. It includes the list
| of supervisors, failed jobs, job metrics, and other information.
|
*/

'use' => 'default',

/*
|--------------------------------------------------------------------------
| Horizon Redis Prefix
|--------------------------------------------------------------------------
|
| This prefix will be used when storing all Horizon data in Redis. You
| may modify the prefix when you are running multiple installations
| of Horizon on the same server so that they don't have problems.
|
*/

'prefix' => env(
'HORIZON_PREFIX',
Str::slug(env('APP_NAME', 'laravel'), '_').'_horizon:'
),

/*
|--------------------------------------------------------------------------
| Horizon Route Middleware
|--------------------------------------------------------------------------
|
| These middleware will get attached onto each Horizon route, giving you
| the chance to add your own middleware to this list or change any of
| the existing middleware. Or, you can simply stick with this list.
|
*/

'middleware' => ['web'],

/*
|--------------------------------------------------------------------------
| Queue Wait Time Thresholds
|--------------------------------------------------------------------------
|
| This option allows you to configure when the LongWaitDetected event
| will be fired. Every connection / queue combination may have its
| own, unique threshold (in seconds) before this event is fired.
|
*/

'waits' => [
'redis:default' => 60,
],

/*
|--------------------------------------------------------------------------
| Job Trimming Times
|--------------------------------------------------------------------------
|
| Here you can configure for how long (in minutes) you desire Horizon to
| persist the recent and failed jobs. Typically, recent jobs are kept
| for one hour while all failed jobs are stored for an entire week.
|
*/

'trim' => [
'recent' => 60,
'pending' => 60,
'completed' => 60,
'recent_failed' => 10080,
'failed' => 10080,
'monitored' => 10080,
],

/*
|--------------------------------------------------------------------------
| Silenced Jobs
|--------------------------------------------------------------------------
|
| Silencing a job will instruct Horizon to not place the job in the list
| of completed jobs within the Horizon dashboard. This setting may be
| used to fully remove any noisy jobs from the completed jobs list.
|
*/

'silenced' => [
// App\Jobs\ExampleJob::class,
],

/*
|--------------------------------------------------------------------------
| Metrics
|--------------------------------------------------------------------------
|
| Here you can configure how many snapshots should be kept to display in
| the metrics graph. This will get used in combination with Horizon's
| `horizon:snapshot` schedule to define how long to retain metrics.
|
*/

'metrics' => [
'trim_snapshots' => [
'job' => 24,
'queue' => 24,
],
],

/*
|--------------------------------------------------------------------------
| Fast Termination
|--------------------------------------------------------------------------
|
| When this option is enabled, Horizon's "terminate" command will not
| wait on all of the workers to terminate unless the --wait option
| is provided. Fast termination can shorten deployment delay by
| allowing a new instance of Horizon to start while the last
| instance will continue to terminate each of its workers.
|
*/

'fast_termination' => false,

/*
|--------------------------------------------------------------------------
| Memory Limit (MB)
|--------------------------------------------------------------------------
|
| This value describes the maximum amount of memory the Horizon master
| supervisor may consume before it is terminated and restarted. For
| configuring these limits on your workers, see the next section.
|
*/

'memory_limit' => 64,

/*
|--------------------------------------------------------------------------
| Queue Worker Configuration
|--------------------------------------------------------------------------
|
| Here you may define the queue worker settings used by your application
| in all environments. These supervisors and settings handle all your
| queued jobs and will be provisioned by Horizon during deployment.
|
*/

'defaults' => [
'supervisor-1' => [
'connection' => 'redis',
'queue' => ['default'],
'balance' => 'auto',
'autoScalingStrategy' => 'time',
'maxProcesses' => 1,
'maxTime' => 0,
'maxJobs' => 0,
'memory' => 128,
'tries' => 1,
'timeout' => 60,
'nice' => 0,
],
],

'environments' => [
'production' => [
'supervisor-1' => [
'maxProcesses' => 10,
'balanceMaxShift' => 1,
'balanceCooldown' => 3,
],
],

'local' => [
'supervisor-1' => [
'maxProcesses' => 3,
],
],
],
];
1 change: 1 addition & 0 deletions version.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"version":"v2.0.0-alpha.11"}

0 comments on commit 73100ad

Please sign in to comment.