|
| 1 | +# Install and upgrade checks |
| 2 | + |
| 3 | +Two scripts, one set of assertions: |
| 4 | + |
| 5 | +- `install-and-smoke.sh` installs this tree onto a database and checks what it |
| 6 | + put there, then runs the updater over it to catch anything not idempotent. |
| 7 | +- `upgrade-and-smoke.sh` installs an **older release**, copies this tree over it |
| 8 | + the way unpacking a release archive would, and runs the updater. That is the |
| 9 | + only check that replays the migration chain over a schema this branch did not |
| 10 | + create - what every existing site does when it moves to a new release. |
| 11 | + |
| 12 | +Both take a `sqlite`, `mysql` or `pgsql` database from `EVO_DB_TYPE`. |
| 13 | + |
| 14 | +## Installing |
| 15 | + |
| 16 | +Run either database leg from the repository root: |
| 17 | + |
| 18 | +```sh |
| 19 | +docker compose -f .github/docker/ci/docker-compose.yml --profile mysql up \ |
| 20 | + --build --abort-on-container-exit --exit-code-from install-mysql |
| 21 | + |
| 22 | +docker compose -f .github/docker/ci/docker-compose.yml --profile pgsql up \ |
| 23 | + --build --abort-on-container-exit --exit-code-from install-pgsql |
| 24 | +``` |
| 25 | + |
| 26 | +Clean up with `docker compose -f .github/docker/ci/docker-compose.yml --profile |
| 27 | +<mysql|pgsql> down -v`. The container works on a copy of the tree, not a bind |
| 28 | +mount, so a run leaves the working tree alone. |
| 29 | + |
| 30 | +sqlite needs no container at all: |
| 31 | + |
| 32 | +```sh |
| 33 | +EVO_DB_TYPE=sqlite EVO_APP_DIR="$PWD" .github/docker/ci/install-and-smoke.sh |
| 34 | +``` |
| 35 | + |
| 36 | +`PHP_VERSION`, `MYSQL_IMAGE_TAG`, `POSTGRES_IMAGE_TAG`, `MYSQL_PORT` and |
| 37 | +`POSTGRES_PORT` override the defaults (PHP 8.3, MySQL 9.7 LTS, PostgreSQL 18.6 |
| 38 | +LTS, the servers' own ports). |
| 39 | + |
| 40 | +## Upgrading |
| 41 | + |
| 42 | +`upgrade-and-smoke.sh` needs two trees: the older one it installs and upgrades |
| 43 | +in place, and this one to copy over it. The older tree is left dirty, so give it |
| 44 | +a checkout that can be thrown away. |
| 45 | + |
| 46 | +```sh |
| 47 | +git clone --depth 1 --branch 3.5.7 https://github.com/evolution-cms/evolution /tmp/evo-3.5.7 |
| 48 | +EVO_FROM_DIR=/tmp/evo-3.5.7 EVO_NEW_DIR="$PWD" EVO_DB_TYPE=mysql EVO_DB_HOST=127.0.0.1 EVO_DB_USER=root EVO_DB_PASSWORD=secret .github/docker/ci/upgrade-and-smoke.sh |
| 49 | +``` |
| 50 | + |
| 51 | +Two things about the source version are worth knowing: |
| 52 | + |
| 53 | +- **No released version installs on sqlite.** `cli-install.php` offered only |
| 54 | + `pgsql` and `mysql` through 3.5.7; the sqlite branch is new in this tree. So a |
| 55 | + sqlite upgrade leg has to take its source from a ref that carries it - the |
| 56 | + `nightly-3.5.x` tag, or any 3.5.x commit after it landed. A tag works here |
| 57 | + like any other ref once a release ships sqlite support. |
| 58 | +- **No `--skipComposer` before 3.5.8 either.** An older `composerUpdate()` runs |
| 59 | + whatever it finds at `core/vendor/bin/composer` and only warns when that is |
| 60 | + missing, so the script moves the shim aside: `core/vendor` is committed at |
| 61 | + every tag, and a composer update would test the network rather than the CMS. |
| 62 | + |
| 63 | +The source install is checked for hard failures only. A release run on a newer |
| 64 | +PHP may emit deprecations that are not this branch's to fix, and they are not |
| 65 | +what is under test - the updater's own log is checked strictly. |
| 66 | + |
| 67 | +## What CI runs |
| 68 | + |
| 69 | +The `install` job in `.github/workflows/ci.yml` does not use the image above. |
| 70 | +It starts only the database service from this compose file — an official image, |
| 71 | +pulled, never built — and runs `install-and-smoke.sh` directly on the runner, |
| 72 | +whose PHP `shivammathur/setup-php` already provides with `pdo_mysql` and |
| 73 | +`pdo_pgsql` prebuilt. Building the image there would spend two or three minutes |
| 74 | +per leg compiling extensions the runner hands over ready-made, on every push. |
| 75 | + |
| 76 | +The script only needs `EVO_DB_*` and a reachable server, so both paths run the |
| 77 | +same checks; the image is what makes a local run reproducible on a machine with |
| 78 | +no PHP on it, and what pins the PHP version when a version question is the one |
| 79 | +being investigated. |
| 80 | + |
| 81 | +One PHP version, every database: what the job proves is the installer's database |
| 82 | +paths, which do not vary with the PHP minor. 8.3 and 8.4 are both covered by the |
| 83 | +analysis and unit test jobs. The sqlite leg starts no container. |
| 84 | + |
| 85 | +The upgrade checks live in their own workflow, `.github/workflows/upgrade.yml`, |
| 86 | +off `push` and `pull_request` on purpose: an upgrade regression comes from a |
| 87 | +change to the migrations or the seeders, not from every commit, and each leg |
| 88 | +costs a full install plus a full update. It runs nightly, and on demand with the |
| 89 | +versions to go from and to as inputs (Actions -> Upgrade -> Run workflow): |
| 90 | +`from` takes one or more refs of any repository, `to` a ref of this one or blank |
| 91 | +for the checked out tree, which is the default - so the unreleased version is |
| 92 | +what an upgrade is tested against unless you say otherwise. |
| 93 | + |
| 94 | +## What a run asserts |
| 95 | + |
| 96 | +`install-and-smoke.sh` drives it: |
| 97 | + |
| 98 | +1. The installer creates the database itself — neither server image pre-creates |
| 99 | + the one being installed into — and runs the whole migration and seed chain. |
| 100 | +2. Nothing PHP would call a diagnostic was printed. The installer runs the |
| 101 | + migrations inside an output buffer it later discards, so the image also |
| 102 | + routes `error_log` to stderr; a warning raised during a migration cannot be |
| 103 | + swallowed. |
| 104 | +3. `smoke.php --mode=install` checks what reached the database, reading the connection the |
| 105 | + installer just wrote: every table created, the columns the core migrations |
| 106 | + add, the seeded document, template, event names, settings, roles and |
| 107 | + permissions, the admin account with a hashed password and the Administrator |
| 108 | + role, and the bundled plugins and modules. |
| 109 | +4. The updater (`--typeInstall=2`) replays the same chain over the installed |
| 110 | + site, and `smoke.php` runs again — its row counts have to match the first |
| 111 | + run, which is what catches a migration or seeder that is not idempotent. |
| 112 | +5. The site answers over HTTP: the front page renders the seeded document, and |
| 113 | + the manager renders its login form. |
| 114 | + |
| 115 | +An upgrade run asserts the same things through `smoke.php --mode=upgrade`, with |
| 116 | +the expectations that belong to a fresh install relaxed - the content and the |
| 117 | +settings are whichever ones the older site had, not the ones this installer |
| 118 | +would have chosen. Two checks replace them, and they are the point of the mode: |
| 119 | + |
| 120 | +- the counts recorded from the older site by `--mode=baseline`, taken before the |
| 121 | + copy, must not have **dropped** anywhere. A seeded catalogue may grow, because |
| 122 | + topping those up is what the update seeder is for; losing rows is a bug. |
| 123 | +- `site_content`, `users` and `user_attributes` must be **unchanged**. Those are |
| 124 | + the site, not the release, and an upgrade may not touch them. |
| 125 | + |
| 126 | +`manager_language` and `emailsender` stay exact in both modes: they are answers |
| 127 | +the operator gave the installer, and a seeder writing defaults over them would |
| 128 | +reset a live site. |
0 commit comments