190 lines
6.7 KiB
PHP
190 lines
6.7 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Admin;
|
|
|
|
use App\Clients\JenkinsClient;
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\Project;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Validation\Rule;
|
|
|
|
class JenkinsBuildController extends Controller
|
|
{
|
|
public function __construct(
|
|
private readonly JenkinsClient $jenkinsClient
|
|
) {}
|
|
|
|
public function projects(): JsonResponse
|
|
{
|
|
if (! $this->jenkinsClient->isConfigured()) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'Jenkins 未配置,请先配置 JENKINS_HOST、JENKINS_USERNAME、JENKINS_API_TOKEN',
|
|
], 422);
|
|
}
|
|
|
|
$projects = Project::getJenkinsNotifyEnabled()
|
|
->map(function (Project $project) {
|
|
return [
|
|
'id' => $project->id,
|
|
'slug' => $project->slug,
|
|
'name' => $project->name,
|
|
'jenkins_job_name' => $project->jenkins_job_name,
|
|
'parameters' => $this->jenkinsClient->getParameterDefinitions($project->jenkins_job_name),
|
|
];
|
|
})
|
|
->values();
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'data' => [
|
|
'projects' => $projects,
|
|
],
|
|
]);
|
|
}
|
|
|
|
public function trigger(Request $request): JsonResponse
|
|
{
|
|
if (! $this->jenkinsClient->isConfigured()) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'Jenkins 未配置,请先配置 Jenkins 连接信息',
|
|
], 422);
|
|
}
|
|
|
|
$projectSlugs = Project::getJenkinsNotifyEnabled()->pluck('slug')->all();
|
|
|
|
$data = $request->validate([
|
|
'builds' => ['required', 'array', 'min:1'],
|
|
'builds.*.project_slug' => ['required', 'string', Rule::in($projectSlugs)],
|
|
'builds.*.parameters' => ['nullable', 'array'],
|
|
]);
|
|
|
|
$projects = Project::getJenkinsNotifyEnabled()->keyBy('slug');
|
|
$results = [];
|
|
$successCount = 0;
|
|
|
|
foreach ($data['builds'] as $build) {
|
|
/** @var Project $project */
|
|
$project = $projects[$build['project_slug']];
|
|
$parameters = $this->normalizeParameters($build['parameters'] ?? []);
|
|
$result = $this->jenkinsClient->triggerBuild($project->jenkins_job_name, $parameters);
|
|
|
|
if ($result['success'] ?? false) {
|
|
$successCount++;
|
|
}
|
|
|
|
$results[] = [
|
|
'project_slug' => $project->slug,
|
|
'project_name' => $project->name,
|
|
'job_name' => $project->jenkins_job_name,
|
|
'success' => (bool) ($result['success'] ?? false),
|
|
'message' => $result['message'] ?? null,
|
|
'queue_url' => $result['queue_url'] ?? null,
|
|
'build_number' => $result['build_number'] ?? null,
|
|
];
|
|
}
|
|
|
|
return response()->json([
|
|
'success' => $successCount === count($results),
|
|
'message' => sprintf('触发完成:成功 %d 个,失败 %d 个', $successCount, count($results) - $successCount),
|
|
'data' => [
|
|
'results' => $results,
|
|
],
|
|
], $successCount > 0 ? 200 : 422);
|
|
}
|
|
|
|
public function statuses(Request $request): JsonResponse
|
|
{
|
|
if (! $this->jenkinsClient->isConfigured()) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'Jenkins 未配置,请先配置 Jenkins 连接信息',
|
|
], 422);
|
|
}
|
|
|
|
$projectSlugs = Project::getJenkinsNotifyEnabled()->pluck('slug')->all();
|
|
$data = $request->validate([
|
|
'builds' => ['required', 'array', 'min:1'],
|
|
'builds.*.id' => ['required', 'string'],
|
|
'builds.*.project_slug' => ['required', 'string', Rule::in($projectSlugs)],
|
|
'builds.*.queue_url' => ['nullable', 'string'],
|
|
'builds.*.build_number' => ['nullable', 'integer'],
|
|
]);
|
|
|
|
$projects = Project::getJenkinsNotifyEnabled()->keyBy('slug');
|
|
$results = [];
|
|
|
|
foreach ($data['builds'] as $build) {
|
|
/** @var Project $project */
|
|
$project = $projects[$build['project_slug']];
|
|
|
|
$results[] = [
|
|
'id' => $build['id'],
|
|
'project_slug' => $project->slug,
|
|
'job_name' => $project->jenkins_job_name,
|
|
...$this->jenkinsClient->getBuildStatus(
|
|
$project->jenkins_job_name,
|
|
$build['queue_url'] ?? null,
|
|
isset($build['build_number']) ? (int) $build['build_number'] : null
|
|
),
|
|
];
|
|
}
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'data' => [
|
|
'results' => $results,
|
|
],
|
|
]);
|
|
}
|
|
|
|
public function cancel(Request $request): JsonResponse
|
|
{
|
|
if (! $this->jenkinsClient->isConfigured()) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'Jenkins 未配置,请先配置 Jenkins 连接信息',
|
|
], 422);
|
|
}
|
|
|
|
$projectSlugs = Project::getJenkinsNotifyEnabled()->pluck('slug')->all();
|
|
$data = $request->validate([
|
|
'project_slug' => ['required', 'string', Rule::in($projectSlugs)],
|
|
'queue_url' => ['nullable', 'string'],
|
|
'build_number' => ['nullable', 'integer'],
|
|
]);
|
|
|
|
$project = Project::getJenkinsNotifyEnabled()->firstWhere('slug', $data['project_slug']);
|
|
$result = $this->jenkinsClient->cancelBuild(
|
|
$project->jenkins_job_name,
|
|
$data['queue_url'] ?? null,
|
|
isset($data['build_number']) ? (int) $data['build_number'] : null
|
|
);
|
|
|
|
return response()->json([
|
|
'success' => (bool) ($result['success'] ?? false),
|
|
'message' => ($result['success'] ?? false) ? '已发送取消请求' : ($result['message'] ?? '取消失败'),
|
|
'data' => [
|
|
'result' => $result,
|
|
],
|
|
], ($result['success'] ?? false) ? 200 : 422);
|
|
}
|
|
|
|
private function normalizeParameters(array $parameters): array
|
|
{
|
|
return collect($parameters)
|
|
->filter(fn ($value) => $value !== null && $value !== '')
|
|
->map(function ($value) {
|
|
if (is_array($value)) {
|
|
return implode(',', array_filter($value, fn ($item) => $item !== null && $item !== ''));
|
|
}
|
|
|
|
return is_bool($value) ? ($value ? 'true' : 'false') : $value;
|
|
})
|
|
->filter(fn ($value) => $value !== '')
|
|
->all();
|
|
}
|
|
}
|