Files
ephub/deploy.php
T
2026-09-17 18:41:07 +02:00

167 lines
5.3 KiB
PHP

<?php
namespace Deployer;
require 'contrib/cachetool.php';
require 'contrib/rsync.php';
require 'recipe/symfony.php';
/*
* ephub deploys by rsync: everything is built on the developer's machine and shipped, so no
* composer or npm ever runs on the server. That is why vendor/ and assets/vendor/ are NOT in the
* exclude list below even though both are gitignored -- rsync does not read .gitignore, and the
* server needs both.
*
* Assets are AssetMapper, not Encore, so there is no build bundle to upload. Instead:
* 1. `npm run tailwind:build` (local) writes assets/styles/app.css, which is a build artifact
* and gitignored -- without this step AssetMapper would version a stale or missing
* stylesheet;
* 2. `importmap:install` (local) makes sure assets/vendor/ is populated before rsync;
* 3. `asset-map:compile` (server) writes public/assets/ with the versioned filenames and
* the importmap manifest.
*
* Step 3 runs on the server rather than locally so it uses the deployed vendor/ and the prod
* environment. public/assets/ is therefore excluded from rsync: shipping a local copy would only
* put a stale build in place for the moment between rsync and compile.
*/
add('shared_dirs', [
'var/log',
'var/sessions',
]);
add('shared_files', [
// Kept out of the release and symlinked, so server-side rules survive a deploy. It is in the
// rsync excludes for the same reason.
'public/.htaccess',
]);
set('keep_releases', 3);
// Rsync options, mainly files/dirs to exclude
$rsyncOptions = [
'exclude' => [
'.claude',
'.cursor',
'.idea',
'.vscode',
'.DS_Store',
'.ddev',
'.git',
'.github',
'.jj',
'node_modules',
'.editorconfig',
'.env.dev',
'.env.dev.local',
'.env.dev.local.php',
'.env.test',
'.env.test.local',
'.gitignore',
'.nvmrc',
// Tooling this project does not carry yet, but both sibling projects do.
'.php-cs-fixer.cache',
'.php-cs-fixer.dist.php',
'.phpunit.cache',
'.phpunit.result.cache',
'phpunit.dist.xml',
'phpunit.xml',
'CLAUDE.md',
'deploy.php',
// The Tailwind toolchain is a build-time concern only: the compiled stylesheet ships as
// assets/styles/app.css, the sources and the CLI config do not.
'package.json',
'package-lock.json',
'tailwind.config.js',
'tailwind/',
// Written on the server by asset-map:compile.
'public/assets/',
'tests/',
'var/',
],
'exclude-file' => false,
'include' => [],
'include-file' => false,
'filter' => [],
'filter-file' => false,
'filter-perdir' => false,
'flags' => 'rz',
'options' => ['delete', 'copy-links', 'chmod=D755,F664'],
'timeout' => 300,
];
host('prod')
->setHostname('dedi10193.your-server.de')
->setRemoteUser('ephubsf')
->setForwardAgent(true)
->setSshMultiplexing(true)
->setDeployPath('/usr/home/ephubsf/public_html/prod')
->set('bin/php', '/usr/bin/php')
->set('http_user', 'ephubsf')
->set('rsync_src', __DIR__)
->set('rsync', $rsyncOptions)
->set('cachetool_args', '--web=SymfonyHttpClient --web-path={{current_path}}/public/ --web-url=https://hub.ep-reisen.de')
;
host('staging')
->setHostname('www198.your-server.de')
->setRemoteUser('pfqasy')
->setForwardAgent(true)
->setSshMultiplexing(true)
->setDeployPath('/usr/home/pfqasy/public_html/ephub.fromme.dev')
->set('bin/php', '/usr/bin/php')
->set('http_user', 'pfqasy')
->set('rsync_src', __DIR__)
->set('rsync', $rsyncOptions)
->set('cachetool_args', '--web=SymfonyHttpClient --web-path={{current_path}}/public/ --web-url=https://ephub.fromme.dev')
->add('shared_files', [
'public/.htpasswd',
])
;
task('deploy', [
'deploy:info',
'deploy:setup',
'deploy:lock',
'deploy:release',
'deploy:assets',
'rsync',
'deploy:shared',
'deploy:writable',
'deploy:cache:clear',
'deploy:assetmap',
'database:migrate',
'cachetool:clear:opcache',
'deploy:publish',
'deploy:stop-workers',
]);
/**
* Local build step. Produces the two things rsync has to carry that git does not:
* the compiled Tailwind stylesheet and the downloaded importmap vendor files.
*/
task('deploy:assets', function () {
runLocally('ddev exec npm ci');
// Writes assets/styles/app.css -- must happen before asset-map:compile, or the stylesheet
// that gets versioned is whatever was lying around.
runLocally('ddev exec npm run tailwind:build');
// assets/vendor/ is gitignored, so make sure it is actually there before it is shipped.
runLocally('ddev exec php bin/console importmap:install');
})->once();
/**
* Server build step: versioned filenames and the importmap manifest under public/assets/.
*
* Runs after deploy:cache:clear so it works against a clean cache, and before deploy:publish so
* the symlink only ever flips to a release whose assets are already in place.
*/
task('deploy:assetmap', function () {
run('{{bin/console}} asset-map:compile --no-interaction');
});
task('deploy:stop-workers', function () {
run('{{bin/console}} messenger:stop-workers');
});
after('deploy:failed', 'deploy:unlock');