Skip to content

Releasing and deploying ​

A MelaCMS site is built in GitHub Actions and copied to the server over SSH. The server needs only PHP 8.4 and SSH: no Composer, no Node and no build step. That is why a classic shared host is enough.

The workflow files ​

The installer copies four files into the site. From then on they belong to the site and can be changed freely. mela:update asks before taking a new version of one (see Updating the core).

FileRuns onDoes
.github/workflows/ci.ymlPush to development, pull requestsPint check, agent instructions check, asset build, php artisan test
.github/workflows/release.ymlPush to masterCI, then the release PR, then the deploy when a release is created
.github/workflows/deploy.ymlCalled by the release, or by handBuilds the site and copies it to the server over SSH
.github/dependabot.ymlDailyA pull request for a new MelaCMS version

The flow ​

  1. Work on development with conventional commits: feat: ..., fix: ..., feat!: ... for a breaking change.
  2. Merge development into master and push.
  3. release-please opens a release PR with the next version and the CHANGELOG.md entry.
  4. Merge the release PR. This creates the tag and the GitHub Release, and deploys that tag.

So a release takes two merges. Merging development into master only opens the release PR and deploys nothing.

The commit type decides the version. feat: raises the minor version and fix: raises the patch. docs:, chore: and the other types make no release, so nothing is deployed. Never edit CHANGELOG.md by hand.

One-time setup on GitHub ​

  • Create the development and master branches.
  • Under Settings → Actions → General → Workflow permissions, enable Allow GitHub Actions to create and approve pull requests.
  • Commit package-lock.json. The workflows install with npm ci, which needs it.
  • Set the variables and secrets listed at the top of .github/workflows/deploy.yml: DEPLOY_PATH, SSH_HOST, SSH_USER, SSH_KEY and MAINTENANCE_TOKEN.
  • When php on the server's command line is older than 8.4, which is common on shared hosting, also set the PHP_BIN variable to the 8.4 binary, for example php8.4.

One-time setup on the server ​

  • PHP 8.4 on the command line, with the extensions listed under Requirements. Check with php -v and php -m over SSH: the command-line PHP can differ from the one serving the site.
  • The web root points to public/ inside DEPLOY_PATH.
  • A .env in DEPLOY_PATH with APP_KEY, APP_URL and the database. The deploy never copies or changes it.

What a deploy does ​

  1. Builds the site in GitHub Actions: Composer without the development packages, and the Vite assets.
  2. Copies the result to DEPLOY_PATH over SSH.
  3. On the server: checks the PHP version, removes the cached config, routes and events of the previous release, puts the site in maintenance mode, runs the migrations, makes the public/storage link, builds the caches and brings the site back up.

The script stops at the first error, so a failed migration leaves the site in maintenance mode.

The first super-admin on the server ​

The deploy runs the migrations and creates no account, so after the first deploy nobody can log in yet. Run this once, over SSH, in the app directory on the server:

bash
php artisan mela:super-admin

It creates the three roles if they are missing, then asks for an email, a name and a password. If the email belongs to an existing user, that user keeps their name and password and gains the role. So the same command also restores access to a site that has lost its last super-admin. The other users are then created in the panel.

Deploying again ​

  • After a failed deploy, fix the cause, then use Re-run failed jobs on the workflow run, or gh run rerun <run id> --failed. The variables and secrets are read again.
  • To deploy any tag or branch, use Actions → Deploy → Run workflow.

Troubleshooting ​

ProblemCauseFix
The deploy stops with "'php' on the server is PHP 8.3..."The command-line php is older than 8.4Set the PHP_BIN variable, then run the failed deploy again
The copy step ends with dial tcp ...:22: i/o timeoutThe server did not answer in time. Nothing was copiedRun the failed deploy again
development was merged into master and nothing was deployedThat merge only opens the release PRMerge the release PR
Nobody can log in on a freshly deployed siteThe deploy creates no accountphp artisan mela:super-admin over SSH
Dependabot's update fails with dependency_file_not_resolvableNo PHP version pin in composer.jsonThe pin, committed

Known limits ​

  • The deploy copies over the live directory. It is not atomic, and files removed from the repository stay on the server.
  • There is no rollback step.
  • A host without SSH is not supported.

A site that is not deployed through GitHub Actions can delete the deploy job and deploy.yml. Versions and the changelog keep working without them.

Code released under the MIT License. The MelaCMS name and logo are trademarks, see Brand.