Deployer: Versioning framework recipes

Created on 7 Apr 2017  Â·  11Comments  Â·  Source: deployphp/deployer

| Q | A
| ----------------- | ---
| Issue Type | Discussion
| Deployer Version | 5

Description

I think the default recipes are very nice, but sometimes I'm a bit worried about versioning. What if Laravel 5.5 adds a new command that should be added by default, will it be included in laravel.php? And will that break my existing L5.4 deployment? Or do we never add it, or create laravel5.5.php? Imho, the deployment should almost never change after we set it up, unless we explicitly do so. This includes changes in shared folders, commands to run and possibly even flags (see Laravel 4 -> 5 added the --force flag to migrations).
This of course applies to all frameworks/apps.

Solution?

The init commands currently adds an initial recipe, extending recipe/laravel.php (in this example). But perhaps it would be better to also include all the deploy tasks, so it is more clear what you are running, and it won't change with an upgrade of deployer.

2 possible solutions:

  • Split the task definitions and the deploy definition, to just include the deploy definition (and perhaps the shared/writable defaults) in the init

    • Copy the entire recipe to the initialised deploy script, perhaps after what is current in the init file. More verbose but won't break. Downside it that it's not easy to patch issues.

research

Most helpful comment

Or get the output from php artisan --version

All 11 comments

I don't like copy pasting entire recipe, the cool thing is easy updates and bug fixes. What about adding versioning?
For example there are already some: drupal 7/8, symfony 2/3, yii/??
Maybe lets create subdir for frameworks what requires more when one version?

  • recipe/laravel/5.4.php
  • recipe/laravel/5.5.php

And what about creating function for simple require? Like this:

use('laravel', '5.4');
use('symfony', '3.x');
use('yii-app-advanced', '2.x');

And what about this:

require 'recipe/symfony/3.php';
require 'npm.php';

I think version bump is probably only needed when big things change, like different command names/syntax. So hard to tell when exactly, but would probably be good to create a new version when needed then (eg. when 5.6 is breaking some command, create a 5.6 recipe, whichs extend the base laravel one).

What do you think about copying just the deploy part and the default directores? Eg. this

// Laravel shared dirs
set('shared_dirs', [
    'storage',
]);
// Laravel shared file
set('shared_files', [
    '.env',
]);
// Laravel writable dirs
set('writable_dirs', [
    'bootstrap/cache',
    'storage',
    'storage/app',
    'storage/app/public',
    'storage/framework',
    'storage/framework/cache',
    'storage/framework/sessions',
    'storage/framework/views',
    'storage/logs',
]);

/**
 * Main task
 */
desc('Deploy your project');
task('deploy', [
    'deploy:prepare',
    'deploy:lock',
    'deploy:release',
    'deploy:update_code',
    'deploy:shared',
    'deploy:vendors',
    'deploy:writable',
    'artisan:storage:link',
    'artisan:view:clear',
    'artisan:cache:clear',
    'artisan:config:cache',
    'artisan:optimize',
    'deploy:symlink',
    'deploy:unlock',
    'cleanup',
]);

What's possible to do, bat i like to keep project deploy.php file as minimal as possible. One of Deployer features is:

Ready to use recipes for most frameworks

I like to keep it in mind. It's always possible to do by your self. But for good default, i think minimalizm is prefered. (Alos take a look at new Symfony 4 – only one composer.json file required.)

Creating separate recipes only for major changes will make deployer look outdated. Assume last major change was in Laravel 5.1 and now we have Laravel 5.5 withour major changes. Loading laravel-5.1.php for laravel 5.5 will look confusing at best.

I would suggest having latest version as default, but include conditional fixes for older versions. Something like:

```
define('LARAVEL_LATEST', 5.5);

....

task('deploy', [
'deploy', [
'deploy:prepare',
'deploy:lock',
'deploy:release',
'deploy:update_code',
'deploy:shared',
'deploy:vendors',
'deploy:writable',

version_compare(5.5, LARAVEL_VERSION', '>=') ? null : 'task:for -last',
version_compare(5.5, LARAVEL_VERSION', '<') ? null : 'task:for -old',

'deploy:writable',
'artisan:storage:link',
'artisan:view:clear',
'artisan:cache:clear',
'artisan:config:cache',
'artisan:optimize',
'deploy:symlink',
'deploy:unlock',
'cleanup',

]); ```

It would bake recipes less pretty, but it would be transparent to end users.

Why laravel doesn't follow semver and add bc in minor releases?
For example for sumfony there is two recipes: 2 and 3.

What about adding to recipe config like framework_version?

Or get the output from php artisan --version

@barryvdh take a look at this: https://github.com/deployphp/deployer/pull/1246

We have this same issue with Magento2. With Magento 2.2 there are new and improved CLI commands for building and deploying the application. So we need to have a different approach to earlier versions (2.0 and 2.1). I think (at some point) every application will have differences, some within minor versions, some in major versions (for instance Magento1 and Magento2).

Maybe it would be possible to add a third optional parameter to the task indicating an application constraint:

task('name:name', function() { /*...*/ }, version('appname', 'constraint'));

The version() function could accept the application to which the constraint applies ('laravel', 'magento2', '...') and a version constraint, for instance like '2.2', '>=5.5', '>=7 <8'. The version() function would create some object (VersionConstraint or something like that) which will evaluate if the task should be ran or not / which will be called by the task to evaluate if it should run or not run.

The current version could/should be set at the top of any application's recipe:

setVersion('laravel', function() { /*... artisan --version ... */ });
setVersion('magento2', function() { /*... bin/magento --version ... */ });

I'm thinking of using set('version', '...'); options.
But default, each framework recipe stay synchronized with latest version, and if you need to downgrade you set version option.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

minkbear picture minkbear  Â·  4Comments

osbulbul picture osbulbul  Â·  3Comments

jolipixel picture jolipixel  Â·  4Comments

JonasDoebertin picture JonasDoebertin  Â·  4Comments

brunodevel picture brunodevel  Â·  3Comments