4 Commits

Author SHA1 Message Date
cfb69c8dab Add Deploy step 2025-09-08 21:51:00 +02:00
35ec71302b Update bake 2025-09-08 19:53:23 +02:00
b7a570928a Update dependencies 2025-09-08 19:50:23 +02:00
d80436534f Update Symfony packages 2025-09-08 19:26:45 +02:00
16 changed files with 1011 additions and 740 deletions

View File

@@ -4,6 +4,8 @@ on:
push: push:
branches: branches:
- main - main
tags:
- '*'
pull_request: ~ pull_request: ~
workflow_dispatch: ~ workflow_dispatch: ~
@@ -18,10 +20,12 @@ jobs:
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Lint Dockerfile
uses: hadolint/hadolint-action@v3.1.0
- name: Set up Docker Buildx - name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3 uses: docker/setup-buildx-action@v3
- name: Build Docker images - name: Build Docker images
uses: docker/bake-action@v4 uses: docker/bake-action@v5
with: with:
pull: true pull: true
load: true load: true
@@ -53,12 +57,17 @@ jobs:
run: docker compose exec -T php vendor/bin/phpunit run: docker compose exec -T php vendor/bin/phpunit
- name: Doctrine Schema Validator - name: Doctrine Schema Validator
run: docker compose exec -T php bin/console -e test doctrine:schema:validate run: docker compose exec -T php bin/console -e test doctrine:schema:validate
lint: deploy:
name: Docker Lint name: Deploy
environment:
name: ${{ startsWith(github.ref, 'refs/tags/') && 'production' || (github.ref == 'refs/heads/main' && 'acceptance' || '') }}
url: ${{ vars.URL }}
needs: tests
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/')
steps: steps:
- name: Checkout - shell: bash
uses: actions/checkout@v4 env:
- name: Lint Dockerfile PORTAINER_WEBHOOK: ${{secrets.PORTAINER_WEBHOOK}}
uses: hadolint/hadolint-action@v3.1.0 run: |
curl -v -X POST "$PORTAINER_WEBHOOK"

View File

@@ -9,21 +9,21 @@
"php": ">=8.4", "php": ">=8.4",
"ext-ctype": "*", "ext-ctype": "*",
"ext-iconv": "*", "ext-iconv": "*",
"doctrine/dbal": "^4.2.3", "doctrine/dbal": "^4.3.3",
"doctrine/doctrine-bundle": "^2.14.0", "doctrine/doctrine-bundle": "^2.16.1",
"doctrine/doctrine-migrations-bundle": "^3.4.2", "doctrine/doctrine-migrations-bundle": "^3.4.2",
"doctrine/orm": "^3.3.3", "doctrine/orm": "^3.5.2",
"easycorp/easyadmin-bundle": "^4.24.7", "easycorp/easyadmin-bundle": "^4.25.0",
"phpdocumentor/reflection-docblock": "^5.6.2", "phpdocumentor/reflection-docblock": "^5.6.3",
"phpoffice/phpspreadsheet": "^4.3.1", "phpoffice/phpspreadsheet": "^5.1",
"phpstan/phpdoc-parser": "^2.1", "phpstan/phpdoc-parser": "^2.3",
"runtime/frankenphp-symfony": "^0.2.0", "runtime/frankenphp-symfony": "^0.2.0",
"sentry/sentry-symfony": "^5.2", "sentry/sentry-symfony": "^5.4",
"symfony/asset": "7.3.*", "symfony/asset": "7.3.*",
"symfony/asset-mapper": "7.3.*", "symfony/asset-mapper": "7.3.*",
"symfony/console": "7.3.*", "symfony/console": "7.3.*",
"symfony/dotenv": "7.3.*", "symfony/dotenv": "7.3.*",
"symfony/flex": "^2.7.1", "symfony/flex": "^2.8.2",
"symfony/form": "7.3.*", "symfony/form": "7.3.*",
"symfony/framework-bundle": "7.3.*", "symfony/framework-bundle": "7.3.*",
"symfony/mailer": "7.3.*", "symfony/mailer": "7.3.*",
@@ -35,10 +35,10 @@
"symfony/serializer": "7.3.*", "symfony/serializer": "7.3.*",
"symfony/twig-bundle": "7.3.*", "symfony/twig-bundle": "7.3.*",
"symfony/uid": "7.3.*", "symfony/uid": "7.3.*",
"symfony/ux-turbo": "^2.26.1", "symfony/ux-turbo": "^2.30.0",
"symfony/yaml": "7.3.*", "symfony/yaml": "7.3.*",
"symfonycasts/sass-bundle": "^0.8.2", "symfonycasts/sass-bundle": "^0.8.3",
"symfonycasts/verify-email-bundle": "^1.17.3", "symfonycasts/verify-email-bundle": "^1.17.4",
"thecodingmachine/safe": "^3.3.0", "thecodingmachine/safe": "^3.3.0",
"twig/extra-bundle": "^3.21", "twig/extra-bundle": "^3.21",
"twig/intl-extra": "^3.21", "twig/intl-extra": "^3.21",
@@ -46,23 +46,23 @@
}, },
"require-dev": { "require-dev": {
"doctrine/doctrine-fixtures-bundle": "^4.1", "doctrine/doctrine-fixtures-bundle": "^4.1",
"friendsofphp/php-cs-fixer": "^3.75.0", "friendsofphp/php-cs-fixer": "^3.87.1",
"phpstan/extension-installer": "^1.4.3", "phpstan/extension-installer": "^1.4.3",
"phpstan/phpstan": "^2.1.17", "phpstan/phpstan": "^2.1.22",
"phpstan/phpstan-doctrine": "^2.0.3", "phpstan/phpstan-doctrine": "^2.0.5",
"phpstan/phpstan-phpunit": "^2.0.6", "phpstan/phpstan-phpunit": "^2.0.7",
"phpstan/phpstan-symfony": "^2.0.6", "phpstan/phpstan-symfony": "^2.0.8",
"phpunit/phpunit": "^12.2.1", "phpunit/phpunit": "^12.3.8",
"rector/rector": "^2.0.17", "rector/rector": "^2.1.6",
"roave/security-advisories": "dev-latest", "roave/security-advisories": "dev-latest",
"symfony/browser-kit": "7.3.*", "symfony/browser-kit": "7.3.*",
"symfony/css-selector": "7.3.*", "symfony/css-selector": "7.3.*",
"symfony/maker-bundle": "^1.63.0", "symfony/maker-bundle": "^1.64.0",
"symfony/phpunit-bridge": "7.3.*", "symfony/phpunit-bridge": "7.3.*",
"symfony/stopwatch": "7.3.*", "symfony/stopwatch": "7.3.*",
"symfony/web-profiler-bundle": "7.3.*", "symfony/web-profiler-bundle": "7.3.*",
"thecodingmachine/phpstan-safe-rule": "^1.4.1", "thecodingmachine/phpstan-safe-rule": "^1.4.1",
"vincentlanglet/twig-cs-fixer": "^3.7.1" "vincentlanglet/twig-cs-fixer": "^3.9.0"
}, },
"config": { "config": {
"allow-plugins": { "allow-plugins": {

1648
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -29,6 +29,7 @@ readonly class AddSettingsCommand
if (null !== $season->getSettings()) { if (null !== $season->getSettings()) {
continue; continue;
} }
$io->text('Adding settings to season : '.$season->getSeasonCode()); $io->text('Adding settings to season : '.$season->getSeasonCode());
$season->setSettings(new SeasonSettings()); $season->setSettings(new SeasonSettings());
} }

View File

@@ -7,6 +7,7 @@ namespace App\Controller\Admin;
use App\Entity\Answer; use App\Entity\Answer;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController; use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
/** @extends AbstractCrudController<Answer> */
class AnswerCrudController extends AbstractCrudController class AnswerCrudController extends AbstractCrudController
{ {
public static function getEntityFqcn(): string public static function getEntityFqcn(): string

View File

@@ -7,6 +7,7 @@ namespace App\Controller\Admin;
use App\Entity\Candidate; use App\Entity\Candidate;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController; use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
/** @extends AbstractCrudController<Candidate> */
class CandidateCrudController extends AbstractCrudController class CandidateCrudController extends AbstractCrudController
{ {
public static function getEntityFqcn(): string public static function getEntityFqcn(): string

View File

@@ -7,6 +7,7 @@ namespace App\Controller\Admin;
use App\Entity\GivenAnswer; use App\Entity\GivenAnswer;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController; use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
/** @extends AbstractCrudController<GivenAnswer> */
class GivenAnswerCrudController extends AbstractCrudController class GivenAnswerCrudController extends AbstractCrudController
{ {
public static function getEntityFqcn(): string public static function getEntityFqcn(): string

View File

@@ -7,6 +7,7 @@ namespace App\Controller\Admin;
use App\Entity\Question; use App\Entity\Question;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController; use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
/** @extends AbstractCrudController<Question> */
class QuestionCrudController extends AbstractCrudController class QuestionCrudController extends AbstractCrudController
{ {
public static function getEntityFqcn(): string public static function getEntityFqcn(): string

View File

@@ -7,7 +7,8 @@ namespace App\Controller\Admin;
use App\Entity\QuizCandidate; use App\Entity\QuizCandidate;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController; use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
class CorrectionCrudController extends AbstractCrudController /** @extends AbstractCrudController<QuizCandidate> */
class QuizCorrectionCrudController extends AbstractCrudController
{ {
public static function getEntityFqcn(): string public static function getEntityFqcn(): string
{ {

View File

@@ -7,6 +7,7 @@ namespace App\Controller\Admin;
use App\Entity\Quiz; use App\Entity\Quiz;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController; use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
/** @extends AbstractCrudController<Quiz> */
class QuizCrudController extends AbstractCrudController class QuizCrudController extends AbstractCrudController
{ {
public static function getEntityFqcn(): string public static function getEntityFqcn(): string

View File

@@ -7,6 +7,7 @@ namespace App\Controller\Admin;
use App\Entity\Season; use App\Entity\Season;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController; use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
/** @extends AbstractCrudController<Season> */
class SeasonCrudController extends AbstractCrudController class SeasonCrudController extends AbstractCrudController
{ {
public static function getEntityFqcn(): string public static function getEntityFqcn(): string

View File

@@ -7,6 +7,7 @@ namespace App\Controller\Admin;
use App\Entity\User; use App\Entity\User;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController; use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
/** @extends AbstractCrudController<User> */
class UserCrudController extends AbstractCrudController class UserCrudController extends AbstractCrudController
{ {
public static function getEntityFqcn(): string public static function getEntityFqcn(): string

View File

@@ -57,6 +57,7 @@ final class RegistrationController extends AbstractController
} catch (TransportExceptionInterface $e) { } catch (TransportExceptionInterface $e) {
$logger->error($e->getMessage()); $logger->error($e->getMessage());
} }
$response = $security->login($user, 'form_login', 'main'); $response = $security->login($user, 'form_login', 'main');
\assert($response instanceof Response); \assert($response instanceof Response);

View File

@@ -39,15 +39,8 @@ class RegistrationFormType extends AbstractType
'second_options' => ['label' => $this->translator->trans('Repeat Password')], 'second_options' => ['label' => $this->translator->trans('Repeat Password')],
'mapped' => false, 'mapped' => false,
'constraints' => [ 'constraints' => [
new NotBlank([ new NotBlank(message: 'Please enter a password'),
'message' => 'Please enter a password', new Length(min: 8, max: 4096, minMessage: 'Your password should be at least {{ limit }} characters'),
]),
new Length([
'min' => 8,
'minMessage' => 'Your password should be at least {{ limit }} characters',
// max length allowed by Symfony for security reasons
'max' => 4096,
]),
], ],
'translation_domain' => false, 'translation_domain' => false,
]) ])

View File

@@ -31,13 +31,9 @@ class UploadQuizFormType extends AbstractType
'required' => true, 'required' => true,
'translation_domain' => false, 'translation_domain' => false,
'constraints' => [ 'constraints' => [
new File([ new File(maxSize: '1024k', mimeTypes: [
'maxSize' => '1024k',
'mimeTypes' => [
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
], ], mimeTypesMessage: $this->translator->trans('Please upload a valid XLSX file')),
'mimeTypesMessage' => $this->translator->trans('Please upload a valid XLSX file'),
]),
], ],
]) ])
; ;

View File

@@ -12,6 +12,7 @@ use App\Entity\Quiz;
use App\Entity\Season; use App\Entity\Season;
use App\Entity\User; use App\Entity\User;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Vote;
use Symfony\Component\Security\Core\Authorization\Voter\Voter; use Symfony\Component\Security\Core\Authorization\Voter\Voter;
/** @extends Voter<string, Season> */ /** @extends Voter<string, Season> */
@@ -37,7 +38,7 @@ final class SeasonVoter extends Voter
} }
/** @param Season|Elimination|Quiz|Candidate|Answer|Question $subject */ /** @param Season|Elimination|Quiz|Candidate|Answer|Question $subject */
protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token): bool protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token, ?Vote $vote = null): bool
{ {
$user = $token->getUser(); $user = $token->getUser();
if (!$user instanceof User) { if (!$user instanceof User) {