Skip to content

Latest commit

 

History

History
189 lines (140 loc) · 5.9 KB

PLUGIN_HOWTO.rst

File metadata and controls

189 lines (140 loc) · 5.9 KB

Maintenance Mode Plugin

First we need to prepare directory structure and create all files:

* Deploy
  * Maintenance
    * DependencyInjection
      * Configuration.php
      * DeployMaintenanceExtension.php
    * Resources
      * config
        * services.php
    * Deploy.php

Lets start with DeployMaintenanceExtension.php. It's task is to validate configuration and load services definition.

<?php
namespace Deploy\Maintenance\DependencyInjection;

use Symfony\Component\Config\Definition\Processor;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Extension\ExtensionInterface;
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;

class DeployMaintenanceExtension implements ExtensionInterface
{

    public function getAlias()
    {
        return 'deploy_maintenance';
    }

    public function load(array $configs, ContainerBuilder $container)
    {
        $configuration = new Configuration();
        $processor = new Processor();
        $config = $processor->processConfiguration($configuration, $configs);

        $loader = new PhpFileLoader(
            $container,
            new FileLocator(__DIR__.'/../Resources/config')
        );
        $loader->load('services.php');

        foreach($config as $key => $val) {
            $container->setParameter($this->getAlias() . '.' . $key, $val);
        }
    }

    public function getNamespace()
    {
        return false;
    }

    public function getXsdValidationBasePath()
    {
        return false;
    }
}

For configuration validation it uses class Configuration which in case of this plugin checks that only "template_file" and "target_file" options are specified.

<?php
namespace Deploy\Maintenance\DependencyInjection;

use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;

class Configuration implements ConfigurationInterface
{
    public function getConfigTreeBuilder()
    {
        $treeBuilder = new TreeBuilder();
        $rootNode = $treeBuilder->root('deploy_maintenance');

        $rootNode
            ->children()
                ->scalarNode('template_file')->isRequired()->end()
                ->scalarNode('target_file')->isRequired()->end()
            ->end();

        return $treeBuilder;
    }
}

Next we can write a definition for service which this plugin will provide. This definition belongs to services.php. We use parameters which we defined in class Configuration and pass it to service's constructor. This plugin needs to do something only before and after deploy so let's subscribe to PRE_DEPLOY and POST_DEPLOY events.

<?php
use Deploy\Core\Event\DeployEvents;
use Symfony\Component\DependencyInjection\DefinitionDecorator;

$container->setParameter('deploy_maintenance.class', 'Deploy\Maintenance\Deploy');

$container
    ->setDefinition('deploy_maintenance', new DefinitionDecorator('deploy_plugin'))
    ->setClass('%deploy_maintenance.class%')
    ->addArgument('%deploy_maintenance.template_file%')
    ->addArgument('%deploy_maintenance.target_file%')
    ->addTag('deploy.event_listener', array('event' => DeployEvents::PRE_DEPLOY))
    ->addTag('deploy.event_listener', array('event' => DeployEvents::POST_DEPLOY));

/** @var  LoggerInterface */
protected $logger;

/** @var  Utils */
protected $utils;

/** @var  string absolute path */
protected $deploy_path;

Now we can create very simple service just to test this out. Lets edit Deploy.php file. We can use logger, utils and read deploy_path because our class inherits from DeployBase class and our service from deploy_plugin service.

<?php
namespace Deploy\Maintenance;

use Deploy\Core\Event\DeployEvent;
use Deploy\DeployBase;

class Deploy extends DeployBase
{
    private $template_file;
    private $target_file;

    public function __construct($template_file, $target_file)
    {
        $this->template_file = $template_file;
        $this->target_file = $target_file;
    }

    public function onPreDeployEvent(DeployEvent $event)
    {
        $this->logger->debug("Maintenance::PreDeploy");

        $this->logger->alert("Copy {$this->template_file} to {$this->target_file}.");
    }

    public function onPreDeployEventUndo(DeployEvent $event)
    {
        $this->logger->debug("Maintenance::PreDeploy undo");

        $this->logger->alert("Remove {$this->target_file}.");
    }

    public function onPostDeployEvent(DeployEvent $event)
    {
        $this->logger->debug("Maintenance::PostDeploy");

        $this->logger->alert("Remove {$this->target_file}.");
    }
}

Last thing we need is to enable this plugin in config/plugins.php, so just create a new instance and configure it in config/config.php.

<?php
// plugins.php
return array(
    ...,
    new \Deploy\Maintenance\DependencyInjection\DeployMaintenanceExtension()
);

// config.php
return array(
    ...,
    'deploy_maintenance' => array(
        'template_file' => 'web/maintenance.html',
        'target_file' => 'web/index.html'
    )
);

Now if you try to deploy with ./run deploy you will see alerts logged from Maintenance plugin. You can take a look at the final Deploy.php implementation.