Update Staging Deploy

This commit is contained in:
2026-06-09 11:45:59 +02:00
parent f529f74823
commit 6b02c1b2f4
14 changed files with 168 additions and 28 deletions

View File

@@ -0,0 +1,52 @@
name: Deploy Laravel Staging
on:
push:
branches: [staging]
jobs:
deploy:
runs-on: self-hosted
steps:
- name: Configure Git credentials
run: |
git config --global credential.helper store
echo "https://staging-runner:${{ env.GITEA_TOKEN }}@code.romhackplaza.org" \
> /root/.git-credentials
- name: Mark Git Folder as safe
run: git config --global --add safe.directory /deploy/laravel
- name: Code pull
run: |
git -C /deploy/laravel fetch origin staging
git -C /deploy/laravel reset --hard origin/staging
- name: Storage Link
run: |
docker exec staging_rhpz_web \
php /sites/laravel/artisan storage:link --force
- name: Composer Dependencies
run: |
docker exec staging_rhpz_web composer install \
--no-dev \
--optimize-autoloader \
--working-dir=/sites/laravel
- name: JS Dependencies
run: cd /deploy/laravel && npm ci
- name: Build JS/CSS
run: cd /deploy/laravel && npm run build
- name: Migrations
run: |
docker exec staging_rhpz_web \
php /sites/laravel/artisan migrate --force
- name: Opti Laravel
run: |
docker exec staging_rhpz_web \
php /sites/laravel/artisan optimize

View File

@@ -90,4 +90,9 @@ class EntryHelpers {
});
}
public static function enableOnlinePatcherBasedOnExtension(string $filename): bool
{
return Str::endsWith(Str::lower($filename), ['.ips', '.bps', '.xdelta', '.zip' ]);
}
}

View File

@@ -41,6 +41,22 @@ class FormHelpers {
'release_site_helper' => "Project entry on site/blog/forum/Github.",
'youtube_video' => "YouTube video",
],
'homebrew' => [
'page_title' => "Submit an homebrew",
'about_the' => "About the homebrew",
'version' => "Patch version",
'status' => "Status",
'release_date' => "Release date",
'release_date_helper' => "If only initial release exist, the release date.",
'description' => "Description",
'about_game' => "Game Information",
'attachments' => "Attachments",
'authors' => "Team members",
'related_links' => "Related links",
'release_site' => "Release site",
'release_site_helper' => "Project entry on site/blog/forum/Github.",
'youtube_video' => "YouTube video",
],
];
public static function getEntryFormWords( string $section ){

View File

@@ -2,6 +2,7 @@
namespace App\Http\Controllers;
use App\Helpers\EntryHelpers;
use App\Models\EntryFile;
use App\Services\FileServersService;
use Illuminate\Http\Client\ConnectionException;
@@ -52,7 +53,7 @@ class FileServerController extends Controller {
'filesize' => $data['file']['size'],
'favorite_server' => $data['favorite_server'],
'favorite_at' => time(),
'state' => 'public'
'state' => 'public',
], now()->addHours(2) );
$data['finished'] = true;

View File

@@ -49,7 +49,7 @@ class SubmissionController extends Controller
if( section_must_be( 'romhacks', $section ) ){
$data['modifications'] = Modification::orderBy('name')->get();
}
if( section_must_be( [ 'romhacks', 'translations' ], $section ) ){
if( section_must_be( [ 'romhacks', 'translations', 'homebrew' ], $section ) ){
$data['statuses'] = Status::orderBy('id')->get();
}

View File

@@ -2,6 +2,8 @@
namespace App\Http\Controllers;
use App\Models\EntryFile;
use App\Services\FileServersService;
use Illuminate\Http\Request;
class ToolsController extends Controller
@@ -10,11 +12,21 @@ class ToolsController extends Controller
public function patcher()
{
return view('tools.patcher');
}
public function directPatch( Request $request, int $entry_id, EntryFile $file )
{
if( $file->entry_id != $entry_id ) {
abort(404);
}
$service = app(FileServersService::class);
$patches = [
'file' => 'ZELDA.ips',
'name' => "Meltin",
'description' => 'Blablabla',
'outputName' => 'Game...'
'file' => $service->getDownloadFileUrl( $file ),
'name' => $file->entry->title,
'outputName' => $file->filename
];
return view('tools.patcher', compact('patches'));

View File

@@ -64,7 +64,7 @@ class StoreEntryRequest extends FormRequest
$rules['files_state.*'] = 'string|in:public,private,archived';
}
if( section_must_not_be( 'translations', $section ) ){
if( section_must_not_be( ['translations','homebrew'], $section ) ){
$rules['entry_title'] = "required|string|max:255";
} else {
$rules['entry_title'] = "nullable|string|max:255";
@@ -124,6 +124,12 @@ class StoreEntryRequest extends FormRequest
}
}
if( $isEdit ){
$rules['files_metadata'] = 'array|nullable';
$rules['files_metadata.*.online_patcher'] = 'nullable|boolean';
$rules['files_metadata.*.secondary_online_patcher'] = 'nullable|boolean|required_with:files_metadata.*.online_patcher';
}
if( $isEdit && $this->user()->can('moderate', $this->route('entry') ) ){
$rules['staff_comment'] = 'nullable|string';
$rules['owner_user_id'] = [ 'required', 'integer', new XfUserExists ];

View File

@@ -162,7 +162,7 @@ class SubmissionsService {
$entry = Entry::create( $fields );
// STEP 7 : Save entry fields.
$this->Step7_SaveEntryFiles( $entry->id );
$this->Step7_SaveEntryFiles( $entry );
// STEP 8 : Save hashes.
$this->Step8_SaveHashes( $entry->id );
@@ -275,25 +275,35 @@ class SubmissionsService {
* @return void
* @throws SubmissionException
*/
private function Step7_SaveEntryFiles( int $entryId, ?array $uuidData = null ): void
private function Step7_SaveEntryFiles( Entry $entry, ?array $uuidData = null ): void
{
if( !$uuidData )
$uuidData = $this->request->input('files_uuid', [] );
$metadataArray = $this->request->input('files_metadata', []);
foreach ( $uuidData ?? [] as $uuid ) {
$fileData = Cache::pull("uploaded_file_{$uuid}");
if( !$fileData )
throw new SubmissionException( "File {$uuid} has expired. Please delete all your files and retry. If it's an edition, delete all your new files and retry." );
$onlinePatcher = (bool)($metadataArray[$uuid]['online_patcher'] ?? false);
if( !$onlinePatcher )
$onlinePatcher = EntryHelpers::enableOnlinePatcherBasedOnExtension( $fileData['filename'] );
$secondaryOnlinePatcher = (bool)($metadataArray[$uuid]['secondary_online_patcher'] ?? false);
EntryFile::create([
'entry_id' => $entryId,
'entry_id' => $entry->id,
'file_uuid' => $uuid,
'filename' => $fileData['filename'],
'filepath' => $fileData['filepath'],
'favorite_server' => $fileData['favorite_server'],
'favorite_at' => \DateTimeImmutable::createFromTimestamp( $fileData['favorite_at'] ),
'filesize' => $fileData['filesize'],
'state' => 'public'
'state' => 'public',
'online_patcher' => $onlinePatcher,
'secondary_online_patcher' => $secondaryOnlinePatcher,
]);
}
@@ -361,7 +371,6 @@ class SubmissionsService {
*/
private function Step10_SaveRomhacksModifications( Entry $entry ): void
{
// TODO: Replace by edit version
foreach ( $this->request->input('modifications', [] ) ?? [] as $modificationId ) {
@@ -494,7 +503,7 @@ class SubmissionsService {
'user_id' => $user_id,
'complete_title' => $completeTitle,
'comments_thread_id' => $this->request->input('comments_thread_id'),
'featured' => $this->request->input('featured'),
'featured' => $this->request->input('featured') ?? false,
];
if( \Auth::user()->can('moderate', $this->entry) ){
@@ -600,12 +609,23 @@ class SubmissionsService {
$needAddition = array_diff( $requestUuids, $existingUuids );
if( !empty( $needAddition ) ){
$this->Step7_SaveEntryFiles( $this->entry->id, $needAddition ); // Same code.
$this->Step7_SaveEntryFiles( $this->entry, $needAddition ); // Same code.
}
$metadataArray = $this->request->input('files_metadata', []);
$stateMap = array_combine( $requestUuids, $requestStates );
foreach( $stateMap as $uuid => $state ){
EntryFile::where('file_uuid', $uuid)->where('entry_id', $entryId)->where('state', '!=', 'archived')->update(['state' => $state]);
$onlinePatcher = (bool)($metadataArray[$uuid]['online_patcher'] ?? false);
$secondaryOnlinePatcher = (bool)($metadataArray[$uuid]['secondary_online_patcher'] ?? false);
EntryFile::where('file_uuid', $uuid)->where('entry_id', $entryId)->where('state', '!=', 'archived')
->update([
'state' => $state,
'online_patcher' => $onlinePatcher,
'secondary_online_patcher' => $secondaryOnlinePatcher,
]);
}
}

View File

@@ -27,7 +27,7 @@ return [
'name' => "My Drafts",
'icon' => 'scissors',
'route' => 'entries.drafts',
'condition' => (fn() => !\Auth::guest())
'auth' => true
]
]
],
@@ -63,7 +63,7 @@ return [
[
'name' => 'ROM Patcher',
'icon' => 'stamp',
'route' => 'home'
'route' => 'tools.patcher'
],
[
'name' => 'ROM Hasher',

View File

@@ -15,7 +15,7 @@
<div class="menu-group">
<div class="menu-group-title">{{ $menu['name'] }}</div>
@foreach( $menu['items'] as $item )
@if( !isset( $item['condition'] ) || $item['condition']() )
@if( !isset( $item['requires_auth'] ) || $item['requires_auth'] && !\Auth::guest() )
<a href="{{ isset($item['xf_route']) ? xfRoute($item['xf_route']) : route($item['route']) }}"
@class(['menu-item', 'active' => request()->routeIs( $item['route'] ?? '' )]) >
<i data-lucide="{{ $item['icon'] }}"></i><span>{{ $item['name'] }}</span>

View File

@@ -22,7 +22,12 @@
<span class="file-name">{{ $file->filename }}</span>
<span class="file-meta">{{ $file->filesize }} - 0 downloads</span>
</div>
<a href="{{ route('fs.download', ['entry_id' => $entryId, 'file' => $file->file_uuid] ) }}" class="btn primary"><i data-lucide="download"></i> Download</a>
<div style="display:flex;flex-direction:column;gap:15px;">
<a href="{{ route('fs.download', ['entry_id' => $entryId, 'file' => $file->file_uuid] ) }}" class="btn primary"><i data-lucide="download"></i> Download</a>
@if( $file->online_patcher )
<a href="{{ route('tools.direct-patch', ['entry_id' => $entryId, 'file' => $file->file_uuid] ) }}" class="btn"><i data-lucide="stamp"></i> Patch</a>
@endif
</div>
</div>
@empty
No files found

View File

@@ -29,7 +29,7 @@
<!-- ABOUT THE ENTRY -->
<x-form-group-title label="{{ $words['about_the'] }}" icon="puzzle" />
@if( section_must_not_be( 'translations', $section ) )
@if( section_must_not_be( ['translations', 'homebrew'], $section ) )
<div class="form-group">
<x-form-field-title name="{{ $words['entry_title'] }}" required="true" />
<input class="form-input" type="text" name="entry_title" value="{{ old('entry_title', $entry->title ?? '' ) }}" required>
@@ -37,7 +37,7 @@
<x-form-error-text message="{{ $message }}" />
@enderror
</div>
@else
@elseif( section_must_be( 'translations', $section ) )
<div class="form-group">
<x-form-field-title name="{{ $words['entry_title'] }}" helper="{{ $words['entry_title_helper'] }}" />
<input class="form-input" type="text" name="entry_title" value="{{ old('entry_title', $entry->title, '' ) }}">
@@ -59,7 +59,7 @@
</div>
@endif
@if( section_must_be( ['romhacks', 'translations'], $section ) )
@if( section_must_be( ['romhacks', 'translations', 'homebrew'], $section ) )
<div class="form-group grid-c3">
<div>
<x-form-field-title name="{{ $words['version'] }}" required="true" />
@@ -178,7 +178,7 @@
</div>
<div>
<x-form-field-title name="Owner" required="true" />
<livewire:xf-user-selector :initial-user-id="$entry->user_id" />
<livewire:xf-user-selector :initial-user-id="old('owner_user_id', $entry->user_id)" />
</div>
</div>
<div class="form-group grid-c2">

View File

@@ -131,11 +131,19 @@
</div>
<div class="modal-content">
<div class="form-group">
<x-form-group-title label="Online patcher" />
<label><input type="checkbox" class="form-checkbox" :name="'files_metadata[' + file.uuid + '][online_patcher]'" x-model="file.meta_online_patcher"> Enable it</label>
<label x-show="file.meta_online_patcher"><input type="checkbox" class="form-checkbox" :name="'files_metadata[' + file.meta_secondary_online_patcher + '][secondary_online_patcher]'" x-model="file.meta_secondary_online_patcher"> Mark as a secondary patch</label>
</div>
@if( section_must_be( ['translations', 'romhacks'], $section ) )
<div class="form-group">
<x-form-group-title label="Online patcher" />
<label>
<input type="checkbox" class="form-checkbox" x-model="file.meta_online_patcher">
Enable it
</label>
<label x-show="file.meta_online_patcher">
<input type="checkbox" class="form-checkbox" x-model="file.meta_secondary_online_patcher">
Mark as a secondary patch
</label>
</div>
@endif
</div>
</div>
</div>
@@ -144,6 +152,19 @@
<input type="hidden" name="files_uuid[]" :value="file.uuid" x-show="file.done">
@if($isEdit)
<input type="hidden" name="files_state[]" :value="file.state" x-show="file.done">
<template x-if="file.done">
<div>
@if( section_must_be( ['translations', 'romhacks'], $section ) )
<input type="hidden"
:name="'files_metadata[' + file.uuid + '][online_patcher]'"
:value="file.meta_online_patcher ? 1 : 0">
<input type="hidden"
:name="'files_metadata[' + file.uuid + '][secondary_online_patcher]'"
:value="(file.meta_online_patcher && file.meta_secondary_online_patcher) ? 1 : 0">
@endif
</div>
</template>
@endif
</div>
</template>

View File

@@ -67,6 +67,8 @@ Route::name('queue.')->prefix('/queue')->controller(\App\Http\Controllers\QueueC
// ToolsController
Route::name('tools.')->controller(\App\Http\Controllers\ToolsController::class)->group(function () {
Route::get('/patch', 'patcher' )->name('patcher');
Route::get( '/patch/{entry_id}/{file:file_uuid}', 'directPatch' )->name('direct-patch')
->where(['entry_id' => '[0-9]+']);
});
// ModeratorCPController