summaryrefslogtreecommitdiff
path: root/servers/gitlab_glab/src/mcp_server_gitlab_glab/server.py
diff options
context:
space:
mode:
authorDawid Rycerz <dawid@rycerz.xyz>2025-05-28 15:44:40 +0200
committerDawid Rycerz <dawid@rycerz.xyz>2025-05-28 15:44:40 +0200
commit54b521f19e00bea52304f7379ca59de0c2e20962 (patch)
treed28ecbe7dbd59a5d400f52cd7345ed0f5ec66476 /servers/gitlab_glab/src/mcp_server_gitlab_glab/server.py
parent0b819edceb307ce2f8ba6d58b37a86329b7d6ec0 (diff)
feat(gitlab_glab): add CI pipeline functionality with glab ci run
- Add new run_ci_pipeline method to GitLabServer class - Support all glab ci run options including variables, branch, and web mode - Auto-detect current branch using git branch --show-current when -b is missing - Implement web mode that overrides CI_PIPELINE_SOURCE=web - Add comprehensive test coverage with 9 new test cases - Update README.md with complete documentation and usage examples - Maintain 95% test coverage and pass all 53 tests - Follow project standards with proper error handling and type hints Closes: Add CI job runner functionality as requested
Diffstat (limited to 'servers/gitlab_glab/src/mcp_server_gitlab_glab/server.py')
-rw-r--r--servers/gitlab_glab/src/mcp_server_gitlab_glab/server.py144
1 files changed, 144 insertions, 0 deletions
diff --git a/servers/gitlab_glab/src/mcp_server_gitlab_glab/server.py b/servers/gitlab_glab/src/mcp_server_gitlab_glab/server.py
index 881228f..b661255 100644
--- a/servers/gitlab_glab/src/mcp_server_gitlab_glab/server.py
+++ b/servers/gitlab_glab/src/mcp_server_gitlab_glab/server.py
@@ -402,7 +402,115 @@ class GitLabServer:
"temp_file_path": None
}
+ def run_ci_pipeline(
+ self,
+ working_directory: str,
+ branch: str | None = None,
+ variables: list[str] | None = None,
+ variables_env: list[str] | None = None,
+ variables_file: list[str] | None = None,
+ variables_from: str | None = None,
+ web_mode: bool = False,
+ repo: str | None = None,
+ ) -> dict[str, Any]:
+ """Run a CI/CD pipeline on GitLab.
+ Args:
+ working_directory: The directory to execute the command in.
+ branch: Create pipeline on branch/ref. If None, uses current branch.
+ variables: Pass variables to pipeline in format key:value.
+ variables_env: Pass environment variables to pipeline in format key:value.
+ variables_file: Pass file contents as file variables in format key:filename.
+ variables_from: JSON file containing variables for pipeline execution.
+ web_mode: Run pipeline in web mode (overrides CI_PIPELINE_SOURCE to 'web').
+ repo: Select another repository (OWNER/REPO or GROUP/NAMESPACE/REPO format).
+
+ Returns:
+ A dictionary containing the pipeline information or an error message.
+ """
+ # Build command arguments
+ args = ["ci", "run"]
+
+ # Handle branch - if not provided, get current branch
+ if branch is None:
+ try:
+ # Get current branch using git command
+ result = subprocess.run(
+ ["git", "branch", "--show-current"],
+ capture_output=True,
+ text=True,
+ check=False,
+ cwd=working_directory,
+ )
+ if result.returncode == 0 and result.stdout.strip():
+ branch = result.stdout.strip()
+ logger.info(f"Using current branch: {branch}")
+ else:
+ logger.warning(
+ "Could not determine current branch, proceeding without -b flag"
+ )
+ except Exception as e:
+ logger.warning(f"Could not determine current branch: {str(e)}")
+
+ # Add branch if available
+ if branch:
+ args.extend(["-b", branch])
+
+ # Add variables
+ if variables:
+ for var in variables:
+ args.extend(["--variables", var])
+
+ # Add environment variables
+ if variables_env:
+ for var in variables_env:
+ args.extend(["--variables-env", var])
+
+ # Add file variables
+ if variables_file:
+ for var in variables_file:
+ args.extend(["--variables-file", var])
+
+ # Add variables from file
+ if variables_from:
+ args.extend(["-f", variables_from])
+
+ # Add web mode - override CI_PIPELINE_SOURCE to 'web'
+ if web_mode:
+ args.extend(["--variables-env", "CI_PIPELINE_SOURCE:web"])
+
+ # Add repo
+ if repo:
+ args.extend(["-R", repo])
+
+ # Execute the command
+ success, result = self.execute_glab_command(args, working_directory)
+
+ if not success:
+ return result
+
+ # Parse the output to extract pipeline information
+ # The output typically contains pipeline URL and ID
+ output_lines = result.strip().split('\n') if isinstance(result, str) else []
+
+ pipeline_info = {
+ "success": True,
+ "output": result,
+ "branch": branch,
+ "web_mode": web_mode
+ }
+
+ # Try to extract pipeline URL if present
+ for line in output_lines:
+ if "https://" in line and "/pipelines/" in line:
+ # Extract just the URL from the line
+ import re
+ url_match = re.search(r'https://[^\s]+/pipelines/\d+', line)
+ if url_match:
+ pipeline_info["pipeline_url"] = url_match.group(0)
+ break
+
+ return pipeline_info
def create_server(host: str = "127.0.0.1", port: int = 8080) -> FastMCP:
"""Create and configure the FastMCP server.
@@ -581,6 +689,42 @@ def create_server(host: str = "127.0.0.1", port: int = 8080) -> FastMCP:
max_size_kb=max_size_kb,
)
+ @mcp.tool()
+ def run_ci_pipeline(
+ working_directory: str,
+ branch: str | None = None,
+ variables: list[str] | None = None,
+ variables_env: list[str] | None = None,
+ variables_file: list[str] | None = None,
+ variables_from: str | None = None,
+ web_mode: bool = False,
+ repo: str | None = None,
+ ) -> dict[str, Any]:
+ """Run a CI/CD pipeline on GitLab.
+
+ Args:
+ working_directory: The directory to execute the command in.
+ branch: Create pipeline on branch/ref. If None, uses current branch.
+ variables: Pass variables to pipeline in format key:value.
+ variables_env: Pass environment variables to pipeline in format key:value.
+ variables_file: Pass file contents as file variables in format key:filename.
+ variables_from: JSON file containing variables for pipeline execution.
+ web_mode: Run pipeline in web mode (overrides CI_PIPELINE_SOURCE to 'web').
+ repo: Select another repository (OWNER/REPO or GROUP/NAMESPACE/REPO format).
+
+ Returns:
+ A dictionary containing the pipeline information or an error message.
+ """
+ return gitlab.run_ci_pipeline(
+ working_directory=working_directory,
+ branch=branch,
+ variables=variables,
+ variables_env=variables_env,
+ variables_file=variables_file,
+ variables_from=variables_from,
+ web_mode=web_mode,
+ repo=repo,
+ )
return mcp