1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
|
/**
* config check
*/
// GitLab 服务器地址
if (!config('myflex.gitlab.origin')) {
$this->info('gitlab origin is not set');
return;
}
// 项目或用户访问令牌
if (!config('myflex.gitlab.token')) {
$this->info('gitlab token is not set');
return;
}
// 项目ID
if (!config('myflex.gitlab.fe_id')) {
$this->info('gitlab project id is not set');
return;
}
/**
* 根据不同环境拉取不同的打包结果
*/
$jobName = 'job_build_unknown';
switch (config('app.env')) {
case 'production':
$jobName = 'job_build_prod';
break;
case 'development':
case 'local':
$jobName = 'job_build_stage';
break;
default:
break;
}
// GitLab 客户端
$client = new \Gitlab\Client();
$client->setUrl(config('myflex.gitlab.origin'));
$client->authenticate(config('myflex.gitlab.token'), \Gitlab\Client::AUTH_HTTP_TOKEN);
/**
* @var \Gitlab\Api\Jobs
*/
$jobs = $client->jobs();
$job = collect($client->jobs()->all(config('myflex.gitlab.fe_id'), ['scope' => 'success']))
->where('name', $jobName)
->where('tag', true)
->filter(function ($item) use ($jobName) {
if ($jobName == 'job_build_prod') {
// 正式
return preg_match('{^v?(\d{1,5})(\.\d++)?(\.\d++)?(\.\d++)?(-\d+)?$}i', strtolower($item['ref']));
} else if ($jobName == 'job_build_stage') {
// 测试
return preg_match('{^v?(\d{1,5})(\.\d++)?(\.\d++)?(\.\d++)?(-stage\.\d+)$}i', strtolower($item['ref']));
} else {
return false;
}
})
->first();
if (!$job) {
$this->info('gitlab job not exist');
return;
}
$this->info("gitlab sync fe with {$jobName}:{$job['ref']}");
/**
* 下载文件
*/
$artifacts = $jobs->artifactsByRefName(
config('myflex.gitlab.fe_id'),
$job['ref'],
$jobName
);
$curRef = $job['ref'];
$refPath = implode(DIRECTORY_SEPARATOR, ['gitlab', '.ref',]);
// 定位目录,检查是否有必要拉取文件
/** @var \Illuminate\Filesystem\FilesystemAdapter */
$storage = static::getStorage();
if ($storage->exists($refPath)) {
$prevRef = trim($storage->get($refPath));
if ($prevRef == $curRef) {
$this->info('gitlab remote ref not change');
return;
}
}
// 创建下载文件名
$file = implode(DIRECTORY_SEPARATOR, ['gitlab', $curRef . '.zip']);
if ($storage->exists($file)) {
$storage->delete($file);
}
$storage->put($file, $artifacts);
/**
* 解压文件
*/
$dest = implode(DIRECTORY_SEPARATOR, [
dirname($file), $curRef
]);
$zip = new \ZipArchive();
$zip->open($storage->path($file));
$zip->extractTo($storage->path($dest));
$zip->close();
flush();
/**
* 复制文件
*/
$prefix = implode(DIRECTORY_SEPARATOR, [
'gitlab', $curRef, 'dist',
]) . DIRECTORY_SEPARATOR;
collect($storage->files($dest, true))
->each(function ($file) use ($storage, $prefix) {
$file = str_replace('/', DIRECTORY_SEPARATOR, $file);
/**
* 跳过 php 和 favicon.con 文件
*/
if (Str::endsWith($file, '.php') || Str::endsWith($file, 'favicon.ico')) {
return;
}
/**
* 根据环境选择文件
*/
if (!Str::startsWith($file, $prefix)) {
return;
}
$from = $storage->path($file);
$to = public_path(str_replace($prefix, '', $file));
if (!file_exists(dirname($to))) {
mkdir(dirname($to), 0777, true);
}
copy($from, $to);
});
$storage->put($refPath, $curRef);
$storage->deleteDirectory($dest);
|