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
3 changes: 2 additions & 1 deletion .github/docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
# The base image is built from evolution-cms/salo2 runtimes/<php version> (Salo
# is the Evolution CMS flavour of Laravel Sail): php:<version>-apache with gd,
# zip, pdo and mod_rewrite. sqlite3/pdo_sqlite come enabled in the official php
# images. The workflow builds 8.3, 8.4 and 8.5 and overrides BASE_IMAGE per leg.
# images. The workflow builds every version .github/scripts/php-versions.sh lists
# for the tree (8.3 too below CMS 3.6) and overrides BASE_IMAGE per leg.
ARG BASE_IMAGE=evo-salo-runtime:8.4
FROM ${BASE_IMAGE}

Expand Down
2 changes: 1 addition & 1 deletion .github/docker/ci/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
# installer, the migrations and the seeded data, and the built in web server is
# enough to prove the installed site answers. Which web server serves it is what
# the Salo images in .github/docker/Dockerfile are for.
ARG PHP_VERSION=8.4
ARG PHP_VERSION=8.3
FROM php:${PHP_VERSION}-cli

# libpq/libzip/libicu are the build inputs of the extensions below; the -dev
Expand Down
12 changes: 7 additions & 5 deletions .github/docker/ci/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ EVO_DB_TYPE=sqlite EVO_APP_DIR="$PWD" .github/docker/ci/install-and-smoke.sh
```

`PHP_VERSION`, `MYSQL_IMAGE_TAG`, `POSTGRES_IMAGE_TAG`, `MYSQL_PORT` and
`POSTGRES_PORT` override the defaults (PHP 8.4, MySQL 9.7 LTS, PostgreSQL 18.6
`POSTGRES_PORT` override the defaults (PHP 8.3, MySQL 9.7 LTS, PostgreSQL 18.6
LTS, the servers' own ports).

## Upgrading
Expand Down Expand Up @@ -79,11 +79,13 @@ no PHP on it, and what pins the PHP version when a version question is the one
being investigated.

One PHP version, every database: what the job proves is the installer's database
paths, which do not vary with the PHP minor. PHP 8.4 and 8.5 are covered by
the analysis and unit test jobs. The sqlite leg starts no container.
paths, which do not vary with the PHP minor, and it runs on the lowest one
`.github/scripts/php-versions.sh` lists. The analysis and unit test jobs cover
all of them: 8.4 and 8.5, plus 8.3 while the CMS version is below 3.6. The
sqlite leg starts no container.

The same workflow also builds this image from the official `php:8.6-rc-cli`
image and runs the unit tests in it. The `8.6-rc` tag follows the latest PHP 8.6
From CMS 3.6 on (the 3.5 line skips it), the same workflow also builds this
image from the official `php:8.6-rc-cli` image and runs the unit tests in it. The `8.6-rc` tag follows the latest PHP 8.6
release candidate; it currently resolves to PHP 8.6.0RC3. The image includes
SQLite and mbstring support for the test suite. This prerelease compatibility
job reports the build, version and test results in the Actions summary and as a
Expand Down
4 changes: 2 additions & 2 deletions .github/docker/ci/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ services:
context: ../../..
dockerfile: .github/docker/ci/Dockerfile
args:
PHP_VERSION: ${PHP_VERSION:-8.4}
PHP_VERSION: ${PHP_VERSION:-8.3}
depends_on:
mysql:
condition: service_healthy
Expand All @@ -75,7 +75,7 @@ services:
context: ../../..
dockerfile: .github/docker/ci/Dockerfile
args:
PHP_VERSION: ${PHP_VERSION:-8.4}
PHP_VERSION: ${PHP_VERSION:-8.3}
depends_on:
pgsql:
condition: service_healthy
Expand Down
45 changes: 45 additions & 0 deletions .github/scripts/php-versions.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#!/bin/sh
# The PHP versions CI runs a tree on, decided by the CMS version of that tree:
# 3.6 requires PHP 8.4, the 3.5 line still supports 8.3, and the PHP 8.6 release
# candidate is a 3.6 concern only. So one set of workflows keeps testing 8.3 on
# 3.5.x and moves to 8.6 on 3.6.x, whichever branch it was merged to.
#
# Usage: php-versions.sh [tree] (default: the current directory)
# Writes to $GITHUB_OUTPUT when set, to stdout otherwise:
# versions JSON list for a job matrix, lowest first
# lowest the lowest of them, for jobs that run on one version only
# rc the prerelease version to check as well, empty for none
set -eu

tree=${1:-.}
file="$tree/core/factory/version.php"
version=$(sed -n "s/^[[:space:]]*'version'[[:space:]]*=>[[:space:]]*'\([0-9][0-9.]*\)'.*/\1/p" "$file" | head -n 1)
if [ -z "$version" ]; then
echo "::error file=$file::no 'version' => 'x.y.z' entry" >&2
exit 1
fi

major=${version%%.*}
rest=${version#*.}
minor=${rest%%.*}
if [ "$major" -gt 3 ] || { [ "$major" -eq 3 ] && [ "$minor" -ge 6 ]; }; then
set -- 8.4 8.5
rc=8.6
else
set -- 8.3 8.4 8.5
rc=
fi

lowest=$1
versions=$(printf '"%s",' "$@")
versions="[${versions%,}]"

result="versions=$versions
lowest=$lowest
rc=$rc"
if [ -n "${GITHUB_OUTPUT:-}" ]; then
echo "$result" >> "$GITHUB_OUTPUT"
else
echo "$result"
fi
echo "CMS $version: PHP $*${rc:+, $rc RC}" >&2
36 changes: 27 additions & 9 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,26 @@ env:
SALO2_REF: master

jobs:
php:
name: PHP versions
runs-on: ubuntu-latest
outputs:
versions: ${{ steps.php.outputs.versions }}
lowest: ${{ steps.php.outputs.lowest }}
steps:
- uses: actions/checkout@v7
with:
sparse-checkout: |
.github/scripts
core/factory

# 8.3 below CMS 3.6 only, see the script
- id: php
run: sh .github/scripts/php-versions.sh

zip:
name: Installed CMS (zip, sqlite)
needs: php
runs-on: ubuntu-latest
permissions:
contents: write # required to publish the nightly release
Expand All @@ -58,8 +76,8 @@ jobs:
uses: shivammathur/setup-php@v2
with:
# Built on the lowest supported version so the vendor tree stays
# usable on 8.4 and 8.5 alike.
php-version: '8.4'
# usable on every version the docker job runs it on.
php-version: ${{ needs.php.outputs.lowest }}
extensions: ctype, dom, fileinfo, filter, iconv, intl, json, mbstring, openssl, pdo, pdo_sqlite, readline, simplexml, sqlite3, tokenizer, xml, xmlreader, zip
coverage: none
tools: composer:v2
Expand All @@ -72,8 +90,8 @@ jobs:
uses: actions/cache@v6
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: composer-${{ runner.os }}-php8.4-build-${{ hashFiles('core/composer.lock') }}
restore-keys: composer-${{ runner.os }}-php8.4-build-
key: composer-${{ runner.os }}-php${{ needs.php.outputs.lowest }}-build-${{ hashFiles('core/composer.lock') }}
restore-keys: composer-${{ runner.os }}-php${{ needs.php.outputs.lowest }}-build-

- name: Install core dependencies
working-directory: core
Expand Down Expand Up @@ -169,7 +187,7 @@ jobs:

docker:
name: Docker image PHP ${{ matrix.php }} ${{ matrix.server }} (GHCR)
needs: zip
needs: [php, zip]
# Pull requests get a read-only token and cannot push packages, so the job is
# skipped there — including on the run that stays attached to a merged PR.
# The push to the base branch, and workflow_dispatch, are what build the image.
Expand All @@ -183,9 +201,9 @@ jobs:
# the ones that did build stay usable.
fail-fast: false
matrix:
# 8.4 is the lowest supported version and the one the vendor tree in the
# zip is built on, so it proves the archive is portable upwards.
php: ['8.4', '8.5']
# The lowest of them is the one the vendor tree in the zip is built on,
# so the others prove the archive is portable upwards.
php: ${{ fromJSON(needs.php.outputs.versions) }}
# Three different PHP SAPIs, not three front ends over one PHP: apache
# runs mod_php, nginx talks FastCGI to php-fpm, and FrankenPHP embeds
# PHP inside Caddy. They cannot share a base image, so each is a build.
Expand All @@ -196,7 +214,7 @@ jobs:
PUSH_IMAGE: ${{ github.event_name != 'workflow_dispatch' || inputs.docker == 'push' }}
PHP_VERSION: ${{ matrix.php }}
SERVER: ${{ matrix.server }}
# The combination that carries the unsuffixed tags, so `:3.6.x` keeps
# The combination that carries the unsuffixed tags, so `:3.5.x` keeps
# meaning what it meant before the matrix existed.
DEFAULT_PHP: '8.4'
DEFAULT_SERVER: apache
Expand Down
32 changes: 28 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,32 @@ env:
PHP_EXTENSIONS: ctype, dom, fileinfo, filter, iconv, intl, json, mbstring, openssl, pdo, pdo_sqlite, readline, simplexml, tokenizer, xml, xmlreader, zip

jobs:
php:
name: PHP versions
runs-on: ubuntu-latest
outputs:
versions: ${{ steps.php.outputs.versions }}
lowest: ${{ steps.php.outputs.lowest }}
rc: ${{ steps.php.outputs.rc }}
steps:
- uses: actions/checkout@v7
with:
sparse-checkout: |
.github/scripts
core/factory

# 8.3 below CMS 3.6 only, 8.6 RC from 3.6 only, see the script
- id: php
run: sh .github/scripts/php-versions.sh

analyze:
name: Static analysis (PHP ${{ matrix.php }})
needs: php
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
php: ['8.4', '8.5']
php: ${{ fromJSON(needs.php.outputs.versions) }}
steps:
- uses: actions/checkout@v7

Expand Down Expand Up @@ -57,11 +76,12 @@ jobs:

tests:
name: Unit tests (PHP ${{ matrix.php }})
needs: php
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
php: ['8.4', '8.5']
php: ${{ fromJSON(needs.php.outputs.versions) }}
steps:
- uses: actions/checkout@v7

Expand Down Expand Up @@ -94,6 +114,8 @@ jobs:

php86-rc:
name: PHP 8.6 RC compatibility (Docker)
needs: php
if: needs.php.outputs.rc == '8.6'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
Expand Down Expand Up @@ -143,6 +165,7 @@ jobs:

install:
name: Install on ${{ matrix.db }}
needs: php
runs-on: ubuntu-latest
strategy:
fail-fast: false
Expand Down Expand Up @@ -184,7 +207,7 @@ jobs:
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.4'
php-version: ${{ needs.php.outputs.lowest }}
extensions: ${{ env.PHP_EXTENSIONS }}, pdo_mysql, pdo_pgsql, sqlite3
ini-values: error_reporting=E_ALL, display_errors=On, display_startup_errors=On, log_errors=On, error_log=/dev/stderr
coverage: none
Expand Down Expand Up @@ -215,6 +238,7 @@ jobs:

audit:
name: Dependency audit
needs: php
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
Expand All @@ -224,7 +248,7 @@ jobs:
with:
# The audit reads composer.lock and the advisory database; it does not run the code,
# so one version is enough. Kept at the lowest supported one for consistency.
php-version: '8.4'
php-version: ${{ needs.php.outputs.lowest }}
extensions: ${{ env.PHP_EXTENSIONS }}
coverage: none
tools: composer:v2
Expand Down
19 changes: 16 additions & 3 deletions .github/workflows/upgrade.yml
Original file line number Diff line number Diff line change
Expand Up @@ -110,12 +110,25 @@ jobs:
if: matrix.leg.db != 'sqlite'
run: docker compose -f "new/$COMPOSE" --profile ${{ matrix.leg.db }} up -d --wait ${{ matrix.leg.db }}

# 8.4 is the lowest version both trees support, so it is the one that can
# run the old installer and the new updater in the same job.
# The script comes from this workflow's own commit: a "to" ref may be older
# than the script.
- name: Check out the CI scripts
uses: actions/checkout@v7
with:
path: ci
sparse-checkout: .github/scripts

# The lowest version the new tree supports (8.3 below CMS 3.6, 8.4 from
# 3.6), which the older trees run on too, so one job can run the old
# installer and the new updater.
- name: PHP version of the new tree
id: php
run: sh ci/.github/scripts/php-versions.sh new

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.4'
php-version: ${{ steps.php.outputs.lowest }}
extensions: ctype, dom, fileinfo, filter, iconv, intl, json, mbstring, openssl, pdo, pdo_mysql, pdo_pgsql, pdo_sqlite, readline, simplexml, sqlite3, tokenizer, xml, xmlreader, zip
ini-values: error_reporting=E_ALL, display_errors=On, display_startup_errors=On, log_errors=On, error_log=/dev/stderr
coverage: none
Expand Down
26 changes: 13 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

[![CMS Evolution](https://img.shields.io/badge/CMS-Evolution-brightgreen.svg)](https://packagist.org/packages/evolution-cms/evolution)
[![GitHub release](https://img.shields.io/github/release/evolution-cms/evolution.svg)](https://github.com/evolution-cms/evolution/releases)
[![PHP supported](https://img.shields.io/badge/PHP_supported-8.4_%7C_8.5-777BB4?logo=php&logoColor=white)](#php-compatibility)
[![PHP supported](https://img.shields.io/badge/PHP_supported-8.3_%7C_8.4_%7C_8.5-777BB4?logo=php&logoColor=white)](#php-compatibility)
[![PHP recommended](https://img.shields.io/badge/PHP_recommended-8.4-2ea44f?logo=php&logoColor=white)](#php-compatibility)
[![Issues](https://img.shields.io/github/issues-closed-raw/evolution-cms/evolution.svg?maxAge=2592000)](https://github.com/evolution-cms/evolution/issues)
[![Total Installs](https://img.shields.io/packagist/dt/evolution-cms/evolution)](https://packagist.org/packages/evolution-cms/evolution)
Expand Down Expand Up @@ -53,32 +53,32 @@ You can use the single click installer: [Evolution CMS Installer](https://github

### PHP compatibility

Evolution CMS **3.6.x** requires **PHP 8.4 or later within PHP 8.x** (`^8.4` in [core/composer.json](core/composer.json)).
Evolution CMS **3.5.x** requires **PHP 8.3 or later within PHP 8.x** (`^8.3` in [core/composer.json](core/composer.json)).

| PHP version | Evolution CMS support | Recommendation |
| --- | --- | --- |
| **8.4** | Supported; minimum required version | **Recommended for production and new installations** |
| **8.3** | Supported; minimum required version | Suitable for existing installations |
| **8.4** | Supported | **Recommended for production and new installations** |
| **8.5** | Supported | Check installed extras and custom code before upgrading |
| **8.6 RC** | Experimental compatibility checks only | Not recommended for production |

The [CI workflow](.github/workflows/ci.yml) runs static analysis and unit tests on PHP **8.4 and 8.5**. PHP **8.6 RC** has a separate experimental compatibility job and is not recommended for production.
The [CI workflow](.github/workflows/ci.yml) runs unit tests on PHP **8.3, 8.4 and 8.5**. PHP **8.6 RC** has a separate experimental compatibility job and is not recommended for production.

Use the latest patch release of your chosen PHP version. See the [PHP support lifecycle](https://www.php.net/supported-versions.php) for maintenance and security support dates.

## Update and switch versions

A site can move between a release (such as `3.5.9`), a development branch (such as `3.6.x`) and a fork in either direction. The target version must support the server's PHP version. Take a database backup first: a switch back to an older release keeps the database schema of the newer one.
A site can move between a release (such as `3.5.8`), the `3.5.x` development branch (nightly) and a fork in either direction. Take a database backup first: a switch back to an older release keeps the database schema of the newer one.

### With Artisan (recommended)

Run from the `core/` directory:

| Command | What it does |
| --- | --- |
| `php artisan make:site` | Updates along the line the site runs. A release moves to the newest release of its major version, a site on `3.6.x` takes the latest `3.6.x` again (run it every night to follow the nightly), a site on a fork branch takes that branch again. It never moves a site back to an older release. |
| `php artisan make:site update 3.6.x` | Switches to the `3.6.x` branch. The site stays on it until a version is passed again. |
| `php artisan make:site update 3.5.9` | Switches to a release, also an older one (back from `3.6.x` or from a fork). |
| `php artisan make:site update nightly-3.6.x` | Switches to the nightly build tag. |
| `php artisan make:site` | Updates along the line the site runs. A release moves to the newest release of its major version, a site on `3.5.x` takes the latest `3.5.x` again (run it every night to follow the nightly), a site on a fork branch takes that branch again. It never moves a site back to an older release. |
| `php artisan make:site update 3.5.x` | Switches to the `3.5.x` branch. The site stays on it until a version is passed again. |
| `php artisan make:site update 3.5.8` | Switches to a release, also an older one (back from `3.5.x` or from a fork). |
| `php artisan make:site update nightly-3.5.x` | Switches to the nightly build tag. |
| `php artisan make:site update https://github.com/<owner>/evolution/tree/<branch>` | Switches to a branch or tag of a fork, as GitHub shows it in the browser. `.../releases/tag/<tag>` and `.../commit/<hash>` work too. A plain `make:site` then stays on that branch of the fork. |
| `php artisan make:site update <branch> --repository=<owner>/evolution` | The same as the URL form. |

Expand All @@ -98,7 +98,7 @@ Packages added through `core/custom/composer.json` are kept on every update and
Get the files of the version you want, lay them over the site and run the installer in update mode:

```bash
composer create-project --no-install evolution-cms/evolution /tmp/evo 3.6.x-dev # or 3.5.9
composer create-project --no-install evolution-cms/evolution /tmp/evo 3.5.x-dev # or 3.5.8
cp -a /tmp/evo/. /path/to/site/ # or unpack a release / branch archive there
cd /path/to/site/install
php cli-install.php --typeInstall=2 --removeInstall=y
Expand All @@ -110,11 +110,11 @@ Instead of the last two lines you can open `/install/` in the browser while logg

### From the manager

The update widget on the dashboard follows the line the site runs. A release is offered newer releases. A site updated from `3.6.x`, `nightly-3.6.x` or a fork branch is offered that branch again once it has new commits (with a link to the changes), from the repository it came from. **Manual update (WEB)** queues `make:site` for that target, so everything above applies. To leave a branch for a release, run `php artisan make:site update <release>`.
The update widget on the dashboard follows the line the site runs. A release is offered newer releases. A site updated from `3.5.x`, `nightly-3.5.x` or a fork branch is offered that branch again once it has new commits (with a link to the changes), from the repository it came from. **Manual update (WEB)** queues `make:site` for that target, so everything above applies. To leave a branch for a release, run `php artisan make:site update <release>`.

### Things to know

- When moving from **3.5.8** to `3.6.x`, the 3.5.8 updater reports the old version at the end; the site is on `3.6.x` all the same. The 3.5.8 CLI installer cannot restore custom Composer packages, so switch back to 3.5.8 with `make:site update 3.5.8` rather than with its `cli-install.php`.
- Moving from **3.5.8** to `3.5.x` is done by the 3.5.8 updater, which reports the old version at the end; the site is on `3.5.x` all the same. Its CLI installer cannot restore custom Composer packages, so switch back to 3.5.8 with `make:site update 3.5.8` rather than with its `cli-install.php`.
- After a git pull or rsync of new code, with no update step, run `php artisan migrate` and `composer update <your custom packages>` in `core/`. Compiled templates refresh by themselves.
- An old fork branch is an old version of Evolution CMS: switching to it is a downgrade.

Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
"vendor-dir": "vendor"
},
"require": {
"php": "^8.4",
"php": "^8.3",
"ext-pdo": "*",
"ext-json": "*",
"ext-readline": "*",
Expand Down
Loading
Loading