diff options
| author | Dawid Rycerz <dawid@rycerz.xyz> | 2025-05-28 15:44:40 +0200 |
|---|---|---|
| committer | Dawid Rycerz <dawid@rycerz.xyz> | 2025-05-28 15:44:40 +0200 |
| commit | 54b521f19e00bea52304f7379ca59de0c2e20962 (patch) | |
| tree | d28ecbe7dbd59a5d400f52cd7345ed0f5ec66476 /servers/gitlab_glab/src/mcp_server_gitlab_glab | |
| parent | 0b819edceb307ce2f8ba6d58b37a86329b7d6ec0 (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')
| -rw-r--r-- | servers/gitlab_glab/src/mcp_server_gitlab_glab/server.py | 144 |
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 |
