3
3
namespace SymfonyDocsBuilder \Command ;
4
4
5
5
use Symfony \Component \Console \Command \Command ;
6
+ use Symfony \Component \Console \Exception \RuntimeException ;
6
7
use Symfony \Component \Console \Input \InputArgument ;
7
8
use Symfony \Component \Console \Input \InputInterface ;
8
9
use Symfony \Component \Console \Output \OutputInterface ;
9
10
use Symfony \Component \Console \Style \SymfonyStyle ;
10
11
use Symfony \Component \HttpClient \Exception \ClientException ;
11
12
use Symfony \Component \HttpClient \HttpClient ;
13
+ use Symfony \Component \Process \Exception \ProcessFailedException ;
12
14
use Symfony \Component \Process \Process ;
15
+ use Symfony \Contracts \HttpClient \HttpClientInterface ;
13
16
14
17
class GithubReleaseCommand extends Command
15
18
{
16
19
protected static $ defaultName = 'github:release ' ;
17
20
18
21
/** @var SymfonyStyle */
19
22
private $ io ;
23
+ /** @var HttpClientInterface */
24
+ private $ client ;
25
+
26
+ private $ tag ;
27
+ private $ name ;
28
+ private $ description ;
20
29
21
30
public function __construct ()
22
31
{
@@ -28,21 +37,44 @@ protected function configure()
28
37
$ this ->setDescription ('Create a release on github with a .phar as attachment. ' );
29
38
// todo valid with regex
30
39
$ this ->addArgument ('tag ' , InputArgument::REQUIRED , 'Release \'s tag. ' );
31
- $ this ->addArgument ('name ' , InputArgument::REQUIRED , 'Release name ' );
32
- $ this ->addArgument ('description ' , InputArgument::REQUIRED , 'Release description ' );
40
+ $ this ->addArgument ('name ' , InputArgument::OPTIONAL , 'Release name ' , ' Symfony docs builder %s ' );
41
+ $ this ->addArgument ('description ' , InputArgument::OPTIONAL , 'Symfony docs builder %s ' );
33
42
}
34
43
35
44
protected function initialize (InputInterface $ input , OutputInterface $ output )
36
45
{
37
46
$ this ->io = new SymfonyStyle ($ input , $ output );
47
+ $ this ->client = $ this ->createHttpClient ();
48
+
49
+ $ tag = $ input ->getArgument ('tag ' );
50
+ if (!preg_match ('/v\d+\.\d+\.\d+/ ' , $ tag )) {
51
+ throw new RuntimeException (sprintf ('"%s" is not a valid tag. ' , $ tag ));
52
+ }
53
+
54
+ $ this ->tag = $ tag ;
55
+ $ this ->name = sprintf ($ input ->getArgument ('name ' ), $ tag );
56
+ $ this ->description = sprintf ($ input ->getArgument ('description ' ), $ tag );
38
57
}
39
58
40
59
protected function execute (InputInterface $ input , OutputInterface $ output )
60
+ {
61
+ $ this ->compilePhar ();
62
+
63
+ $ this ->addAssetToRelease ($ this ->createRelease ());
64
+ }
65
+
66
+ /**
67
+ * @throws ProcessFailedException
68
+ */
69
+ private function compilePhar (): void
41
70
{
42
71
$ process = Process::fromShellCommandline ('./bin/compile ' , __DIR__ .'/../.. ' );
43
72
$ process ->mustRun ();
73
+ }
44
74
45
- // TODO token form .env
75
+ private function createHttpClient (): HttpClientInterface
76
+ {
77
+ // TODO token form .env
46
78
$ client = HttpClient::create (
47
79
[
48
80
'headers ' => [
@@ -51,25 +83,60 @@ protected function execute(InputInterface $input, OutputInterface $output)
51
83
]
52
84
);
53
85
86
+ return $ client ;
87
+ }
88
+
89
+ private function createRelease (): int
90
+ {
54
91
try {
55
- $ client ->request (
92
+ $ response = $ this -> client ->request (
56
93
'POST ' ,
94
+ // todo change repo
57
95
'https://api.github.com/repos/nikophil/test/releases ' ,
58
96
[
59
97
'json ' => [
60
- 'tag_name ' => $ input -> getArgument ( ' tag ' ) ,
98
+ 'tag_name ' => $ this -> tag ,
61
99
'target_commitish ' => 'master ' ,
62
- 'name ' => $ input ->getArgument ('name ' ),
63
- 'body ' => $ input ->getArgument ('description ' ),
64
- 'draft ' => false ,
65
- 'prerelease ' => false
66
- ]
100
+ 'name ' => $ this ->name ,
101
+ 'description ' => $ this ->description ,
102
+ 'draft ' => false ,
103
+ 'prerelease ' => false ,
104
+ ],
105
+ ]
106
+ );
107
+
108
+ return (int ) $ response ->toArray ()['id ' ];
109
+ } catch (ClientException $ exception ) {
110
+ throw new RuntimeException ('Error while trying to create release. Maybe the tag name already exists? ' , 0 , $ exception );
111
+ }
112
+ }
113
+
114
+ private function addAssetToRelease (int $ releaseId ): void
115
+ {
116
+ try {
117
+ $ this ->client ->request (
118
+ 'POST ' ,
119
+ sprintf ('https://uploads.github.com/repos/nikophil/test/releases/%s/assets?name=docs.phar ' , $ releaseId ),
120
+ [
121
+ 'headers ' => ['Content-Type ' => 'application/octet-stream ' ],
122
+ 'body ' => file_get_contents (__DIR__ .'/../../docs.phar ' ),
67
123
]
68
124
);
69
125
} catch (ClientException $ exception ) {
70
- $ this ->io ->error ('Error while trying to create release. Maybe the tag name already exists? ' );
126
+ $ this ->deleteRelease ($ releaseId );
127
+ throw new RuntimeException ('Error while adding asset to release. Maybe the tag name already exists? ' , 0 , $ exception );
128
+ }
129
+ }
71
130
72
- return ;
131
+ private function deleteRelease (int $ releaseId ): void
132
+ {
133
+ try {
134
+ $ this ->client ->request (
135
+ 'DELETE ' ,
136
+ sprintf ('https://api.github.com/repos/nikophil/test/releases/%s ' , $ releaseId )
137
+ );
138
+ } catch (ClientException $ exception ) {
139
+ throw new RuntimeException ('Error while deleting release. ' , 0 , $ exception );
73
140
}
74
141
}
75
142
}
0 commit comments