Skip to main content
Glama
wqhui
by wqhui
gitlab.ts6.59 kB
import axios, { AxiosInstance } from 'axios'; import { logger } from '../utils/logger.js'; export interface PipelineVariable { [key: string]: string; } export interface Pipeline { id: number; status: string; ref: string; sha: string; web_url: string; created_at: string; updated_at: string; source: string; } export interface Job { id: number; name: string; status: string; stage: string; created_at: string; started_at?: string; finished_at?: string; web_url: string; } export interface ListPipelinesOptions { ref?: string; status?: string; per_page?: number; page?: number; } export class GitLabService { private createAxiosInstance(gitlabUrl: string, token: string): AxiosInstance { return axios.create({ baseURL: `${gitlabUrl}/api/v4`, headers: { 'Private-Token': token, 'Content-Type': 'application/json', }, timeout: 30000, }); } /** * 触发GitLab流水线 */ async triggerPipeline( gitlabUrl: string, projectId: string, ref: string, token: string, variables?: PipelineVariable ): Promise<Pipeline> { try { const api = this.createAxiosInstance(gitlabUrl, token); const data: any = { ref }; if (variables && Object.keys(variables).length > 0) { data.variables = Object.entries(variables).map(([key, value]) => ({ key, value, })); } logger.info(`触发流水线: ${projectId}@${ref}`); const response = await api.post(`/projects/${encodeURIComponent(projectId)}/pipeline`, data); logger.info(`流水线触发成功: ${response.data.id}`); return response.data; } catch (error) { logger.error('触发流水线失败:', error); if (axios.isAxiosError(error)) { throw new Error(`GitLab API 错误: ${error.response?.status} - ${error.response?.data?.message || error.message}`); } throw error; } } /** * 获取流水线状态 */ async getPipelineStatus( gitlabUrl: string, projectId: string, pipelineId: string, token: string ): Promise<Pipeline> { try { const api = this.createAxiosInstance(gitlabUrl, token); logger.info(`获取流水线状态: ${pipelineId}`); const response = await api.get(`/projects/${encodeURIComponent(projectId)}/pipelines/${pipelineId}`); return response.data; } catch (error) { logger.error('获取流水线状态失败:', error); if (axios.isAxiosError(error)) { throw new Error(`GitLab API 错误: ${error.response?.status} - ${error.response?.data?.message || error.message}`); } throw error; } } /** * 列出项目的流水线 */ async listPipelines( gitlabUrl: string, projectId: string, token: string, options: ListPipelinesOptions = {} ): Promise<Pipeline[]> { try { const api = this.createAxiosInstance(gitlabUrl, token); logger.info(`获取项目流水线列表: ${projectId}`); const params: any = { per_page: options.per_page || 20, page: options.page || 1, }; if (options.ref) params.ref = options.ref; if (options.status) params.status = options.status; const response = await api.get(`/projects/${encodeURIComponent(projectId)}/pipelines`, { params }); return response.data; } catch (error) { logger.error('获取流水线列表失败:', error); if (axios.isAxiosError(error)) { throw new Error(`GitLab API 错误: ${error.response?.status} - ${error.response?.data?.message || error.message}`); } throw error; } } /** * 获取流水线的作业列表 */ async getPipelineJobs( gitlabUrl: string, projectId: string, pipelineId: string, token: string ): Promise<Job[]> { try { const api = this.createAxiosInstance(gitlabUrl, token); logger.info(`获取流水线作业: ${pipelineId}`); const response = await api.get(`/projects/${encodeURIComponent(projectId)}/pipelines/${pipelineId}/jobs`); return response.data; } catch (error) { logger.error('获取流水线作业失败:', error); if (axios.isAxiosError(error)) { throw new Error(`GitLab API 错误: ${error.response?.status} - ${error.response?.data?.message || error.message}`); } throw error; } } /** * 取消流水线 */ async cancelPipeline( gitlabUrl: string, projectId: string, pipelineId: string, token: string ): Promise<Pipeline> { try { const api = this.createAxiosInstance(gitlabUrl, token); logger.info(`取消流水线: ${pipelineId}`); const response = await api.post(`/projects/${encodeURIComponent(projectId)}/pipelines/${pipelineId}/cancel`); return response.data; } catch (error) { logger.error('取消流水线失败:', error); if (axios.isAxiosError(error)) { throw new Error(`GitLab API 错误: ${error.response?.status} - ${error.response?.data?.message || error.message}`); } throw error; } } /** * 重试流水线 */ async retryPipeline( gitlabUrl: string, projectId: string, pipelineId: string, token: string ): Promise<Pipeline> { try { const api = this.createAxiosInstance(gitlabUrl, token); logger.info(`重试流水线: ${pipelineId}`); const response = await api.post(`/projects/${encodeURIComponent(projectId)}/pipelines/${pipelineId}/retry`); return response.data; } catch (error) { logger.error('重试流水线失败:', error); if (axios.isAxiosError(error)) { throw new Error(`GitLab API 错误: ${error.response?.status} - ${error.response?.data?.message || error.message}`); } throw error; } } /** * 获取作业日志 */ async getJobLog( gitlabUrl: string, projectId: string, jobId: string, token: string ): Promise<string> { try { const api = this.createAxiosInstance(gitlabUrl, token); logger.info(`获取作业日志: ${jobId}`); const response = await api.get(`/projects/${encodeURIComponent(projectId)}/jobs/${jobId}/trace`); return response.data; } catch (error) { logger.error('获取作业日志失败:', error); if (axios.isAxiosError(error)) { throw new Error(`GitLab API 错误: ${error.response?.status} - ${error.response?.data?.message || error.message}`); } throw error; } } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/wqhui/mcp-gitlab'

If you have feedback or need assistance with the MCP directory API, please join our Discord server