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
4 changes: 2 additions & 2 deletions .github/workflows/dependabot-auto-merge.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ jobs:
dependabot:
runs-on: ubuntu-latest
timeout-minutes: 5
if: ${{ github.actor == 'dependabot[bot]' }}
if: github.event.pull_request.user.login == 'dependabot[bot]' && github.repository == 'pixelated-au/streamline'
steps:

- name: Dependabot metadata
id: metadata
uses: dependabot/fetch-metadata@v2.3.0
uses: dependabot/fetch-metadata@v2
with:
github-token: "${{ secrets.GITHUB_TOKEN }}"

Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/fix-php-code-style-issues.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,16 @@ jobs:

steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
ref: ${{ github.head_ref }}

- name: Fix PHP code style issues
uses: aglipanci/laravel-pint-action@2.5
uses: aglipanci/laravel-pint-action@v2
with:
preset: laravel

- name: Commit changes
uses: stefanzweifel/git-auto-commit-action@v5
uses: stefanzweifel/git-auto-commit-action@v7
with:
commit_message: Fix styling
3 changes: 2 additions & 1 deletion .github/workflows/run-tests.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#file: noinspection SpellCheckingInspection
name: run-tests

on:
Expand Down Expand Up @@ -33,7 +34,7 @@ jobs:

steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@v6

- name: Setup PHP
uses: shivammathur/setup-php@v2
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/update-changelog.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:

steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
ref: main

Expand All @@ -25,7 +25,7 @@ jobs:
release-notes: ${{ github.event.release.body }}

- name: Commit updated CHANGELOG
uses: stefanzweifel/git-auto-commit-action@v5
uses: stefanzweifel/git-auto-commit-action@v7
with:
branch: main
commit_message: Update CHANGELOG
Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ Please review [our security policy](../../security/policy) on how to report secu
- [Pixelated](https://github.com/pixelated-au)
- [All Contributors](../../contributors)

## TODO
- [ ] Detect if the GitHub token has expired. If so, output an error to the user

## License

The MIT License (MIT). Please see [License File](LICENSE) for more information.
23 changes: 5 additions & 18 deletions config/streamline.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,15 @@

/** @noinspection PhpUnusedParameterInspection */

use Pixelated\Streamline\Events\CommandClassCallback;
use Pixelated\Streamline\Interfaces\UpdateBuilderInterface;
use Pixelated\Streamline\Pipes\BackupCurrentInstallation;
use Pixelated\Streamline\Pipes\CheckComposer;
use Pixelated\Streamline\Pipes\CheckLaravelBasePathWritable;
use Pixelated\Streamline\Pipes\DownloadRelease;
use Pixelated\Streamline\Pipes\GetNextAvailableReleaseVersion;
use Pixelated\Streamline\Pipes\MakeTempDir;
use Pixelated\Streamline\Pipes\RunUpdate;
use Pixelated\Streamline\Pipes\UnpackRelease;
use Pixelated\Streamline\Pipes\VerifyVersion;
use Symfony\Component\Process\PhpExecutableFinder;
use Symfony\Component\Process\Process;

return [
Expand Down Expand Up @@ -315,6 +313,7 @@

'pipeline-update' => [
CheckLaravelBasePathWritable::class,
CheckComposer::class,
GetNextAvailableReleaseVersion::class,
VerifyVersion::class,
MakeTempDir::class,
Expand All @@ -329,24 +328,12 @@
| Pipeline Cleanup
|--------------------------------------------------------------------------
|
| Anything in this function will be executed after all pipeline steps have
| completed. Even if an error occurs during the pipeline execution.
| Anything in this class will be executed after all pipeline steps have
| completed, even if an error occurs during the pipeline execution.
|
*/

'pipeline-finish' => static function(UpdateBuilderInterface $builder) {
$process = resolve(\Symfony\Component\Process\Process::class, [
'command' => [(new PhpExecutableFinder)->find(), 'artisan', 'streamline:finish-update'],
'cwd' => $builder->getBasePath(),
]);
$process->run();

if ($process->isSuccessful()) {
CommandClassCallback::dispatch('info', $process->getOutput());
} else {
CommandClassCallback::dispatch('error', $process->getErrorOutput());
}
},
'pipeline-finish-class' => \Pixelated\Streamline\Services\FinishUpdate::class,

/*
|--------------------------------------------------------------------------
Expand Down
18 changes: 7 additions & 11 deletions src/Actions/InstantiateStreamlineUpdater.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Pixelated\Streamline\Actions;

use Closure;
use Illuminate\Container\Attributes\Config as ConfigAttribute;
use Illuminate\Support\Facades\Config;
use Pixelated\Streamline\Factories;
use ReflectionClass;
Expand All @@ -13,23 +14,17 @@

class InstantiateStreamlineUpdater
{
/** @var class-string */
private readonly string $runnerClass;

public function __construct(
private readonly Factories\ProcessFactory $process,
// TODO restore this after upgrading to Laravel 11
// #[ConfigAttribute('streamline.runner_class')]
// private readonly string $runnerClass,
) {
// TODO restore this after upgrading to Laravel 11
$this->runnerClass = Config::get('streamline.runner_class');
}
#[ConfigAttribute('streamline.runner_class')]
/** @var class-string */
private readonly string $runnerClass,
) {}

/**
* @param Closure(string, string): void $callback
*/
public function execute(string $versionToInstall, Closure $callback): void
public function execute(string $versionToInstall, string $composerPath, Closure $callback): void
{
$classFilePath = $this->getClassFilePath();

Expand All @@ -46,6 +41,7 @@ public function execute(string $versionToInstall, Closure $callback): void
'PUBLIC_DIR_NAME' => public_path(),
'FRONT_END_BUILD_DIR' => config('streamline.laravel_build_dir_name'),
'INSTALLING_VERSION' => $versionToInstall,
'COMPOSER_PATH' => $composerPath,
'PROTECTED_PATHS' => $protectedPaths,
'DIR_PERMISSION' => (int) config('streamline.directory_permissions'),
'FILE_PERMISSION' => (int) config('streamline.file_permissions'),
Expand Down
9 changes: 6 additions & 3 deletions src/Commands/UpdateCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
namespace Pixelated\Streamline\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Config;
use Pixelated\Streamline\Commands\Traits\GitHubApi;
use Pixelated\Streamline\Commands\Traits\OutputSubProcessCalls;
use Pixelated\Streamline\Interfaces\UpdateBuilderInterface;
use Pixelated\Streamline\Pipeline\Pipeline;
use Pixelated\Streamline\Updater\UpdateBuilder;
use Throwable;

class UpdateCommand extends Command
Expand All @@ -17,6 +18,7 @@ class UpdateCommand extends Command

protected $signature = 'streamline:run-update
{--install-version= : Specify version to install}
{--composer= : Set the path to composer.phar if not installed globally}
{--force : Force update. Use for overriding the current version.}';

protected $description = 'CLI update';
Expand All @@ -28,10 +30,11 @@ public function handle(): int
{
$this->listenForSubProcessEvents();

$builder = (new UpdateBuilder)
$builder = App::make(UpdateBuilderInterface::class)
->setBasePath(base_path())
->setRequestedVersion($this->option('install-version'))
->setCurrentlyInstalledVersion(Config::get('streamline.installed_version'))
->setComposerPath($this->option('composer'))
->forceUpdate($this->option('force'));

return (new Pipeline($builder))
Expand All @@ -41,7 +44,7 @@ public function handle(): int

return self::FAILURE;
})
->finally(config('streamline.pipeline-finish'))
->finally(App::make(config('streamline.pipeline-finish-class')))
->then(fn() => self::SUCCESS);
}
}
4 changes: 4 additions & 0 deletions src/Global/StreamlineUpdater.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ class StreamlineUpdater

public string $installingVersion;

public string $composerPath;

public string $oldReleaseArchivePath;

public array $protectedPaths;
Expand Down Expand Up @@ -46,6 +48,7 @@ public function __construct()
$this->publicDirName = $this->env('PUBLIC_DIR_NAME');
$this->frontEndBuildDir = $this->env('FRONT_END_BUILD_DIR');
$this->installingVersion = $this->env('INSTALLING_VERSION');
$this->composerPath = $this->env('COMPOSER_PATH');
$this->protectedPaths = $this->jsonEnv('PROTECTED_PATHS');
$this->dirPermission = (int) $this->env('DIR_PERMISSION');
$this->filePermission = (int) $this->env('FILE_PERMISSION');
Expand Down Expand Up @@ -109,6 +112,7 @@ public function run(): void
publicDirName: $this->publicDirName,
frontendBuildDir: $this->frontEndBuildDir,
installingVersion: $this->installingVersion,
composerPath: $this->composerPath,
protectedPaths: $this->protectedPaths,
dirPermission: $this->dirPermission,
filePermission: $this->filePermission,
Expand Down
4 changes: 4 additions & 0 deletions src/Interfaces/UpdateBuilderInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ public function setBasePath(string $basePath): UpdateBuilderInterface;

public function getBasePath(): string;

public function setComposerPath(string $path): UpdateBuilderInterface;

public function getComposerPath(): string;

public function setCurrentlyInstalledVersion(string $version): UpdateBuilderInterface;

public function getCurrentlyInstalledVersion(): ?string;
Expand Down
6 changes: 4 additions & 2 deletions src/Pipeline/Pipeline.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ class Pipeline

private Closure $destination;

private ?Closure $finallyHandler = null;
/** @var string|callable */
private $finallyHandler;

public function __construct(protected UpdateBuilderInterface $builder) {}

Expand All @@ -40,9 +41,10 @@ public function catch(Closure $exceptionHandler): static
}

/**
* @param class-string | callable $finallyHandler
* @return $this
*/
public function finally(Closure $finallyHandler): static
public function finally(string|callable $finallyHandler): static
{
$this->finallyHandler = $finallyHandler;

Expand Down
36 changes: 36 additions & 0 deletions src/Pipes/CheckComposer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

namespace Pixelated\Streamline\Pipes;

use Illuminate\Support\Facades\Process;
use Pixelated\Streamline\Interfaces\UpdateBuilderInterface;
use Pixelated\Streamline\Pipeline\Pipe;
use RuntimeException;

class CheckComposer implements Pipe
{
public function __invoke(UpdateBuilderInterface $builder): UpdateBuilderInterface
{
$composerPath = $this->checkComposerPath(
$builder->getComposerPath()
);

$builder->setComposerPath($composerPath);

return $builder;
}

protected function checkComposerPath(string $composerPath): string
{
if (Process::run("$composerPath -V")->failed()) {
throw new RuntimeException(
message: 'Error: Cannot find composer. It doesn\'t appear to be installed globally. ' .
'Please specify the path to composer using the --composer option. ' .
'See https://getcomposer.org for more information.'
);
}

// return the composer full path by using 'which'. Trim off the newline character which is added by Process::run
return trim(Process::run('which composer')->output());
}
}
7 changes: 4 additions & 3 deletions src/Pipes/RunUpdate.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@
{
public function __construct(private InstantiateStreamlineUpdater $runUpdate) {}

public function __invoke($builder): UpdateBuilderInterface
public function __invoke(UpdateBuilderInterface $builder): UpdateBuilderInterface
{
$this->runUpdate->execute(
$builder->getRequestedVersion() ?? $builder->getNextAvailableRepositoryVersion(),
function(string $type, string $output) {
versionToInstall: $builder->getRequestedVersion() ?? $builder->getNextAvailableRepositoryVersion(),
composerPath: $builder->getComposerPath(),
callback: function(string $type, string $output) {
if ($type === 'err') {
CommandClassCallback::dispatch('error', $output);

Expand Down
31 changes: 31 additions & 0 deletions src/Services/FinishUpdate.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace Pixelated\Streamline\Services;

use Pixelated\Streamline\Events\CommandClassCallback;
use Pixelated\Streamline\Interfaces\UpdateBuilderInterface;
use Symfony\Component\Process\PhpExecutableFinder;
use Symfony\Component\Process\Process;

readonly class FinishUpdate
{
public function __construct(
protected UpdateBuilderInterface $builder,
protected PhpExecutableFinder $phpExecutableFinder
) {}

public function __invoke(): void
{
$process = resolve(Process::class, [
'command' => [$this->phpExecutableFinder->find(), 'artisan', 'streamline:finish-update'],
'cwd' => $this->builder->getBasePath(),
]);
$process->run();

if ($process->isSuccessful()) {
CommandClassCallback::dispatch('info', $process->getOutput());
} else {
CommandClassCallback::dispatch('error', $process->getErrorOutput());
}
}
}
6 changes: 5 additions & 1 deletion src/StreamlineServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@
use Pixelated\Streamline\Commands\InitInstalledVersionCommand;
use Pixelated\Streamline\Commands\ListCommand;
use Pixelated\Streamline\Commands\UpdateCommand;
use Pixelated\Streamline\Interfaces\UpdateBuilderInterface;
use Pixelated\Streamline\Macros\ConfigCommaToArrayMacro;
use Pixelated\Streamline\Testing\Mocks\UpdateRunnerFake;
use Pixelated\Streamline\Updater\UpdateBuilder;
use Spatie\LaravelPackageTools\Commands\InstallCommand;
use Spatie\LaravelPackageTools\Package;
use Spatie\LaravelPackageTools\PackageServiceProvider;
Expand All @@ -41,6 +43,8 @@ public function configurePackage(Package $package): void

public function registeringPackage(): void
{
$this->app->singleton(UpdateBuilderInterface::class, UpdateBuilder::class);

$this->app->bind(
CreateArchive::class,
fn(Application $app) => new CreateArchive(
Expand All @@ -50,7 +54,7 @@ public function registeringPackage(): void
)
);

Config::get('logging.channels.streamline', Config::get('streamline.logging'));
Config::set('logging.channels.streamline', Config::get('streamline.logging'));

if ($this->app->environment('local')) {
// @codeCoverageIgnoreStart
Expand Down
Loading