GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( 7a4b4e...76463e )
by Sam
02:56
created

BuildController::pushImage()   B

Complexity

Conditions 3
Paths 2

Size

Total Lines 24
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 3.0175

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 24
ccs 14
cts 16
cp 0.875
rs 8.9713
cc 3
eloc 15
nc 2
nop 1
crap 3.0175
1
<?php
2
declare(strict_types=1);
3
4
namespace SamIT\Yii2\PhpFpm\controllers;
5
6
7
use Docker\API\Model\AuthConfig;
8
use Docker\API\Model\BuildInfo;
9
use Docker\API\Model\PushImageInfo;
10
use Docker\Docker;
11
use Docker\Stream\BuildStream;
12
use Docker\Stream\PushStream;
13
use Psr\Http\Message\ResponseInterface;
14
use SamIT\Yii2\PhpFpm\Module;
15
use yii\base\InvalidConfigException;
16
use yii\console\Controller;
17
use yii\helpers\Console;
18
19
/**
20
 * Class BuildController
21
 * @package SamIT\Yii2\PhpFpm\controllers
22
 * @property Module $module
23
 */
24
class BuildController extends Controller
25
{
26
    public $defaultAction = 'build';
27
28
    /**
29
     * @var string The name of the created image
30
     * If not explicitly set will take its default from module config.
31
     */
32
    public $image;
33
34
    /**
35
     * @var string The tag of the created image
36
     * If not explicitly set will take its default from module config.
37
     */
38
    public $tag;
39
40
    /**
41
     * @var bool whether to push the image after a successful build.
42
     * If not explicitly set will take its default from module config.
43
     */
44
    public $push;
45
46
    /**
47
     * @var Docker
48
     */
49
    protected $docker;
50
51
    /**
52
     * @var string the user to authenticate against the repository
53
     */
54
    public $user;
55
56
    /**
57
     * @var string the password to authenticate against the repository
58
     */
59
    public $password;
60
61 3
    public function init(): void
62
    {
63 3
        parent::init();
64 3
        $this->docker = Docker::create();
65 3
        $this->push = $this->module->push;
66 3
        $this->image = $this->module->image;
67 3
        $this->tag = $this->module->tag;
68 3
    }
69
70 2
    public function actionBuild(): void
71
    {
72 2
        if ($this->push && !isset($this->image, $this->user, $this->password)) {
73 1
            throw new InvalidConfigException("When using the push option, you must configure or provide user, password and image");
74
        }
75
76 1
        $params = [];
77
78
79 1
        if (isset($this->image)) {
80 1
            $name = "{$this->image}:{$this->tag}";
81 1
            $params['t'] = $name;
82
        }
83 1
        $buildStream = $this->createBuildStream($params);
84 1
        $this->color = true;
85 1
        $buildStream->onFrame(\Closure::fromCallable([$this, 'logBuildInfo']));
86 1
        $buildStream->wait();
87 1
        $this->stdout("Wait finished\n");
88 1
        $buildStream->wait();
89
90 1
        if ($this->push && isset($name)) {
91 1
            $this->pushImage($name);
92
        }
93
    }
94
95 1
    private function logBuildInfo(BuildInfo $buildInfo): void
96
    {
97 1
        $this->stdout($buildInfo->getStream(), Console::FG_CYAN);
98 1
        $this->stdout($buildInfo->getProgress(), Console::FG_YELLOW);
99 1
        $this->stdout($buildInfo->getStatus(), Console::FG_RED);
100 1
        if (!empty($buildInfo->getProgressDetail())) {
101
            $this->stdout($buildInfo->getProgressDetail()->getMessage(), Console::FG_YELLOW);
102
        }
103 1
        if (!empty($buildInfo->getErrorDetail())) {
104
            $this->stdout($buildInfo->getErrorDetail()->getCode() . ':' . $buildInfo->getErrorDetail()->getMessage(), Console::FG_YELLOW);
105
        }
106 1
        if (!empty($buildInfo->getError())) {
107
            throw new \Exception($buildInfo->getError() . ':' . $buildInfo->getErrorDetail()->getMessage());
108
        }
109 1
    }
110
111
    /**
112
     * Push a docker container image
113
     * @param string $name
114
     * @throws \Exception
115
     */
116 1
    private function pushImage(string $name): void
117
    {
118 1
        $authConfig = new AuthConfig();
119 1
        $authConfig->setUsername($this->user);
120 1
        $authConfig->setPassword($this->password);
121
        $params = [
122 1
            'X-Registry-Auth' => $authConfig
123
        ];
124
        /** @var PushStream $pushStream */
125 1
        $pushStream = $this->docker->imagePush($name, [], $params ?? [],  Docker::FETCH_OBJECT);
126
127 1
        if ($pushStream instanceof ResponseInterface) {
128
            throw new \Exception($pushStream->getReasonPhrase() . ':' . $pushStream->getBody()->getContents(), $pushStream->getStatusCode());
129
        }
130
131 1
        $pushStream->onFrame(function(PushImageInfo $pushImageInfo): void {
132 1
            if (!empty($pushImageInfo->getError())) {
133 1
                throw new \Exception($pushImageInfo->getError());
134
            }
135 1
            $this->stdout($pushImageInfo->getProgress(), Console::FG_YELLOW);
136 1
            $this->stdout($pushImageInfo->getStatus(), Console::FG_RED);
137 1
        });
138 1
        $pushStream->wait();
139
    }
140
141
    public function actionTestClient(): void
142
    {
143
        $this->stdout("It seems the console client works!\n", Console::FG_GREEN);
144
    }
145
146 2
    public function createBuildStream(array $params = []): BuildStream
147
    {
148
149 2
        $context = $this->module->createBuildContext();
150 2
        return $this->docker->imageBuild($context->toStream(), $params, [], Docker::FETCH_OBJECT);
151
    }
152
153 1
    public function options($actionID)
154
    {
155
156 1
        $result = parent::options($actionID);
157
        switch ($actionID) {
158 1
            case 'build':
159 1
                $result[] = 'push';
160 1
                $result[] = 'image';
161 1
                $result[] = 'tag';
162 1
                $result[] = 'user';
163 1
                $result[] = 'password';
164 1
                break;
165
166
        }
167 1
        return $result;
168
    }
169
170
    public function optionAliases()
171
    {
172
        $result = parent::optionAliases();
173
        $result['p'] = 'push';
174
        $result['t'] = 'tag';
175
        $result['i'] = 'image';
176
        $result['u'] = 'user';
177
        $result['P'] = 'password';
178
        return $result;
179
    }
180
181 1 View Code Duplication
    public function stdout($string)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
182
    {
183 1
        if ($this->isColorEnabled()) {
184 1
            $args = \func_get_args();
185 1
            \array_shift($args);
186 1
            $string = Console::ansiFormat($string, $args);
187
        }
188
189 1
        echo $string;
190 1
        return \strlen($string);
191
    }
192
193
194
}