Development¶
Everything runs in Docker. The host needs Docker, git and jq; php and shellcheck are only for
the test and lint commands below.
On macOS, the bin/smoke suites need GNU tools, because they use sed -i, stat -c,
find -printf and date -d. Run brew install bash coreutils findutils gnu-sed, then put
Homebrew's GNU tools first on PATH:
PATH="$(brew --prefix)/opt/coreutils/libexec/gnubin:$(brew --prefix)/opt/findutils/libexec/gnubin:$(brew --prefix)/opt/gnu-sed/libexec/gnubin:$PATH".
The other bin/ scripts run on macOS as they are.
The local stack¶
bin/dev up # the base image on http://localhost:8300
INSTITUTION=demo bin/dev up # an institution, built on the local base
bin/dev up builds the images and starts the app, cron, a MySQL container and Mailpit. The first start
installs Moodle. Log in as admin with Dev-Admin-1.
Mail the dev site sends lands in Mailpit, on http://localhost:8325 (MAILPIT_PORT).
Anything else after bin/dev goes to Docker Compose:
bin/dev logs -f app
bin/dev exec app php /app/moodle/admin/cli/purge_caches.php
bin/dev down # stop; add -v to also delete the site's database and files
The dev stack is the repo's root compose.yml, so plain docker compose … at the root works
on it, as bin/dev <args> does. Copy .env.example to .env to change its ports or settings.
The host's compose file is host/compose.yml.
Editing code¶
- Internal plugins (
plugins/) are mounted into the running container, so an edit shows on the next page load. A new language string needs a cache purge; a version bump runs its upgrade on the nextbin/dev up. - Harness files (
docker/,Dockerfile) are baked into the image. Runbin/dev upagain: it rebuilds from cache in seconds and restarts. - Moodle core and third-party plugins come from Composer, inside the image. Change them through
an institution's
composer.json(Institutions and plugins).
Inside the image, Moodle lives in /app/moodle: its command-line scripts are in
/app/moodle/admin/cli, and the web root and plugins are in /app/moodle/public.
Checks¶
| Command | Checks | Time |
|---|---|---|
php tests/settings_test.php |
the settings renderer: validation, ${VAR}, the rendered PHP, the command's exit codes |
under a second |
bin/smoke [<institution>] |
the install suite: builds the images, installs a fresh site from host/compose.yml, then checks /up, the login page, cron, and that every locked plugin installed. Tears it all down after |
about 2 minutes |
bin/smoke env |
runs the base image with Mailpit and Redis, and checks mail on local and development, curl on local and production, SMTP locking, and Redis sessions surviving a restart |
about 3 minutes |
bin/smoke backup [<institution>] |
backs up a seeded site (default demo), checks every refusal, restores it |
about 5 minutes |
bin/smoke upgrade |
walks one site through install, upgrades, a failed backup, the escape hatch, the app's own check and a rollback | about 4 minutes |
bin/smoke all [<institution>] |
the four in turn, stopping at the first failure | about 17 minutes |
bin/check-lock |
every institution pins the same Moodle core as the base | instant |
shellcheck -x docker/sis-entrypoint docker/sis-cron bin/* dbtools/sis-* tests/*.sh tests/smoke/*.sh |
the shell scripts, as lint runs it | instant |
bash tests/dbtools_test.sh |
the backup tools' helpers and preupgrade's refusals, against a stub mysql |
a few seconds |
Run bin/smoke before every release. Every suite takes SMOKE_PORT (each has its own default,
so suites can run side by side), SMOKE_TIMEOUT and SMOKE_KEEP=1 (leave the site running and
print how to stop it; not with all). install also takes SMOKE_ENV (extra .env lines) and
SMOKE_IMAGE (an app image to use instead of building). The suites live in tests/smoke/ and
share tests/smoke/lib.sh. Pull requests run only the lint checks in CI; tests and smoke runs
stay local.
Layout of the harness¶
| File | Does |
|---|---|
docker/sis-entrypoint |
the container's start: settings, database wait, install or upgrade, serve |
docker/sis-cron |
the cron container's loop |
docker/sis-settings.php, sis-settings-lib.php |
renders locked settings, applies defaults |
docker/sis-db.php |
tells the entrypoint whether the database is reachable, and empty, installed or half-installed |
docker/config.php |
Moodle's config: reads .env, then the rendered locked settings |
docker/Caddyfile, php.ini |
the web server and PHP settings |