Multi-Platform Support¶
Overview¶
Sentinel CI provides a unified interface to multiple CI/CD platforms. This document compares platform capabilities, configuration, and usage patterns.
Supported Platforms¶
| Platform | Status | API Version | Auth Method | Read-Only |
|---|---|---|---|---|
| Jenkins | ✅ Full | REST | Basic Auth (user:token) | Yes |
| GitHub Actions | ✅ Full | v3 | Bearer Token | Yes |
| GitLab CI | ✅ Full | v4 | Private Token | Yes |
| Generic CI | 🚧 Planned | N/A | Configurable | Yes |
Feature Comparison¶
| Feature | Jenkins | GitHub Actions | GitLab CI | Generic CI |
|---|---|---|---|---|
| List Jobs/Workflows | ✅ | ✅ | ✅ | 🚧 |
| Build Summary | ✅ | ✅ | ✅ | 🚧 |
| Failed Stages | ✅ | ✅ | ✅ | 🚧 |
| Failed Tests | ✅ JUnit | ⚠️ Limited | ✅ Native | 🚧 |
| Log Access | ✅ Full | ✅ Full | ✅ Full | 🚧 |
| Pipeline Visualization | ✅ Blue Ocean | ✅ Workflow Graph | ✅ Pipeline Graph | 🚧 |
| Artifact Access | ✅ | ✅ | ✅ | 🚧 |
| Branch/Tag Filtering | ✅ | ✅ | ✅ | 🚧 |
| Parallel Jobs | ✅ | ✅ | ✅ | 🚧 |
| Cache Support | ✅ | ✅ | ✅ | ✅ |
Legend: - ✅ Full support - ⚠️ Partial support or requires additional setup - 🚧 Planned/In development - ❌ Not supported
Platform-Specific Configuration¶
Jenkins¶
Requirements: - Jenkins 2.x or higher - Installed plugins: wfapi (for Pipeline), junit (for tests) - API token (user:token format)
Configuration:
# .env
CI_PLATFORM=jenkins
JENKINS_URL=https://jenkins.example.com
JENKINS_TOKEN=username:api_token_here
Features:
- Classic and Pipeline job support
- Blue Ocean integration
- JUnit test result parsing
- Console log access
- Folder support (/job/folder/job/name)
API Endpoints:
# List all jobs
GET /api/json?tree=jobs[name,url,color,lastBuild[number,result]]
# Get build details
GET /job/{name}/{build}/api/json
# Get pipeline stages (wfapi plugin)
GET /job/{name}/{build}/wfapi/describe
# Get test results
GET /job/{name}/{build}/testReport/api/json
# Get console log
GET /job/{name}/{build}/consoleText
Status Mapping:
{
'blue': 'SUCCESS',
'red': 'FAILURE',
'yellow': 'UNSTABLE',
'aborted': 'ABORTED',
'notbuilt': 'NOT_BUILT',
'blue_anime': 'IN_PROGRESS',
'red_anime': 'IN_PROGRESS',
}
Example:
from mcps.jenkins.client import JenkinsClient
client = JenkinsClient(
base_url="https://jenkins.example.com",
token="user:token"
)
# List all jobs
jobs = client.list_jobs()
# Get specific build
build = client.get_build_summary("backend-service", "123")
# Get failed tests
tests = client.get_failed_tests("backend-service", "123")
GitHub Actions¶
Requirements:
- GitHub repository with Actions enabled
- Personal Access Token (PAT) or GitHub App
- Permissions: actions:read, contents:read
Configuration:
# .env
CI_PLATFORM=github-actions
GITHUB_TOKEN=ghp_xxxxxxxxxxxxxxxxxxxx
GITHUB_OWNER=your-org
GITHUB_REPO=your-repo
Features: - Workflow runs - Job and step details - Log downloads - Artifact access - Check run integration
API Endpoints:
# List workflow runs
GET /repos/{owner}/{repo}/actions/runs
# Get run details
GET /repos/{owner}/{repo}/actions/runs/{run_id}
# Get jobs for a run
GET /repos/{owner}/{repo}/actions/runs/{run_id}/jobs
# Download logs
GET /repos/{owner}/{repo}/actions/runs/{run_id}/logs
Status Mapping:
{
'completed': 'SUCCESS' or 'FAILURE',
'in_progress': 'IN_PROGRESS',
'queued': 'PENDING',
'cancelled': 'ABORTED',
}
Example:
from mcps.github_actions.client import GitHubActionsClient
client = GitHubActionsClient(
token="ghp_token",
owner="your-org",
repo="your-repo"
)
# List workflow runs
runs = client.list_jobs()
# Get specific run
run = client.get_build_summary("workflow-name", "run-id")
# Get failed steps
steps = client.get_failed_stages("workflow-name", "run-id")
Limitations: - Test reporting requires GitHub Checks API or third-party actions - Logs must be downloaded as ZIP and extracted - Rate limits: 5,000 requests/hour for authenticated requests
GitLab CI¶
Requirements:
- GitLab instance (self-hosted or GitLab.com)
- Personal Access Token or Project Access Token
- Permissions: read_api
Configuration:
# .env
CI_PLATFORM=gitlab-ci
GITLAB_URL=https://gitlab.com # or self-hosted URL
GITLAB_TOKEN=glpat-xxxxxxxxxxxxxxxxxxxx
GITLAB_PROJECT_ID=12345 # or "group/project"
Features: - Pipeline jobs - Stage details - Native test report support - MR pipeline tracking - Job artifacts - Trace (log) streaming
API Endpoints:
# List pipelines
GET /api/v4/projects/{id}/pipelines
# Get pipeline details
GET /api/v4/projects/{id}/pipelines/{pipeline_id}
# Get pipeline jobs
GET /api/v4/projects/{id}/pipelines/{pipeline_id}/jobs
# Get test report
GET /api/v4/projects/{id}/pipelines/{pipeline_id}/test_report
# Get job trace
GET /api/v4/projects/{id}/jobs/{job_id}/trace
Status Mapping:
{
'created': 'PENDING',
'pending': 'PENDING',
'running': 'IN_PROGRESS',
'success': 'SUCCESS',
'failed': 'FAILURE',
'canceled': 'ABORTED',
'skipped': 'SKIPPED',
'manual': 'MANUAL',
}
Example:
from mcps.gitlab_ci.client import GitLabCIClient
client = GitLabCIClient(
base_url="https://gitlab.com",
token="glpat-token",
project_id="12345"
)
# List pipelines
pipelines = client.list_jobs()
# Get specific pipeline
pipeline = client.get_build_summary("pipeline-name", "pipeline-id")
# Get test report
tests = client.get_failed_tests("pipeline-name", "pipeline-id")
Advantages: - Built-in test report support (JUnit XML, JSON) - Rich pipeline graph visualization - MR integration - Self-hosted option
Platform Selection Guide¶
Choose Jenkins if:¶
- ✅ You have complex build pipelines
- ✅ You need extensive plugin ecosystem
- ✅ You're using Groovy-based Jenkinsfiles
- ✅ You have on-premise infrastructure
- ✅ You need fine-grained access control
Choose GitHub Actions if:¶
- ✅ Your code is on GitHub
- ✅ You want tight Git integration
- ✅ You prefer YAML-based workflows
- ✅ You want marketplace actions
- ✅ You're okay with cloud-hosted runners
Choose GitLab CI if:¶
- ✅ Your code is on GitLab
- ✅ You want native test reporting
- ✅ You prefer
.gitlab-ci.ymlformat - ✅ You need built-in security scanning
- ✅ You want GitOps integration
Choose Generic CI if:¶
- ✅ You're using CircleCI, Travis, Bamboo, etc.
- ✅ You need custom integration
- ✅ Your platform has a REST API
- ✅ You want to define your own mappings
Migration Between Platforms¶
Jenkins → GitHub Actions¶
Configuration changes:
# Before (Jenkins)
CI_PLATFORM=jenkins
JENKINS_URL=https://jenkins.example.com
JENKINS_TOKEN=user:token
# After (GitHub Actions)
CI_PLATFORM=github-actions
GITHUB_TOKEN=ghp_token
GITHUB_OWNER=your-org
GITHUB_REPO=your-repo
Code changes:
- Job names: job/name → workflow-name
- Build IDs: 123 → run-id
- No changes to tool calls (same API)
GitLab CI → Jenkins¶
# Before (GitLab)
CI_PLATFORM=gitlab-ci
GITLAB_URL=https://gitlab.com
GITLAB_TOKEN=glpat-token
GITLAB_PROJECT_ID=12345
# After (Jenkins)
CI_PLATFORM=jenkins
JENKINS_URL=https://jenkins.example.com
JENKINS_TOKEN=user:token
Considerations: - GitLab pipeline IDs are numeric - Jenkins build numbers are also numeric - Test reporting format may differ
Multi-Platform Usage¶
Running Multiple Platforms Simultaneously¶
Option 1: Multiple instances
# Terminal 1: Jenkins
export CI_PLATFORM=jenkins
export JENKINS_URL=https://jenkins.example.com
export JENKINS_TOKEN=user:token
python -m sentinel_ci.server
# Terminal 2: GitHub Actions
export CI_PLATFORM=github-actions
export GITHUB_TOKEN=ghp_token
export GITHUB_OWNER=your-org
export GITHUB_REPO=your-repo
python -m sentinel_ci.server --port 8001
Option 2: Docker Compose
version: '3'
services:
sentinel-jenkins:
image: sentinel-ci:latest
environment:
- CI_PLATFORM=jenkins
- JENKINS_URL=${JENKINS_URL}
- JENKINS_TOKEN=${JENKINS_TOKEN}
ports:
- "8000:8000"
sentinel-github:
image: sentinel-ci:latest
environment:
- CI_PLATFORM=github-actions
- GITHUB_TOKEN=${GITHUB_TOKEN}
- GITHUB_OWNER=${GITHUB_OWNER}
- GITHUB_REPO=${GITHUB_REPO}
ports:
- "8001:8000"
Aggregating Data Across Platforms¶
Example: Compare build times
import asyncio
from mcps.jenkins.client import JenkinsClient
from mcps.github_actions.client import GitHubActionsClient
async def compare_platforms():
jenkins_client = JenkinsClient(...)
github_client = GitHubActionsClient(...)
jenkins_builds = jenkins_client.list_jobs()
github_runs = github_client.list_jobs()
# Compare average duration
jenkins_avg = sum(b['duration'] for b in jenkins_builds) / len(jenkins_builds)
github_avg = sum(r['duration'] for r in github_runs) / len(github_runs)
print(f"Jenkins avg: {jenkins_avg}s")
print(f"GitHub avg: {github_avg}s")
Platform-Specific Tips¶
Jenkins¶
Performance optimization:
# Use depth parameter to limit tree depth
GET /api/json?tree=jobs[name,lastBuild[number,result]]&depth=1
# Filter by job type
GET /api/json?tree=jobs[name]&filter=org.jenkinsci.plugins.workflow.job.WorkflowJob
Handling folders:
# Jobs in folders use slash notation
job_name = "folder/subfolder/job-name"
build = client.get_build_summary(job_name, "123")
GitHub Actions¶
Rate limiting:
# Check rate limit status
import requests
response = requests.get(
'https://api.github.com/rate_limit',
headers={'Authorization': f'Bearer {token}'}
)
print(response.json())
Using GitHub App:
# Better rate limits with GitHub App
from github import Github
g = Github(app_id, private_key)
installation = g.get_app().get_installation(installation_id)
token = installation.get_access_token().token
GitLab CI¶
Using project ID vs path:
Self-hosted GitLab:
# Include API version
GITLAB_URL=https://gitlab.mycompany.com
# API calls will use: https://gitlab.mycompany.com/api/v4/...
Troubleshooting¶
Jenkins Issues¶
Problem: "Authentication failed"
# Verify token format
echo $JENKINS_TOKEN # Should be: username:token
# Test manually
curl -u username:token https://jenkins.example.com/api/json
Problem: "wfapi plugin not found"
GitHub Actions Issues¶
Problem: "Rate limit exceeded"
# Check current limit
curl -H "Authorization: Bearer $GITHUB_TOKEN" \
https://api.github.com/rate_limit
# Solution: Use GitHub App or wait for reset
Problem: "Resource not accessible by integration"
GitLab CI Issues¶
Problem: "404 Project not found"
# Verify project ID
curl -H "PRIVATE-TOKEN: $GITLAB_TOKEN" \
https://gitlab.com/api/v4/projects/12345
# Or use URL-encoded path
curl -H "PRIVATE-TOKEN: $GITLAB_TOKEN" \
"https://gitlab.com/api/v4/projects/group%2Fproject"
Future Platform Support¶
Planned:¶
- 🚧 CircleCI
- 🚧 Travis CI
- 🚧 Bamboo
- 🚧 TeamCity
- 🚧 Azure DevOps
- 🚧 Drone CI
- 🚧 Buildkite
Generic CI Adapter¶
For unsupported platforms, use the Generic CI adapter:
# generic-ci-config.yaml
platform: circleci
base_url: https://circleci.com/api/v2
auth:
type: bearer
token: ${CIRCLECI_TOKEN}
endpoints:
list_jobs: /project/{project}/pipeline
build_details: /project/{project}/pipeline/{id}
logs: /project/{project}/job/{job_id}/logs
mappings:
status:
success: SUCCESS
failed: FAILURE
running: IN_PROGRESS
Contributing¶
See CONTRIBUTING.md for how to add support for a new platform.
Quick checklist:
1. Create mcps/<platform>/client.py
2. Implement AbstractCIClient interface
3. Add configuration to .env.example
4. Write tests in tests/test_<platform>.py
5. Update this documentation
6. Add example to examples/