DeployJob   A
last analyzed

Complexity

Total Complexity 7

Size/Duplication

Total Lines 123
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 8
Bugs 0 Features 0
Metric Value
wmc 7
eloc 80
c 8
b 0
f 0
dl 0
loc 123
ccs 0
cts 45
cp 0
rs 10

2 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
C execute() 0 95 6
1
<?php
2
3
namespace App\Queue;
4
5
use App\Action\ActivateAction;
6
use App\Action\CheckoutAction;
7
use App\Action\CleanupAction;
8
use App\Action\ClearPathsAction;
9
use App\Action\ComposerAction;
10
use App\Action\Context;
11
use App\Action\CreateWorkspaceAction;
12
use App\Action\FinaliseAction;
13
use App\Action\ScanConfigurationAction;
14
use App\Action\SharedAction;
15
use App\Action\WritablesAction;
16
use App\Builder;
17
use App\Facades\Log;
18
use App\Facades\Notifier;
19
use App\Facades\Provider;
20
use App\Facades\Settings;
21
use App\Model\Deployment;
22
use App\Model\Project;
23
use Exception;
24
use Ronanchilvers\Foundation\Config;
25
use Ronanchilvers\Foundation\Queue\Exception\FatalException;
26
use Ronanchilvers\Foundation\Queue\Job\Job;
27
use Ronanchilvers\Orm\Orm;
28
use Ronanchilvers\Utility\File;
29
use RuntimeException;
30
use Symfony\Component\Yaml\Yaml;
31
32
/**
33
 * Deploy a project
34
 *
35
 * @author Ronan Chilvers <[email protected]>
36
 */
37
class DeployJob extends Job
38
{
39
    /**
40
     * @var string
41
     */
42
    protected $queue = 'deploy';
43
44
    /**
45
     * @var \App\Model\deployment
46
     */
47
    protected $deployment;
48
49
    /**
50
     * Class constructor
51
     *
52
     * @param \App\Model\Deployment $project
53
     * @author Ronan Chilvers <[email protected]>
54
     */
55
    public function __construct(Deployment $deployment)
56
    {
57
        $this->deployment = $deployment;
58
    }
59
60
    /**
61
     * {@inheritdoc}
62
     *
63
     * @author Ronan Chilvers <[email protected]>
64
     */
65
    public function execute()
66
    {
67
        $project       = $this->deployment->project;
68
        $data          = Yaml::parseFile(__DIR__ . '/../../config/defaults.yaml');
69
        $configuration = new Config($data);
70
        $builder       = new Builder(
71
            $project,
72
            $this->deployment
73
        );
74
        $baseDir    = Settings::get('build.base_dir');
75
        $key        = $project->key;
76
        $projectDir = File::join(
77
            $baseDir,
78
            $key
79
        );
80
        $deploymentBaseDir = File::join(
81
            $projectDir,
82
            'deployments'
83
        );
84
        $deploymentDir = File::join(
85
            $deploymentBaseDir,
86
            $this->deployment->number
87
        );
88
        try {
89
            $context = new Context;
90
            $context->set('project_base_dir', $projectDir);
91
            $context->set('deployment_base_dir', $deploymentBaseDir);
92
            $context->set('deployment_dir', $deploymentDir);
93
            $provider = Provider::forProject($project);
94
            $builder->addAction(new ScanConfigurationAction($provider));
95
            $builder->addAction(new CreateWorkspaceAction);
96
            $builder->addAction(new CheckoutAction($provider));
97
            $builder->addAction(new ComposerAction);
98
            $builder->addAction(new SharedAction);
99
            $builder->addAction(new WritablesAction);
100
            $builder->addAction(new ClearPathsAction);
101
            $builder->addAction(new ActivateAction);
102
            $builder->addAction(new FinaliseAction);
103
            $builder->addAction(new CleanupAction);
104
            if (!$this->deployment->start()) {
105
                throw new RuntimeException('Unable to mark the deployment as started');
106
            }
107
            $builder->run(
108
                $configuration,
109
                $context,
110
                function($data) use ($project) {
111
                    Log::debug($data, [
112
                        'project' => $project->toArray(),
113
                    ]);
114
                }
115
            );
116
            if (!$this->deployment->finish()) {
117
                throw new RuntimeException('Unable to mark the deployment as finished');
118
            }
119
120
            Notifier::send(
121
                sprintf(
122
                    "Deployment completed for <%s|%s>\nSHA: <%s|%s>\nAuthor: %s",
123
                    $provider->getRepositoryLink($project->repository),
124
                    $project->repository,
125
                    $provider->getShaLink($project->repository, $this->deployment->sha),
126
                    $this->deployment->sha,
127
                    $this->deployment->author
128
                ),
129
                $configuration->get('notify', [])
130
            );
131
        } catch (Exception $ex) {
132
            Log::critical($ex->getMessage(), [
133
                'project'   => $project->toArray(),
134
                'deployment'   => $this->deployment->toArray(),
135
                'exception' => $ex,
136
            ]);
137
            if (!$this->deployment->fail()) {
138
                throw new RuntimeException('Unable to mark the deployment as failed');
139
            }
140
            Notifier::send(
141
                sprintf(
142
                    "Deployment failed for <%s|%s>\nSHA: <%s|%s>\nAuthor: %s",
143
                    $provider->getRepositoryLink($project->repository),
144
                    $project->repository,
145
                    $provider->getShaLink($project->repository, $this->deployment->sha),
146
                    $this->deployment->sha,
147
                    $this->deployment->author
148
                ),
149
                $configuration->get('notify', [])
150
            );
151
            throw new FatalException(
152
                $ex->getMessage(),
153
                $ex->getCode(),
154
                $ex
155
            );
156
        } finally {
157
            $project->updateFromDeployment($this->deployment);
158
            if (!$project->markActive()) {
159
                throw new RuntimeException('Unable to update project details');
160
            }
161
        }
162
    }
163
}
164