Snapshot of main at 9f39a6e1e (2026-11-02)

This commit is contained in:
Ronald Huynen committed 2026-11-02 10:41:47 +01:00
commit 6ccf1792d7
2580 files changed
+1040202

No files matched your search

@@ -0,0 +1,203 @@
# Runbook: Laravel 12 preparation steps, for every installation
Laravel 12 needs a few package changes that already work on Laravel 11. They reach `main` one step at a time, and every
installation (Timebank.cc, Uuro) takes them with its normal deploy. This runbook is the checklist per step: what changes,
how to deploy it, what to check afterwards and how to go back. Background: Phase 1 of
[plans/LARAVEL_UPGRADE_PLAN.md](plans/LARAVEL_UPGRADE_PLAN.md).
| | |
|---|---|
| From | Laravel 11.57 on `main` (every installation, since the 10 to 11 upgrade) |
| To | still Laravel 11.57, with Carbon 3, flatpickr in the app, unused packages removed, PHPUnit 11, Fortify 1.41 |
| Tool | `./deploy.sh -e server`, once per step |
| Duration | a normal deploy per step, no maintenance window |
| Database | no migrations in any step |
| Rollback | code only, to the tag of the previous step (see [Rollback](#rollback)) |
Laravel 12 itself comes after all five steps, with `scripts/upgrade.sh` and a runbook of its own.
## The steps
Each step is a tag on `main`. Timebank.cc deploys a step first and watches its log for two or three days; then the next
step goes to `main`. Take the steps in order, and preferably one at a time. When your installation is several steps
behind, a deploy brings them all at once: that works, but do the checks of every step it brought.
| Tag | Step | What changes | Visible to members |
|---|---|---|---|
| `l12-prep-0-start` | starting point | `main` before the first step; the rollback target of step 1 | - |
| `l12-prep-1-carbon3` | Carbon 3 | date library 2 -> 3; durations and timestamps keep their old behaviour | no (dates must look the same) |
| `l12-prep-2-flatpickr` | flatpickr into the app | the date picker component moves into the app, package `asdh/laravel-flatpickr` removed | no |
| `l12-prep-3-cleanup` | package clean-up | unused `robsontenorio/mary` and `laradumps/laradumps` removed, `config/mary.php` deleted, `psr/simple-cache` 1 -> 3 | no |
| `l12-prep-4-phpunit` | PHPUnit 11 | test tools only (PHPUnit 11.5, Collision 8.9) | no |
| `l12-prep-5-qrcode` | QR codes, Fortify 1.41 | QR codes made by the app itself (bacon 3), `simplesoftwareio/simple-qrcode` removed, Fortify 1.21 -> 1.41 | no (QR codes look the same) |
Start every terminal session by setting the application root once (the server's own path):
```bash
export APP=/var/www/CHANGE-ME # the application root on this server
```
---
## Once: is the installation on `main`'s history?
`main` was rewritten once, after the 10 to 11 upgrade. An installation that was deployed in between sits on a commit
that is not on `main` any more, and a routine deploy would then merge two histories. Check it once, read-only:
```bash
( cd "$APP" && git fetch -q origin main \
&& echo "branch: $(git rev-parse --abbrev-ref HEAD) HEAD: $(git log -1 --format='%h %s')" \
&& if git merge-base --is-ancestor HEAD origin/main; then echo "OK: on main's history, nothing to do"; \
else echo "NOT on main's history. Code that differs from origin/main (expect nothing):"; \
git diff --stat HEAD origin/main -- app bootstrap/app.php config database lang resources routes composer.json composer.lock package.json; fi )
```
- **OK**: go on with the steps.
- **NOT on main's history** and no code differs: move the installation onto `main` without changing any code (this
changes the installation; the tag keeps the old position):
```bash
( set -e; cd "$APP"
git diff --name-only HEAD origin/main | xargs -r git -c core.fileMode=false status --porcelain -- | grep . \
&& { echo "Local changes on files that differ: stop and ask"; exit 1; } || true
git tag "pre-realign-$(date +%F)" HEAD
git -c core.fileMode=false checkout -B main origin/main
git branch -u origin/main main
git status -sb | head -1 )
```
The last line must show `## main...origin/main` without "ahead" or "behind".
- **NOT on main's history** and code differs: stop and ask; do not deploy.
---
## Every step
### 1. Before the deploy (read-only)
```bash
( cd "$APP"; git fetch -q origin main --tags
echo "now: $(git describe --tags --always HEAD)"
echo "main: $(git describe --tags --always origin/main)"
git merge-base --is-ancestor HEAD origin/main && echo "fast-forward: yes" || echo "fast-forward: NO"
echo "steps this deploy brings: $(git tag -l 'l12-prep-*' --merged origin/main --no-merged HEAD | tr '\n' ' ')"
php -v | head -1; df -h "$APP" | tail -1
echo "local changes:"; git -c core.fileMode=false status --porcelain | head )
```
- `fast-forward: yes` must be there (otherwise see the section above).
- PHP 8.2 or newer; a few hundred MB free.
- Local changes (the last lines) are the ones `deploy.sh` asks about; on a server they are usually build files.
### 2. Deploy
```bash
cd "$APP" && ./deploy.sh -e server
```
As root, the way you always deploy. It installs the changed packages with `composer install`, clears the caches and
restarts the queue workers.
### 3. Check (read-only)
```bash
( cd "$APP" && echo "now: $(git describe --tags --always HEAD)" \
&& sudo -u www-data php artisan upgrade:verify \
&& sudo -u www-data php artisan about --only=environment | head -12 )
```
- `upgrade:verify` ends without failures.
- Then the checks of the step(s) this deploy brought, below, in the browser.
### 4. The next days: watch the log (read-only)
```bash
( cd "$APP"; for d in $(seq 0 2); do f=storage/logs/laravel-$(date -d "-$d day" +%F).log; [ -f $f ] && echo "== $f: $(grep -c '\.ERROR' $f) errors" && grep '\.ERROR' $f | cut -c1-160 | sed -E 's/\[[^]]*\] //' | sort | uniq -c | sort -rn | head -5; done )
```
An error type you have not seen before the deploy deserves a look. Report it, with the step and the log lines.
---
## Checks per step
### Step 1: Carbon 3 (`l12-prep-1-carbon3`)
Carbon 3 counts differences between dates with a sign and with fractions, and reads timestamps as UTC. The code now asks
for the old behaviour everywhere; these checks confirm it.
- [ ] A post and a profile show the same date and time as before the deploy (not 1 or 2 hours off).
- [ ] Chat: "online" / "last seen" and the typing indicator behave as before.
- [ ] Log in, stay idle longer than the platform's inactivity logout: you are logged out as before.
- [ ] The next morning: no errors from the scheduled commands (inactive profiles, bounce processing, expired chat
messages) in the log.
### Step 2: flatpickr into the app (`l12-prep-2-flatpickr`)
The `<x-flatpickr>` component and its views move into the app (`app/View/Components/Flatpickr.php`,
`resources/views/flatpickr/`); the package is removed. No view that uses the picker changed.
- [ ] The date pickers open and fill in on: the transactions page (period filter), a post's start and end date in
Posts (admin), creating and editing a call, a mailing's send date (admin), the date of birth in the profile settings
and the statistics period (admin).
- [ ] A chosen date and time is saved as chosen (not shifted by the timezone).
- [ ] Only if your platform folder overrides the picker's views (`platform/views/vendor/flatpickr/`): check that your
override still applies, and tell us.
### Step 3: package clean-up (`l12-prep-3-cleanup`)
Nothing visible changes. Removed: Mary (with `config/mary.php`; nothing used it), laradumps (development only); the
`psr/simple-cache` requirement moves from 1 to 3.
- [ ] Home page, search, a profile and the chat open without errors.
- [ ] Icons look as before (they come from WireUI, not from Mary).
### Step 4: PHPUnit 11 (`l12-prep-4-phpunit`)
Test tools only. Nothing changes for visitors.
- [ ] `upgrade:verify` passes; nothing else to check.
### Step 5: QR codes and Fortify 1.41 (`l12-prep-5-qrcode`)
The QR codes are made by the app itself now (the package used before does not work with Laravel 12's Fortify). They
look the same. Fortify, the login package, goes from 1.21 to 1.41; it adds no routes or tables.
- [ ] Pay page: the QR code appears.
- [ ] A transaction and an account statement (PDF): the QR code appears and can be scanned.
- [ ] The PDF of a post (and of a call, if your platform has calls): QR code present.
- [ ] Log in and out, the password reset mail, and two-factor authentication: turning it on shows a QR code that an
authenticator app accepts, and logging in with a code works.
---
## Rollback
No step has migrations, so a rollback only puts the code back. Use it when a step breaks something for members and a fix
is not available soon. It changes the installation:
```bash
( set -e; cd "$APP"
PREV=l12-prep-CHANGE-ME # the tag of the step BEFORE the one you leave, e.g. l12-prep-1-carbon3
git fetch -q origin --tags
git -c core.fileMode=false checkout -B main "$PREV"
COMPOSER_ALLOW_SUPERUSER=1 composer install --no-interaction --prefer-dist --optimize-autoloader
php artisan optimize:clear
git log -1 --format='now: %h %s' )
```
Then restart the queue workers and Reverb the way `deploy.sh` does on your server (the `timebank-*` services), and run
the check of step 3 above.
**After a rollback, do not deploy** until the fix is on `main`: a deploy pulls `main` and brings the step back. Report
what broke; the fix comes as a new commit on `main`, and the next deploy fast-forwards as usual.
## Troubleshooting
| Symptom | Cause and fix |
|---|---|
| `Class "...MaryServiceProvider" not found` (or another removed package) right after the deploy | A stale package cache. `cd "$APP" && rm -f bootstrap/cache/packages.php bootstrap/cache/services.php && composer dump-autoload && php artisan optimize:clear` |
| `deploy.sh` stops: "main moves Laravel from 11 to 12" | Not one of these steps: Laravel 12 itself has reached `main`. Use its runbook and `scripts/upgrade.sh`. |
| `git pull` in `deploy.sh` wants to merge, or "divergent branches" | The installation is not on `main`'s history: see the first section. |
| Dates 1-2 hours off after step 1 | Report it with the page and the expected time: a `createFromTimestamp()` call without the app timezone. |
| A date picker is missing or unstyled after step 2 | `php artisan view:clear`, then reload; if it stays, report the page. |
## Record
| Step | Installation | Deployed (date) | `upgrade:verify` | Checks | Log quiet after 2-3 days |
|---|---|---|---|---|---|
| 1 Carbon 3 | | | | | |
| 2 flatpickr | | | | | |
| 3 clean-up | | | | | |
| 4 PHPUnit 11 | | | | | |
| 5 QR codes | | | | | |