From 9409284ad4273610d78448d3c29c4227a2435294 Mon Sep 17 00:00:00 2001 From: TheMilek Date: Wed, 13 May 2026 12:35:23 +0200 Subject: [PATCH 1/3] Reorganise build --- .../{ci__full_2_2.yaml => ci__full.yaml} | 23 ++-- .github/workflows/ci__full_1_14.yaml | 118 ---------------- .github/workflows/ci__full_2_1.yaml | 129 ------------------ .github/workflows/ci_e2e-mariadb.yaml | 28 +--- .github/workflows/ci_e2e-mysql.yaml | 28 +--- .github/workflows/ci_e2e-pgsql.yaml | 28 +--- .github/workflows/ci_frontend.yaml | 11 -- .github/workflows/ci_js.yaml | 26 +--- .github/workflows/ci_static-checks.yaml | 4 - 9 files changed, 21 insertions(+), 374 deletions(-) rename .github/workflows/{ci__full_2_2.yaml => ci__full.yaml} (91%) delete mode 100644 .github/workflows/ci__full_1_14.yaml delete mode 100644 .github/workflows/ci__full_2_1.yaml diff --git a/.github/workflows/ci__full_2_2.yaml b/.github/workflows/ci__full.yaml similarity index 91% rename from .github/workflows/ci__full_2_2.yaml rename to .github/workflows/ci__full.yaml index 5128fd609d..c12f918548 100644 --- a/.github/workflows/ci__full_2_2.yaml +++ b/.github/workflows/ci__full.yaml @@ -1,4 +1,4 @@ -name: Continuous Integration 2.2 (Full) +name: Continuous Integration (Full) on: push: @@ -10,17 +10,17 @@ on: workflow_dispatch: ~ concurrency: - group: ci-${{ github.workflow }}-${{ github.ref }}-2_0-full + group: ci-${{ github.workflow }}-${{ github.ref }}-full cancel-in-progress: true -permissions: +permissions: contents: read jobs: static-checks: strategy: matrix: - branch: ["2.2"] + branch: ["2.2", "2.3"] name: "[${{ matrix.branch }}] Static checks" uses: ./.github/workflows/ci_static-checks.yaml with: @@ -29,7 +29,7 @@ jobs: e2e-mariadb: strategy: matrix: - branch: ["2.2"] + branch: ["2.2", "2.3"] name: "[${{ matrix.branch }}] Tests (MariaDB)" needs: static-checks uses: ./.github/workflows/ci_e2e-mariadb.yaml @@ -39,7 +39,7 @@ jobs: e2e-mysql: strategy: matrix: - branch: ["2.2"] + branch: ["2.2", "2.3"] name: "[${{ matrix.branch }}] Tests (MySQL)" needs: static-checks uses: ./.github/workflows/ci_e2e-mysql.yaml @@ -49,7 +49,7 @@ jobs: e2e-pgsql: strategy: matrix: - branch: ["2.2"] + branch: ["2.2", "2.3"] name: "[${{ matrix.branch }}] Tests (PostgreSQL)" needs: static-checks uses: ./.github/workflows/ci_e2e-pgsql.yaml @@ -59,7 +59,7 @@ jobs: e2e-js: strategy: matrix: - branch: ["2.2"] + branch: ["2.2", "2.3"] name: "[${{ matrix.branch }}] Javascript Tests (MySQL)" needs: static-checks uses: ./.github/workflows/ci_js.yaml @@ -67,7 +67,10 @@ jobs: branch: ${{ matrix.branch }} type: full frontend: - name: Frontend + strategy: + matrix: + branch: ["2.2", "2.3"] + name: "[${{ matrix.branch }}] Frontend" needs: static-checks uses: ./.github/workflows/ci_frontend.yaml with: @@ -76,7 +79,7 @@ jobs: packages: strategy: matrix: - branch: ["2.2"] + branch: ["2.2", "2.3"] name: "[${{ matrix.branch }}] Packages" needs: static-checks uses: ./.github/workflows/ci_packages.yaml diff --git a/.github/workflows/ci__full_1_14.yaml b/.github/workflows/ci__full_1_14.yaml deleted file mode 100644 index 828155d603..0000000000 --- a/.github/workflows/ci__full_1_14.yaml +++ /dev/null @@ -1,118 +0,0 @@ -name: Continuous Integration 1.14 (Full) - -on: - push: - branches: - - 'full-ci/**' - schedule: - - - cron: "0 1 * * *" # Run every day at 1am - workflow_dispatch: ~ - -concurrency: - group: ci-${{ github.workflow }}-${{ github.ref }}-1_14-full - cancel-in-progress: true - -permissions: - contents: read - -jobs: - static-checks: - strategy: - matrix: - branch: ["1.14"] - name: "[${{ matrix.branch }}] Static checks" - uses: ./.github/workflows/ci_static-checks.yaml - with: - branch: ${{ matrix.branch }} - type: full - e2e-mariadb: - strategy: - matrix: - branch: ["1.14"] - name: "[${{ matrix.branch }}] End-to-end tests (MariaDB)" - needs: static-checks - uses: ./.github/workflows/ci_e2e-mariadb.yaml - with: - branch: ${{ matrix.branch }} - type: full - e2e-mysql: - strategy: - matrix: - branch: ["1.14"] - name: "[${{ matrix.branch }}] End-to-end tests (MySQL)" - needs: static-checks - uses: ./.github/workflows/ci_e2e-mysql.yaml - with: - branch: ${{ matrix.branch }} - type: full - e2e-pgsql: - strategy: - matrix: - branch: ["1.14"] - name: "[${{ matrix.branch }}] End-to-end tests (PostgreSQL)" - needs: static-checks - uses: ./.github/workflows/ci_e2e-pgsql.yaml - with: - branch: ${{ matrix.branch }} - type: full - frontend: - name: Frontend - needs: static-checks - uses: ./.github/workflows/ci_frontend.yaml - with: - branch: ${{ matrix.branch }} - type: full - packages: - strategy: - matrix: - branch: ["1.14"] - name: "[${{ matrix.branch }}] Packages" - needs: static-checks - uses: ./.github/workflows/ci_packages.yaml - with: - branch: ${{ matrix.branch }} - type: full - notify-about-build-status: - if: ${{ always() }} - name: "Notify about build status" - needs: [static-checks, e2e-mariadb, e2e-mysql, e2e-pgsql, frontend, packages] - runs-on: ubuntu-latest - timeout-minutes: 20 - - steps: - - name: "Process data" - id: process-data - shell: bash - run: | - echo "branch=$(echo ${{ github.ref }} | sed 's/refs\/heads\///g' | sed 's/refs\/tags\///g')" >> $GITHUB_OUTPUT - echo "sha=$(echo ${{ github.sha }} | cut -c 1-12)" >> $GITHUB_OUTPUT - - - name: "Notify on Slack" - uses: edge/simple-slack-notify@master - env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} - if: env.SLACK_WEBHOOK_URL != null - with: - channel: "#daily-build" - username: "GitHub Actions" - text: | - ** - - ${{ needs.static-checks.result == 'success' && ':+1:' || ':x:' }} Static Checks - ${{ needs.e2e-mariadb.result == 'success' && ':+1:' || ':x:' }} End-to-End (MariaDB) - ${{ needs.e2e-mysql.result == 'success' && ':+1:' || ':x:' }} End-to-End (MySQL) - ${{ needs.e2e-pgsql.result == 'success' && ':+1:' || ':x:' }} End-to-End (PostgreSQL) - ${{ needs.frontend.result == 'success' && ':+1:' || ':x:' }} Frontend - ${{ needs.packages.result == 'success' && ':+1:' || ':x:' }} Packages - - _ _ _ _ _ _ _ - color: "danger" - fields: | - [ - { "title": "Repository", "value": "", "short": true }, - { "title": "Action", "value": "", "short": true }, - { "title": "Reference", "value": "", "short": true }, - { "title": "Commit", "value": "", "short": true }, - { "title": "Event", "value": "${{ github.event_name }}", "short": true } - ] diff --git a/.github/workflows/ci__full_2_1.yaml b/.github/workflows/ci__full_2_1.yaml deleted file mode 100644 index d429593951..0000000000 --- a/.github/workflows/ci__full_2_1.yaml +++ /dev/null @@ -1,129 +0,0 @@ -name: Continuous Integration 2.1 (Full) - -on: - push: - branches: - - 'full-ci/**' - schedule: - - - cron: "0 2 * * *" # Run every day at 2am - workflow_dispatch: ~ - -concurrency: - group: ci-${{ github.workflow }}-${{ github.ref }}-2_1-full - cancel-in-progress: true - -permissions: - contents: read - -jobs: - static-checks: - strategy: - matrix: - branch: ["2.1"] - name: "[${{ matrix.branch }}] Static checks" - uses: ./.github/workflows/ci_static-checks.yaml - with: - branch: ${{ matrix.branch }} - type: full - e2e-mariadb: - strategy: - matrix: - branch: ["2.1"] - name: "[${{ matrix.branch }}] Tests (MariaDB)" - needs: static-checks - uses: ./.github/workflows/ci_e2e-mariadb.yaml - with: - branch: ${{ matrix.branch }} - type: full - e2e-mysql: - strategy: - matrix: - branch: ["2.1"] - name: "[${{ matrix.branch }}] Tests (MySQL)" - needs: static-checks - uses: ./.github/workflows/ci_e2e-mysql.yaml - with: - branch: ${{ matrix.branch }} - type: full - e2e-pgsql: - strategy: - matrix: - branch: ["2.1"] - name: "[${{ matrix.branch }}] Tests (PostgreSQL)" - needs: static-checks - uses: ./.github/workflows/ci_e2e-pgsql.yaml - with: - branch: ${{ matrix.branch }} - type: full - e2e-js: - strategy: - matrix: - branch: ["2.1"] - name: "[${{ matrix.branch }}] Javascript Tests (MySQL)" - needs: static-checks - uses: ./.github/workflows/ci_js.yaml - with: - branch: ${{ matrix.branch }} - type: full - frontend: - name: Frontend - needs: static-checks - uses: ./.github/workflows/ci_frontend.yaml - with: - branch: ${{ matrix.branch }} - type: full - packages: - strategy: - matrix: - branch: ["2.1"] - name: "[${{ matrix.branch }}] Packages" - needs: static-checks - uses: ./.github/workflows/ci_packages.yaml - with: - branch: ${{ matrix.branch }} - type: full - notify-about-build-status: - if: ${{ always() }} - name: "Notify about build status" - needs: [static-checks, e2e-mariadb, e2e-mysql, e2e-pgsql, e2e-js, frontend, packages] - runs-on: ubuntu-latest - timeout-minutes: 20 - - steps: - - name: "Process data" - id: process-data - shell: bash - run: | - echo "branch=$(echo ${{ github.ref }} | sed 's/refs\/heads\///g' | sed 's/refs\/tags\///g')" >> $GITHUB_OUTPUT - echo "sha=$(echo ${{ github.sha }} | cut -c 1-12)" >> $GITHUB_OUTPUT - - - name: "Notify on Slack" - uses: edge/simple-slack-notify@master - env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} - if: env.SLACK_WEBHOOK_URL != null - with: - channel: "#daily-build" - username: "GitHub Actions" - text: | - ** - - ${{ needs.static-checks.result == 'success' && ':+1:' || ':x:' }} Static Checks - ${{ needs.e2e-mariadb.result == 'success' && ':+1:' || ':x:' }} Tests (MariaDB) - ${{ needs.e2e-mysql.result == 'success' && ':+1:' || ':x:' }} Tests (MySQL) - ${{ needs.e2e-pgsql.result == 'success' && ':+1:' || ':x:' }} Tests (PostgreSQL) - ${{ needs.e2e-js.result == 'success' && ':+1:' || ':x:' }} Javascript Tests (MySQL) - ${{ needs.frontend.result == 'success' && ':+1:' || ':x:' }} Frontend - ${{ needs.packages.result == 'success' && ':+1:' || ':x:' }} Packages - - _ _ _ _ _ _ _ - color: "danger" - fields: | - [ - { "title": "Repository", "value": "", "short": true }, - { "title": "Action", "value": "", "short": true }, - { "title": "Reference", "value": "", "short": true }, - { "title": "Commit", "value": "", "short": true }, - { "title": "Event", "value": "${{ github.event_name }}", "short": true } - ] diff --git a/.github/workflows/ci_e2e-mariadb.yaml b/.github/workflows/ci_e2e-mariadb.yaml index 25804a7791..41758c0aaf 100644 --- a/.github/workflows/ci_e2e-mariadb.yaml +++ b/.github/workflows/ci_e2e-mariadb.yaml @@ -57,17 +57,6 @@ jobs: BEHAT_RERUN_CMD: "vendor/bin/behat --colors --strict --no-interaction -vvv -f pretty --rerun" steps: - - name: Set variables - shell: bash - env: - BRANCH: ${{ inputs.branch }} - run: | - if [ "$BRANCH" == "1.14" ]; then - echo "NODE_VERSION=20.x" >> $GITHUB_ENV - else - echo "NODE_VERSION=24.x" >> $GITHUB_ENV - fi - - name: "Checkout (With Branch)" if: "${{ inputs.branch != '' }}" uses: actions/checkout@v4 @@ -85,7 +74,6 @@ jobs: composer require winzou/state-machine-bundle:^0.6 --no-update - name: Prepare manifest.json files - if: "${{ inputs.branch != '1.14' }}" run: | mkdir -p public/build/admin mkdir -p public/build/shop @@ -125,7 +113,7 @@ jobs: database: "mariadb:${{ matrix.mariadb }}" php_version: ${{ matrix.php }} symfony_version: ${{ matrix.symfony }} - node_version: ${{ env.NODE_VERSION }} + node_version: "24.x" chrome_version: stable - name: Run PHPUnit @@ -170,17 +158,6 @@ jobs: BEHAT_RERUN_CMD: "vendor/bin/behat --colors --strict --no-interaction -vvv -f pretty --rerun" steps: - - name: Set variables - shell: bash - env: - BRANCH: ${{ inputs.branch }} - run: | - if [ "$BRANCH" == "1.14" ]; then - echo "NODE_VERSION=20.x" >> $GITHUB_ENV - else - echo "NODE_VERSION=24.x" >> $GITHUB_ENV - fi - - name: "Checkout (With Branch)" if: "${{ inputs.branch != '' }}" uses: actions/checkout@v4 @@ -198,7 +175,6 @@ jobs: composer require winzou/state-machine-bundle:^0.6 --no-update - name: Prepare manifest.json files - if: "${{ inputs.branch != '1.14' }}" run: | mkdir -p public/build/admin mkdir -p public/build/shop @@ -238,7 +214,7 @@ jobs: database: "mariadb:${{ matrix.mariadb }}" php_version: ${{ matrix.php }} symfony_version: ${{ matrix.symfony }} - node_version: ${{ env.NODE_VERSION }} + node_version: "24.x" chrome_version: stable - name: Run UI Behat diff --git a/.github/workflows/ci_e2e-mysql.yaml b/.github/workflows/ci_e2e-mysql.yaml index e9685c8ede..ea5d2da1a6 100644 --- a/.github/workflows/ci_e2e-mysql.yaml +++ b/.github/workflows/ci_e2e-mysql.yaml @@ -56,17 +56,6 @@ jobs: BEHAT_RERUN_CMD: "vendor/bin/behat --colors --strict --no-interaction -vvv -f pretty --rerun" steps: - - name: Set variables - shell: bash - env: - BRANCH: ${{ inputs.branch }} - run: | - if [ "$BRANCH" == "1.14" ]; then - echo "NODE_VERSION=20.x" >> $GITHUB_ENV - else - echo "NODE_VERSION=24.x" >> $GITHUB_ENV - fi - - name: "Checkout (With Branch)" if: "${{ inputs.branch != '' }}" uses: actions/checkout@v4 @@ -82,7 +71,6 @@ jobs: run: composer require --no-update --no-scripts --no-interaction "twig/twig:${{ matrix.twig }}" - name: Prepare manifest.json files - if: "${{ inputs.branch != '1.14' }}" run: | mkdir -p public/build/admin mkdir -p public/build/shop @@ -103,7 +91,7 @@ jobs: database: "mysql:${{ matrix.mysql }}" php_version: ${{ matrix.php }} symfony_version: ${{ matrix.symfony }} - node_version: ${{ env.NODE_VERSION }} + node_version: "24.x" - name: Fix permissions for Symfony logs directory run: | @@ -155,17 +143,6 @@ jobs: BEHAT_RERUN_CMD: "vendor/bin/behat --colors --strict --no-interaction -vvv -f pretty --rerun" steps: - - name: Set variables - shell: bash - env: - BRANCH: ${{ inputs.branch }} - run: | - if [ "$BRANCH" == "1.14" ]; then - echo "NODE_VERSION=20.x" >> $GITHUB_ENV - else - echo "NODE_VERSION=24.x" >> $GITHUB_ENV - fi - - name: "Checkout (With Branch)" if: "${{ inputs.branch != '' }}" uses: actions/checkout@v4 @@ -181,7 +158,6 @@ jobs: run: composer require --no-update --no-scripts --no-interaction "twig/twig:${{ matrix.twig }}" - name: Prepare manifest.json files - if: "${{ inputs.branch != '1.14' }}" run: | mkdir -p public/build/admin mkdir -p public/build/shop @@ -202,7 +178,7 @@ jobs: database: "mysql:${{ matrix.mysql }}" php_version: ${{ matrix.php }} symfony_version: ${{ matrix.symfony }} - node_version: ${{ env.NODE_VERSION }} + node_version: "24.x" - name: Run UI Behat run: | diff --git a/.github/workflows/ci_e2e-pgsql.yaml b/.github/workflows/ci_e2e-pgsql.yaml index af2202f854..7eda11f3a0 100644 --- a/.github/workflows/ci_e2e-pgsql.yaml +++ b/.github/workflows/ci_e2e-pgsql.yaml @@ -56,17 +56,6 @@ jobs: BEHAT_RERUN_CMD: "vendor/bin/behat --colors --strict --no-interaction -vvv -f pretty --rerun" steps: - - name: Set variables - shell: bash - env: - BRANCH: ${{ inputs.branch }} - run: | - if [ "$BRANCH" == "1.14" ]; then - echo "NODE_VERSION=20.x" >> $GITHUB_ENV - else - echo "NODE_VERSION=24.x" >> $GITHUB_ENV - fi - - name: "Checkout (With Branch)" if: "${{ inputs.branch != '' }}" uses: actions/checkout@v4 @@ -78,7 +67,6 @@ jobs: uses: actions/checkout@v4 - name: Prepare manifest.json files - if: "${{ inputs.branch != '1.14' }}" run: | mkdir -p public/build/admin mkdir -p public/build/shop @@ -99,7 +87,7 @@ jobs: database: "postgres:${{ matrix.postgres }}" php_version: ${{ matrix.php }} symfony_version: ${{ matrix.symfony }} - node_version: ${{ env.NODE_VERSION }} + node_version: "24.x" chrome_version: stable - name: Run PHPUnit @@ -143,17 +131,6 @@ jobs: BEHAT_RERUN_CMD: "vendor/bin/behat --colors --strict --no-interaction -vvv -f pretty --rerun" steps: - - name: Set variables - shell: bash - env: - BRANCH: ${{ inputs.branch }} - run: | - if [ "$BRANCH" == "1.14" ]; then - echo "NODE_VERSION=20.x" >> $GITHUB_ENV - else - echo "NODE_VERSION=24.x" >> $GITHUB_ENV - fi - - name: "Checkout (With Branch)" if: "${{ inputs.branch != '' }}" uses: actions/checkout@v4 @@ -165,7 +142,6 @@ jobs: uses: actions/checkout@v4 - name: Prepare manifest.json files - if: "${{ inputs.branch != '1.14' }}" run: | mkdir -p public/build/admin mkdir -p public/build/shop @@ -186,7 +162,7 @@ jobs: database: "postgres:${{ matrix.postgres }}" php_version: ${{ matrix.php }} symfony_version: ${{ matrix.symfony }} - node_version: ${{ env.NODE_VERSION }} + node_version: "24.x" chrome_version: stable - name: Run UI Behat diff --git a/.github/workflows/ci_frontend.yaml b/.github/workflows/ci_frontend.yaml index b76ec24740..7d69b82c84 100644 --- a/.github/workflows/ci_frontend.yaml +++ b/.github/workflows/ci_frontend.yaml @@ -50,17 +50,6 @@ jobs: APP_ENV: test_cached steps: - - name: Set variables - shell: bash - env: - BRANCH: ${{ inputs.branch }} - run: | - if [ "$BRANCH" == "1.12" ]; then - echo "USE_LEGACY_POSTGRES_SETUP=yes" >> $GITHUB_ENV - else - echo "USE_LEGACY_POSTGRES_SETUP=no" >> $GITHUB_ENV - fi - - name: "Checkout (With Branch)" if: "${{ inputs.branch != '' }}" uses: actions/checkout@v4 diff --git a/.github/workflows/ci_js.yaml b/.github/workflows/ci_js.yaml index a61569283d..c528be7376 100644 --- a/.github/workflows/ci_js.yaml +++ b/.github/workflows/ci_js.yaml @@ -64,17 +64,6 @@ jobs: BEHAT_RERUN_CMD: "vendor/bin/behat --colors --strict --no-interaction -vvv -f pretty --rerun" steps: - - name: Set variables - shell: bash - env: - BRANCH: ${{ inputs.branch }} - run: | - if [ "$BRANCH" == "1.14" ]; then - echo "NODE_VERSION=20.x" >> $GITHUB_ENV - else - echo "NODE_VERSION=24.x" >> $GITHUB_ENV - fi - - name: "Checkout (With Branch)" if: "${{ inputs.branch != '' }}" uses: actions/checkout@v4 @@ -111,7 +100,7 @@ jobs: database: "mysql:${{ matrix.mysql }}" php_version: ${{ matrix.php }} symfony_version: ${{ matrix.symfony }} - node_version: ${{ env.NODE_VERSION }} + node_version: "24.x" - name: Run Behat (${{ matrix.group }}) run: | @@ -145,17 +134,6 @@ jobs: BEHAT_RERUN_CMD: "vendor/bin/behat --colors --strict --no-interaction -vvv -f pretty --rerun" steps: - - name: Set variables - shell: bash - env: - BRANCH: ${{ inputs.branch }} - run: | - if [ "$BRANCH" == "1.14" ]; then - echo "NODE_VERSION=20.x" >> $GITHUB_ENV - else - echo "NODE_VERSION=24.x" >> $GITHUB_ENV - fi - - name: "Checkout (With Branch)" if: "${{ inputs.branch != '' }}" uses: actions/checkout@v4 @@ -192,7 +170,7 @@ jobs: database: "mysql:${{ matrix.mysql }}" php_version: ${{ matrix.php }} symfony_version: ${{ matrix.symfony }} - node_version: ${{ env.NODE_VERSION }} + node_version: "24.x" chrome_version: stable - name: Run Behat (Panther) diff --git a/.github/workflows/ci_static-checks.yaml b/.github/workflows/ci_static-checks.yaml index 7766a97ddb..4bef94c30c 100644 --- a/.github/workflows/ci_static-checks.yaml +++ b/.github/workflows/ci_static-checks.yaml @@ -122,10 +122,6 @@ jobs: - name: Run PHPStan run: vendor/bin/phpstan analyse - - name: Run PHPSpec - if: ${{ inputs.branch == '1.14' }} - run: vendor/bin/phpspec run --ansi --no-interaction -f dot - - name: Run ComposerRequireChecker run: | (cat composer.json | jq '.["autoload-dev"]["psr-4"] |= . + {"Sylius\\Behat\\": "src/Sylius/Behat/"}' | jq 'del(.autoload["psr-4"]["Sylius\\Behat\\"])') > _composer.json From 81a0deef68edc2354cb388f4358b085bdf3969a7 Mon Sep 17 00:00:00 2001 From: TheMilek Date: Wed, 13 May 2026 12:37:13 +0200 Subject: [PATCH 2/3] Update PR tempalte --- .github/PULL_REQUEST_TEMPLATE.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index e94c59d7d7..ac2b1b1b0f 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,6 +1,6 @@ | Q | A |-----------------|----- -| Branch? | 1.14, 2.0 or 2.1 +| Branch? | 2.2 or 2.3 | Bug fix? | no/yes | New feature? | no/yes | BC breaks? | no/yes @@ -9,8 +9,8 @@ | License | MIT