mirror of
https://github.com/koel/koel
synced 2024-09-20 06:11:53 +00:00
feat(build): add CI for MySQL (#1614)
This commit is contained in:
parent
1000059081
commit
dcc0e82a0b
8 changed files with 117 additions and 28 deletions
81
.github/workflows/unit-backend-mysql.yml
vendored
Normal file
81
.github/workflows/unit-backend-mysql.yml
vendored
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
name: Backend Unit Tests - MySQL
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
paths-ignore:
|
||||||
|
- resources/assets/**
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
paths-ignore:
|
||||||
|
- resources/assets/**
|
||||||
|
workflow_dispatch:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
paths-ignore:
|
||||||
|
- resources/assets/**
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
php-version: [ 8.0 ]
|
||||||
|
mysql-version: [ 5.7, 8.0 ]
|
||||||
|
fail-fast: false
|
||||||
|
|
||||||
|
services:
|
||||||
|
mysql:
|
||||||
|
image: mysql:${{ matrix.mysql-version }}
|
||||||
|
env:
|
||||||
|
MYSQL_DATABASE: koel
|
||||||
|
MYSQL_USER: mysql
|
||||||
|
MYSQL_PASSWORD: mysql
|
||||||
|
MYSQL_ROOT_PASSWORD: mysql
|
||||||
|
ports:
|
||||||
|
- 3306:3306
|
||||||
|
options: >-
|
||||||
|
--health-cmd "mysqladmin ping"
|
||||||
|
--health-interval 10s
|
||||||
|
--health-timeout 5s
|
||||||
|
--health-retries 5
|
||||||
|
|
||||||
|
env:
|
||||||
|
DB_CONNECTION: mysql-ci
|
||||||
|
DB_HOST: 127.0.1.1
|
||||||
|
DB_PORT: 3306
|
||||||
|
DB_DATABASE: koel
|
||||||
|
DB_USERNAME: mysql
|
||||||
|
DB_PASSWORD: mysql
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v1
|
||||||
|
- name: Set up PHP
|
||||||
|
uses: shivammathur/setup-php@v2
|
||||||
|
with:
|
||||||
|
php-version: ${{ matrix.php-version }}
|
||||||
|
tools: composer:v2
|
||||||
|
coverage: xdebug
|
||||||
|
extensions: pdo_sqlite, zip, gd
|
||||||
|
- name: Install PHP dependencies
|
||||||
|
uses: ramsey/composer-install@v2
|
||||||
|
with:
|
||||||
|
composer-options: --prefer-dist
|
||||||
|
- name: Generate app key
|
||||||
|
run: php artisan key:generate --quiet
|
||||||
|
- name: Run code style checker
|
||||||
|
run: composer cs
|
||||||
|
- name: Run static analysis
|
||||||
|
run: composer analyze -- --no-progress
|
||||||
|
- name: Run tests
|
||||||
|
run: composer coverage
|
||||||
|
- name: Upload logs if broken
|
||||||
|
uses: actions/upload-artifact@v1
|
||||||
|
if: failure()
|
||||||
|
with:
|
||||||
|
name: logs
|
||||||
|
path: storage/logs
|
||||||
|
- name: Upload coverage
|
||||||
|
uses: codecov/codecov-action@v1
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.CODECOV_TOKEN }}
|
|
@ -86,6 +86,21 @@ return [
|
||||||
'sslmode' => 'prefer',
|
'sslmode' => 'prefer',
|
||||||
],
|
],
|
||||||
|
|
||||||
|
'mysql-ci' => [
|
||||||
|
'driver' => 'mysql',
|
||||||
|
'host' => env('DB_HOST', '127.0.0.1'),
|
||||||
|
'port' => env('DB_PORT', 3306),
|
||||||
|
'database' => env('DB_DATABASE', 'koel'),
|
||||||
|
'username' => env('DB_USERNAME', 'mysql'),
|
||||||
|
'password' => env('DB_PASSWORD', 'mysql'),
|
||||||
|
'charset' => 'utf8mb4',
|
||||||
|
'collation' => 'utf8mb4_unicode_ci',
|
||||||
|
'prefix' => '',
|
||||||
|
'prefix_indexes' => true,
|
||||||
|
'strict' => false,
|
||||||
|
'engine' => null,
|
||||||
|
],
|
||||||
|
|
||||||
'pgsql-ci' => [
|
'pgsql-ci' => [
|
||||||
'driver' => 'pgsql',
|
'driver' => 'pgsql',
|
||||||
'host' => env('DB_HOST', 'localhost'),
|
'host' => env('DB_HOST', 'localhost'),
|
||||||
|
|
|
@ -1,23 +1,11 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
use App\Models\Artist;
|
|
||||||
use Illuminate\Database\Migrations\Migration;
|
use Illuminate\Database\Migrations\Migration;
|
||||||
use Illuminate\Support\Facades\DB;
|
|
||||||
|
|
||||||
class FixArtistAutoindexValue extends Migration
|
class FixArtistAutoindexValue extends Migration
|
||||||
{
|
{
|
||||||
public function up(): void
|
public function up(): void
|
||||||
{
|
{
|
||||||
// This is to fix the auto increment bug caused by 2016_04_16_082627_create_various_artists
|
|
||||||
|
|
||||||
// Return if the database driver is not MySQL.
|
|
||||||
if (DB::getDriverName() !== 'mysql') { // @phpstan-ignore-line
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @var Artist $latestArtist */
|
|
||||||
$latestArtist = Artist::query()->orderByDesc('id')->first();
|
|
||||||
DB::statement('ALTER TABLE artists AUTO_INCREMENT=' . ($latestArtist->id + 1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function down(): void
|
public function down(): void
|
||||||
|
|
|
@ -13,9 +13,9 @@ return new class extends Migration
|
||||||
$table->timestamp('last_played_at')->nullable();
|
$table->timestamp('last_played_at')->nullable();
|
||||||
});
|
});
|
||||||
|
|
||||||
DB::statement('UPDATE interactions SET last_played_at = updated_at');
|
DB::unprepared('UPDATE interactions SET last_played_at = updated_at');
|
||||||
|
|
||||||
DB::statement(
|
DB::unprepared(
|
||||||
"UPDATE playlists SET rules = REPLACE(rules, 'interactions.updated_at', 'interactions.last_played_at')"
|
"UPDATE playlists SET rules = REPLACE(rules, 'interactions.updated_at', 'interactions.last_played_at')"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,12 +28,12 @@ class AlbumCoverTest extends TestCase
|
||||||
$user = User::factory()->admin()->create();
|
$user = User::factory()->admin()->create();
|
||||||
|
|
||||||
/** @var Album $album */
|
/** @var Album $album */
|
||||||
$album = Album::factory()->create(['id' => 9999]);
|
$album = Album::factory()->create();
|
||||||
|
|
||||||
$this->mediaMetadataService
|
$this->mediaMetadataService
|
||||||
->shouldReceive('writeAlbumCover')
|
->shouldReceive('writeAlbumCover')
|
||||||
->once()
|
->once()
|
||||||
->with(Mockery::on(static fn (Album $album) => $album->id === 9999), 'Foo', 'jpeg');
|
->with(Mockery::on(static fn (Album $target) => $target->is($album)), 'Foo', 'jpeg');
|
||||||
|
|
||||||
$this->putAs('api/album/' . $album->id . '/cover', ['cover' => 'data:image/jpeg;base64,Rm9v'], $user)
|
$this->putAs('api/album/' . $album->id . '/cover', ['cover' => 'data:image/jpeg;base64,Rm9v'], $user)
|
||||||
->assertOk();
|
->assertOk();
|
||||||
|
|
|
@ -49,7 +49,9 @@ class PlaylistSongTest extends TestCase
|
||||||
$songs = Song::factory(2)->create();
|
$songs = Song::factory(2)->create();
|
||||||
$playlist->songs()->saveMany($songs);
|
$playlist->songs()->saveMany($songs);
|
||||||
|
|
||||||
$this->getAs("api/playlist/$playlist->id/songs", $playlist->user)
|
$responseIds = $this->getAs("api/playlist/$playlist->id/songs", $playlist->user)
|
||||||
->assertJson($songs->pluck('id')->all());
|
->json();
|
||||||
|
|
||||||
|
self::assertEqualsCanonicalizing($responseIds, $songs->pluck('id')->all());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,6 @@ abstract class TestCase extends BaseTestCase
|
||||||
{
|
{
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
|
|
||||||
$this->prepareForTests();
|
|
||||||
self::createSandbox();
|
self::createSandbox();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,12 +6,14 @@ use App\Console\Kernel;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Illuminate\Contracts\Console\Kernel as Artisan;
|
use Illuminate\Contracts\Console\Kernel as Artisan;
|
||||||
use Illuminate\Foundation\Application;
|
use Illuminate\Foundation\Application;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
trait CreatesApplication
|
trait CreatesApplication
|
||||||
{
|
{
|
||||||
protected string $mediaPath = __DIR__ . '/../songs';
|
protected string $mediaPath = __DIR__ . '/../songs';
|
||||||
private Kernel $artisan;
|
private Kernel $artisan;
|
||||||
protected string $baseUrl = 'http://localhost';
|
protected string $baseUrl = 'http://localhost';
|
||||||
|
public static bool $migrated = false;
|
||||||
|
|
||||||
public function createApplication(): Application
|
public function createApplication(): Application
|
||||||
{
|
{
|
||||||
|
@ -23,15 +25,17 @@ trait CreatesApplication
|
||||||
$this->artisan = $app->make(Artisan::class);
|
$this->artisan = $app->make(Artisan::class);
|
||||||
$this->artisan->bootstrap();
|
$this->artisan->bootstrap();
|
||||||
|
|
||||||
|
// Unless the DB is stored in memory, we need to migrate the DB only once for the whole test suite.
|
||||||
|
if (!CreatesApplication::$migrated || DB::connection()->getDatabaseName() === ':memory:') {
|
||||||
|
$this->artisan->call('migrate');
|
||||||
|
|
||||||
|
if (!User::query()->count()) {
|
||||||
|
$this->artisan->call('db:seed');
|
||||||
|
}
|
||||||
|
|
||||||
|
CreatesApplication::$migrated = true;
|
||||||
|
}
|
||||||
|
|
||||||
return $app;
|
return $app;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function prepareForTests(): void
|
|
||||||
{
|
|
||||||
$this->artisan->call('migrate');
|
|
||||||
|
|
||||||
if (!User::query()->count()) {
|
|
||||||
$this->artisan->call('db:seed');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue