tracehub-mcp 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- tracehub_mcp-0.2.0/.cz.toml +18 -0
- tracehub_mcp-0.2.0/.dockerignore +56 -0
- tracehub_mcp-0.2.0/.env.example +43 -0
- tracehub_mcp-0.2.0/.github/dependabot.yml +30 -0
- tracehub_mcp-0.2.0/.github/workflows/ci.yml +154 -0
- tracehub_mcp-0.2.0/.github/workflows/release.yml +109 -0
- tracehub_mcp-0.2.0/.github/workflows/security.yml +126 -0
- tracehub_mcp-0.2.0/.gitignore +211 -0
- tracehub_mcp-0.2.0/.python-version +1 -0
- tracehub_mcp-0.2.0/CHANGELOG.md +42 -0
- tracehub_mcp-0.2.0/CLAUDE.md +637 -0
- tracehub_mcp-0.2.0/Dockerfile +74 -0
- tracehub_mcp-0.2.0/LICENSE +201 -0
- tracehub_mcp-0.2.0/NOTICE +11 -0
- tracehub_mcp-0.2.0/PKG-INFO +798 -0
- tracehub_mcp-0.2.0/README.md +763 -0
- tracehub_mcp-0.2.0/pyproject.toml +110 -0
- tracehub_mcp-0.2.0/src/opentelemetry_mcp/__init__.py +3 -0
- tracehub_mcp-0.2.0/src/opentelemetry_mcp/attributes.py +174 -0
- tracehub_mcp-0.2.0/src/opentelemetry_mcp/backends/__init__.py +5 -0
- tracehub_mcp-0.2.0/src/opentelemetry_mcp/backends/base.py +160 -0
- tracehub_mcp-0.2.0/src/opentelemetry_mcp/backends/datadog.py +845 -0
- tracehub_mcp-0.2.0/src/opentelemetry_mcp/backends/filter_engine.py +284 -0
- tracehub_mcp-0.2.0/src/opentelemetry_mcp/backends/jaeger.py +474 -0
- tracehub_mcp-0.2.0/src/opentelemetry_mcp/backends/sentry.py +1188 -0
- tracehub_mcp-0.2.0/src/opentelemetry_mcp/backends/tempo.py +700 -0
- tracehub_mcp-0.2.0/src/opentelemetry_mcp/backends/traceloop.py +729 -0
- tracehub_mcp-0.2.0/src/opentelemetry_mcp/config.py +148 -0
- tracehub_mcp-0.2.0/src/opentelemetry_mcp/constants.py +196 -0
- tracehub_mcp-0.2.0/src/opentelemetry_mcp/models.py +685 -0
- tracehub_mcp-0.2.0/src/opentelemetry_mcp/server.py +747 -0
- tracehub_mcp-0.2.0/src/opentelemetry_mcp/tools/__init__.py +3 -0
- tracehub_mcp-0.2.0/src/opentelemetry_mcp/tools/errors.py +123 -0
- tracehub_mcp-0.2.0/src/opentelemetry_mcp/tools/expensive_traces.py +126 -0
- tracehub_mcp-0.2.0/src/opentelemetry_mcp/tools/list_llm_tools.py +137 -0
- tracehub_mcp-0.2.0/src/opentelemetry_mcp/tools/list_models.py +106 -0
- tracehub_mcp-0.2.0/src/opentelemetry_mcp/tools/model_stats.py +168 -0
- tracehub_mcp-0.2.0/src/opentelemetry_mcp/tools/search.py +117 -0
- tracehub_mcp-0.2.0/src/opentelemetry_mcp/tools/search_spans.py +119 -0
- tracehub_mcp-0.2.0/src/opentelemetry_mcp/tools/services.py +52 -0
- tracehub_mcp-0.2.0/src/opentelemetry_mcp/tools/slow_traces.py +114 -0
- tracehub_mcp-0.2.0/src/opentelemetry_mcp/tools/trace.py +80 -0
- tracehub_mcp-0.2.0/src/opentelemetry_mcp/tools/usage.py +114 -0
- tracehub_mcp-0.2.0/src/opentelemetry_mcp/utils.py +23 -0
- tracehub_mcp-0.2.0/start_locally.sh +54 -0
- tracehub_mcp-0.2.0/tests/__init__.py +1 -0
- tracehub_mcp-0.2.0/tests/conftest.py +122 -0
- tracehub_mcp-0.2.0/tests/integration/__init__.py +1 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_jaeger_integration/TestJaegerBackendHealth.test_health_check_healthy.yaml +32 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_jaeger_integration/TestJaegerGetTrace.test_get_trace_by_id.yaml +92 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_jaeger_integration/TestJaegerGetTrace.test_get_trace_invalid_id.yaml +37 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_jaeger_integration/TestJaegerLLMSpans.test_search_llm_spans.yaml +62 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_jaeger_integration/TestJaegerLLMSpans.test_search_traces_with_llm_model_filter.yaml +152 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_jaeger_integration/TestJaegerListServices.test_list_services.yaml +32 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_jaeger_integration/TestJaegerSearchSpans.test_search_spans_basic.yaml +62 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_jaeger_integration/TestJaegerSearchSpans.test_search_spans_with_generic_filter.yaml +62 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_jaeger_integration/TestJaegerSearchSpans.test_search_spans_with_limit.yaml +98 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_jaeger_integration/TestJaegerSearchSpans.test_search_spans_with_operation.yaml +93 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_jaeger_integration/TestJaegerSearchTraces.test_search_traces_basic.yaml +78 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_jaeger_integration/TestJaegerSearchTraces.test_search_traces_with_duration_filter.yaml +64 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_jaeger_integration/TestJaegerSearchTraces.test_search_traces_with_error_filter.yaml +78 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_jaeger_integration/TestJaegerSearchTraces.test_search_traces_with_generic_filter.yaml +62 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_jaeger_integration/TestJaegerSearchTraces.test_search_traces_with_limit.yaml +68 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_jaeger_integration/TestJaegerSearchTraces.test_search_traces_with_operation.yaml +112 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_jaeger_integration/TestJaegerServiceOperations.test_get_service_operations.yaml +62 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_tempo_integration/TestTempoBackendHealth.test_health_check_healthy.yaml +33 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_tempo_integration/TestTempoGetTrace.test_get_trace_by_id.yaml +239 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_tempo_integration/TestTempoGetTrace.test_get_trace_invalid_id.yaml +30 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_tempo_integration/TestTempoLLMSpans.test_search_llm_spans.yaml +5248 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_tempo_integration/TestTempoLLMSpans.test_search_traces_with_llm_model_filter.yaml +122 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_tempo_integration/TestTempoListServices.test_list_services.yaml +39 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_tempo_integration/TestTempoSearchSpans.test_search_spans_basic.yaml +5248 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_tempo_integration/TestTempoSearchSpans.test_search_spans_with_generic_filter.yaml +32 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_tempo_integration/TestTempoSearchSpans.test_search_spans_with_limit.yaml +5248 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_tempo_integration/TestTempoSearchSpans.test_search_spans_with_operation.yaml +69 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_tempo_integration/TestTempoSearchSpans.test_search_spans_with_service_filter.yaml +2707 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_tempo_integration/TestTempoSearchTraces.test_search_traces_basic.yaml +5248 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_tempo_integration/TestTempoSearchTraces.test_search_traces_with_attribute_filter.yaml +5248 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_tempo_integration/TestTempoSearchTraces.test_search_traces_with_duration_filter.yaml +5248 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_tempo_integration/TestTempoSearchTraces.test_search_traces_with_error_filter.yaml +32 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_tempo_integration/TestTempoSearchTraces.test_search_traces_with_generic_filter.yaml +32 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_tempo_integration/TestTempoSearchTraces.test_search_traces_with_limit.yaml +3384 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_tempo_integration/TestTempoSearchTraces.test_search_traces_with_operation.yaml +69 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_tempo_integration/TestTempoSearchTraces.test_search_traces_with_service_filter.yaml +2707 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_tempo_integration/TestTempoServiceOperations.test_get_service_operations.yaml +69 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_tempo_integration/TestTempoTraceQL.test_search_with_contains_filter.yaml +5285 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_tempo_integration/TestTempoTraceQL.test_search_with_in_filter.yaml +5285 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_tempo_integration/TestTempoTraceQL.test_search_with_multiple_filters.yaml +69 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_traceloop_integration/TestTraceloopBackendHealth.test_health_check_healthy.yaml +864 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_traceloop_integration/TestTraceloopFilters.test_search_with_comparison_operators.yaml +40 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_traceloop_integration/TestTraceloopFilters.test_search_with_multiple_filters.yaml +846 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_traceloop_integration/TestTraceloopGetTrace.test_get_trace_by_id.yaml +943 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_traceloop_integration/TestTraceloopGetTrace.test_get_trace_invalid_id.yaml +32 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_traceloop_integration/TestTraceloopLLMSpans.test_search_llm_spans.yaml +1036 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_traceloop_integration/TestTraceloopLLMSpans.test_search_spans_by_llm_system.yaml +2044 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_traceloop_integration/TestTraceloopListServices.test_list_services.yaml +814 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_traceloop_integration/TestTraceloopSearchSpans.test_search_spans_basic.yaml +1036 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_traceloop_integration/TestTraceloopSearchSpans.test_search_spans_with_generic_filter.yaml +1036 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_traceloop_integration/TestTraceloopSearchSpans.test_search_spans_with_limit.yaml +754 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_traceloop_integration/TestTraceloopSearchSpans.test_search_spans_with_operation.yaml +876 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_traceloop_integration/TestTraceloopSearchSpans.test_search_spans_with_service_filter.yaml +846 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_traceloop_integration/TestTraceloopSearchTraces.test_search_spans_with_llm_model_filter.yaml +394 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_traceloop_integration/TestTraceloopSearchTraces.test_search_traces_basic.yaml +40 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_traceloop_integration/TestTraceloopSearchTraces.test_search_traces_with_duration_filter.yaml +40 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_traceloop_integration/TestTraceloopSearchTraces.test_search_traces_with_error_filter.yaml +40 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_traceloop_integration/TestTraceloopSearchTraces.test_search_traces_with_generic_filter.yaml +40 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_traceloop_integration/TestTraceloopSearchTraces.test_search_traces_with_limit.yaml +40 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_traceloop_integration/TestTraceloopSearchTraces.test_search_traces_with_service_filter.yaml +846 -0
- tracehub_mcp-0.2.0/tests/integration/cassettes/test_traceloop_integration/TestTraceloopServiceOperations.test_get_service_operations.yaml +844 -0
- tracehub_mcp-0.2.0/tests/integration/conftest.py +288 -0
- tracehub_mcp-0.2.0/tests/integration/test_jaeger_integration.py +361 -0
- tracehub_mcp-0.2.0/tests/integration/test_tempo_integration.py +439 -0
- tracehub_mcp-0.2.0/tests/integration/test_traceloop_integration.py +469 -0
- tracehub_mcp-0.2.0/tests/test_datadog.py +781 -0
- tracehub_mcp-0.2.0/tests/test_models.py +128 -0
- tracehub_mcp-0.2.0/tests/test_sentry.py +1117 -0
- tracehub_mcp-0.2.0/tests/test_traceloop.py +231 -0
- tracehub_mcp-0.2.0/uv.lock +1965 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
[tool.commitizen]
|
|
2
|
+
name = "cz_conventional_commits"
|
|
3
|
+
version = "0.2.0"
|
|
4
|
+
tag_format = "v$version"
|
|
5
|
+
update_changelog_on_bump = true
|
|
6
|
+
major_version_zero = true
|
|
7
|
+
version_scheme = "pep440"
|
|
8
|
+
|
|
9
|
+
# Files where Commitizen will update the version
|
|
10
|
+
version_files = [
|
|
11
|
+
"pyproject.toml:version",
|
|
12
|
+
"src/opentelemetry_mcp/__init__.py:__version__"
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
# Changelog configuration
|
|
16
|
+
[tool.commitizen.changelog]
|
|
17
|
+
# Categorize commits by type
|
|
18
|
+
file = "CHANGELOG.md"
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
.Python
|
|
7
|
+
*.egg-info/
|
|
8
|
+
dist/
|
|
9
|
+
build/
|
|
10
|
+
*.egg
|
|
11
|
+
|
|
12
|
+
# Virtual environments
|
|
13
|
+
.venv/
|
|
14
|
+
venv/
|
|
15
|
+
ENV/
|
|
16
|
+
env/
|
|
17
|
+
|
|
18
|
+
# Testing
|
|
19
|
+
.pytest_cache/
|
|
20
|
+
.coverage
|
|
21
|
+
htmlcov/
|
|
22
|
+
.mypy_cache/
|
|
23
|
+
.ruff_cache/
|
|
24
|
+
|
|
25
|
+
# IDE
|
|
26
|
+
.vscode/
|
|
27
|
+
.idea/
|
|
28
|
+
*.swp
|
|
29
|
+
*.swo
|
|
30
|
+
*~
|
|
31
|
+
|
|
32
|
+
# Git
|
|
33
|
+
.git/
|
|
34
|
+
.gitignore
|
|
35
|
+
|
|
36
|
+
# Documentation
|
|
37
|
+
*.md
|
|
38
|
+
!README.md
|
|
39
|
+
docs/
|
|
40
|
+
|
|
41
|
+
# CI/CD
|
|
42
|
+
.github/
|
|
43
|
+
|
|
44
|
+
# Environment files (include these at runtime instead)
|
|
45
|
+
.env
|
|
46
|
+
.env.local
|
|
47
|
+
.env.*.local
|
|
48
|
+
|
|
49
|
+
# UV cache
|
|
50
|
+
.uv/
|
|
51
|
+
|
|
52
|
+
# macOS
|
|
53
|
+
.DS_Store
|
|
54
|
+
|
|
55
|
+
# Tests
|
|
56
|
+
tests/
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Backend Configuration
|
|
2
|
+
# Supported backends: jaeger, tempo, traceloop, datadog, sentry
|
|
3
|
+
BACKEND_TYPE=jaeger
|
|
4
|
+
|
|
5
|
+
# Backend URL (required)
|
|
6
|
+
# Examples:
|
|
7
|
+
# Jaeger: http://localhost:16686
|
|
8
|
+
# Tempo: http://localhost:3200
|
|
9
|
+
# Traceloop: https://api.traceloop.com/v2
|
|
10
|
+
# Datadog (US): https://api.datadoghq.com
|
|
11
|
+
# Datadog (EU): https://api.datadoghq.eu
|
|
12
|
+
# Sentry (SaaS): https://sentry.io
|
|
13
|
+
# Sentry (self-hosted): https://sentry.your-company.com
|
|
14
|
+
BACKEND_URL=http://localhost:16686
|
|
15
|
+
|
|
16
|
+
# Optional: API key for authenticated backends (mainly for Traceloop, required
|
|
17
|
+
# for Datadog and Sentry - for Sentry this is an auth token with trace/event
|
|
18
|
+
# read permissions)
|
|
19
|
+
BACKEND_API_KEY=
|
|
20
|
+
|
|
21
|
+
# Required for Datadog backend only: Application key, in addition to BACKEND_API_KEY
|
|
22
|
+
BACKEND_APP_KEY=
|
|
23
|
+
|
|
24
|
+
# Required for Sentry backend only: organization slug (every Sentry API
|
|
25
|
+
# endpoint this backend uses is organization-scoped).
|
|
26
|
+
BACKEND_SENTRY_ORG=
|
|
27
|
+
|
|
28
|
+
# Optional for Sentry backend: project slug to narrow queries to. When
|
|
29
|
+
# omitted, queries span every project the auth token can access.
|
|
30
|
+
BACKEND_SENTRY_PROJECT=
|
|
31
|
+
|
|
32
|
+
# Optional: Comma-separated list of environments for Traceloop backend (default: production)
|
|
33
|
+
# Only used when BACKEND_TYPE=traceloop
|
|
34
|
+
BACKEND_ENVIRONMENTS=production
|
|
35
|
+
|
|
36
|
+
# Optional: Request timeout in seconds (default: 30)
|
|
37
|
+
BACKEND_TIMEOUT=30
|
|
38
|
+
|
|
39
|
+
# Optional: Logging level (DEBUG, INFO, WARNING, ERROR)
|
|
40
|
+
LOG_LEVEL=INFO
|
|
41
|
+
|
|
42
|
+
# Optional: Maximum traces per query (default: 100, max: 1000)
|
|
43
|
+
MAX_TRACES_PER_QUERY=100
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Dependabot configuration
|
|
2
|
+
# https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
|
|
3
|
+
|
|
4
|
+
version: 2
|
|
5
|
+
updates:
|
|
6
|
+
# Python dependencies (pyproject.toml)
|
|
7
|
+
- package-ecosystem: "pip"
|
|
8
|
+
directory: "/"
|
|
9
|
+
schedule:
|
|
10
|
+
interval: "weekly"
|
|
11
|
+
day: "monday"
|
|
12
|
+
commit-message:
|
|
13
|
+
prefix: "chore(deps)"
|
|
14
|
+
labels:
|
|
15
|
+
- "dependencies"
|
|
16
|
+
- "python"
|
|
17
|
+
open-pull-requests-limit: 10
|
|
18
|
+
|
|
19
|
+
# GitHub Actions
|
|
20
|
+
- package-ecosystem: "github-actions"
|
|
21
|
+
directory: "/"
|
|
22
|
+
schedule:
|
|
23
|
+
interval: "weekly"
|
|
24
|
+
day: "monday"
|
|
25
|
+
commit-message:
|
|
26
|
+
prefix: "chore(deps)"
|
|
27
|
+
labels:
|
|
28
|
+
- "dependencies"
|
|
29
|
+
- "github-actions"
|
|
30
|
+
open-pull-requests-limit: 5
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: ["main"]
|
|
6
|
+
pull_request:
|
|
7
|
+
types: [opened, synchronize]
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
lint:
|
|
14
|
+
name: Lint
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v6
|
|
18
|
+
- name: Setup UV
|
|
19
|
+
uses: astral-sh/setup-uv@v7
|
|
20
|
+
with:
|
|
21
|
+
version: "latest"
|
|
22
|
+
enable-cache: true
|
|
23
|
+
- name: Setup Python
|
|
24
|
+
uses: actions/setup-python@v6
|
|
25
|
+
with:
|
|
26
|
+
python-version: "3.13"
|
|
27
|
+
- name: Install dependencies
|
|
28
|
+
run: uv sync --dev
|
|
29
|
+
- name: Lint with Ruff
|
|
30
|
+
run: uv run ruff check --output-format=github
|
|
31
|
+
- name: Lint with Mypy
|
|
32
|
+
run: uv run mypy .
|
|
33
|
+
test:
|
|
34
|
+
name: Test
|
|
35
|
+
runs-on: ubuntu-latest
|
|
36
|
+
steps:
|
|
37
|
+
- uses: actions/checkout@v6
|
|
38
|
+
- name: Setup UV
|
|
39
|
+
uses: astral-sh/setup-uv@v7
|
|
40
|
+
with:
|
|
41
|
+
version: "latest"
|
|
42
|
+
enable-cache: true
|
|
43
|
+
- name: Setup Python
|
|
44
|
+
uses: actions/setup-python@v6
|
|
45
|
+
with:
|
|
46
|
+
python-version: "3.13"
|
|
47
|
+
- name: Install dependencies
|
|
48
|
+
run: uv sync --dev
|
|
49
|
+
- name: Test with pytest
|
|
50
|
+
run: uv run pytest
|
|
51
|
+
build-test:
|
|
52
|
+
needs: test
|
|
53
|
+
runs-on: ubuntu-latest
|
|
54
|
+
permissions:
|
|
55
|
+
contents: read
|
|
56
|
+
actions: read
|
|
57
|
+
pull-requests: write
|
|
58
|
+
security-events: write
|
|
59
|
+
strategy:
|
|
60
|
+
matrix:
|
|
61
|
+
platform: [amd64, arm64]
|
|
62
|
+
include:
|
|
63
|
+
- platform: amd64
|
|
64
|
+
runs-on: ubuntu-latest
|
|
65
|
+
docker-platform: linux/amd64
|
|
66
|
+
- platform: arm64
|
|
67
|
+
runs-on: ubuntu-24.04-arm
|
|
68
|
+
docker-platform: linux/arm64
|
|
69
|
+
steps:
|
|
70
|
+
- uses: actions/checkout@v6
|
|
71
|
+
|
|
72
|
+
- name: Set up Docker Buildx
|
|
73
|
+
uses: docker/setup-buildx-action@v3
|
|
74
|
+
|
|
75
|
+
- name: Docker Build
|
|
76
|
+
uses: docker/build-push-action@v6
|
|
77
|
+
with:
|
|
78
|
+
platforms: ${{ matrix.docker-platform }}
|
|
79
|
+
context: .
|
|
80
|
+
load: true
|
|
81
|
+
push: false
|
|
82
|
+
tags: tracehub-mcp-server:${{ github.sha }}-${{ matrix.platform }}
|
|
83
|
+
- name: Cache Trivy
|
|
84
|
+
uses: actions/cache@v4
|
|
85
|
+
with:
|
|
86
|
+
path: ~/.cache/trivy
|
|
87
|
+
key: trivy-${{ runner.os }}-${{ matrix.platform }}
|
|
88
|
+
restore-keys: |
|
|
89
|
+
trivy-${{ runner.os }}-
|
|
90
|
+
- name: Trivy scan (JSON)
|
|
91
|
+
uses: aquasecurity/trivy-action@v0.35.0
|
|
92
|
+
with:
|
|
93
|
+
image-ref: tracehub-mcp-server:${{ github.sha }}-${{ matrix.platform }}
|
|
94
|
+
scanners: secret,vuln
|
|
95
|
+
exit-code: "0"
|
|
96
|
+
severity: CRITICAL,HIGH
|
|
97
|
+
format: json
|
|
98
|
+
output: trivy-results-${{ matrix.platform }}.json
|
|
99
|
+
- name: Convert to table
|
|
100
|
+
run: trivy convert --format table --output trivy-results-${{ matrix.platform }}.txt trivy-results-${{ matrix.platform }}.json
|
|
101
|
+
- name: Convert to SARIF
|
|
102
|
+
if: github.event_name != 'pull_request' && github.ref == 'refs/heads/main'
|
|
103
|
+
run: trivy convert --format sarif --output trivy-results-${{ matrix.platform }}.sarif trivy-results-${{ matrix.platform }}.json
|
|
104
|
+
- name: Upload SARIF to GitHub Security
|
|
105
|
+
if: github.event_name != 'pull_request' && github.ref == 'refs/heads/main'
|
|
106
|
+
uses: github/codeql-action/upload-sarif@v4
|
|
107
|
+
with:
|
|
108
|
+
sarif_file: trivy-results-${{ matrix.platform }}.sarif
|
|
109
|
+
category: container-security-tracehub-mcp-server-${{ matrix.platform }}
|
|
110
|
+
- name: Log Trivy results
|
|
111
|
+
run: |
|
|
112
|
+
echo "::group::Trivy Scan Results (tracehub-mcp-server-${{ matrix.platform }})"
|
|
113
|
+
if [ -s "trivy-results-${{ matrix.platform }}.txt" ]; then
|
|
114
|
+
cat "trivy-results-${{ matrix.platform }}.txt"
|
|
115
|
+
else
|
|
116
|
+
echo "No issues found!"
|
|
117
|
+
fi
|
|
118
|
+
echo "::endgroup::"
|
|
119
|
+
- name: Prepare PR comment
|
|
120
|
+
if: github.event_name == 'pull_request'
|
|
121
|
+
run: |
|
|
122
|
+
MAX_CHARS=60000
|
|
123
|
+
RESULTS_FILE="trivy-results-${{ matrix.platform }}.txt"
|
|
124
|
+
COMMENT_FILE="trivy-comment-${{ matrix.platform }}.md"
|
|
125
|
+
FILE_SIZE=$(wc -c < "$RESULTS_FILE" || echo "0")
|
|
126
|
+
{
|
|
127
|
+
echo "## Container Security Scan (tracehub-mcp-server-${{ matrix.platform }})"
|
|
128
|
+
echo ""
|
|
129
|
+
if [ ! -s "$RESULTS_FILE" ]; then
|
|
130
|
+
echo "**No vulnerabilities found!**"
|
|
131
|
+
else
|
|
132
|
+
echo "<details>"
|
|
133
|
+
echo "<summary>Click to expand results</summary>"
|
|
134
|
+
echo ""
|
|
135
|
+
echo '```'
|
|
136
|
+
if [ "$FILE_SIZE" -gt "$MAX_CHARS" ]; then
|
|
137
|
+
head -c "$MAX_CHARS" "$RESULTS_FILE"
|
|
138
|
+
echo ""
|
|
139
|
+
echo "... (output truncated - exceeded ${MAX_CHARS} characters)"
|
|
140
|
+
echo "See full results in workflow logs"
|
|
141
|
+
else
|
|
142
|
+
cat "$RESULTS_FILE"
|
|
143
|
+
fi
|
|
144
|
+
echo '```'
|
|
145
|
+
echo ""
|
|
146
|
+
echo "</details>"
|
|
147
|
+
fi
|
|
148
|
+
} > "$COMMENT_FILE"
|
|
149
|
+
- name: Post PR comment
|
|
150
|
+
if: github.event_name == 'pull_request'
|
|
151
|
+
uses: marocchino/sticky-pull-request-comment@v2
|
|
152
|
+
with:
|
|
153
|
+
header: trivy-scan-tracehub-mcp-server-${{ matrix.platform }}
|
|
154
|
+
path: trivy-comment-${{ matrix.platform }}.md
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch: # Manual trigger via GitHub Actions UI
|
|
5
|
+
|
|
6
|
+
permissions:
|
|
7
|
+
contents: write # Required for pushing commits, tags, and creating releases
|
|
8
|
+
id-token: write # Required for PyPI OIDC (Trusted Publishing)
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
bump-version:
|
|
12
|
+
name: Bump Version & Create Release
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
outputs:
|
|
15
|
+
new_version: ${{ steps.cz.outputs.version }}
|
|
16
|
+
steps:
|
|
17
|
+
- name: Checkout code
|
|
18
|
+
uses: actions/checkout@v6
|
|
19
|
+
with:
|
|
20
|
+
fetch-depth: 0 # Full history required for Commitizen
|
|
21
|
+
token: ${{ secrets.GITHUB_TOKEN }}
|
|
22
|
+
|
|
23
|
+
- name: Setup Python
|
|
24
|
+
uses: actions/setup-python@v6
|
|
25
|
+
with:
|
|
26
|
+
python-version: "3.13"
|
|
27
|
+
|
|
28
|
+
- name: Install Commitizen
|
|
29
|
+
run: pip install commitizen
|
|
30
|
+
|
|
31
|
+
- name: Bump version
|
|
32
|
+
id: cz
|
|
33
|
+
uses: commitizen-tools/commitizen-action@master
|
|
34
|
+
with:
|
|
35
|
+
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
36
|
+
changelog_increment_filename: body.md
|
|
37
|
+
# The action's own entrypoint runs `git config --local user.name/email`
|
|
38
|
+
# unconditionally using these inputs (default: github-actions[bot]) --
|
|
39
|
+
# a standalone `git config` step earlier in this job has no effect,
|
|
40
|
+
# since this overwrites it right before the bump commit is made.
|
|
41
|
+
git_name: "sairam0424"
|
|
42
|
+
git_email: "uggesairam0000@gmail.com"
|
|
43
|
+
|
|
44
|
+
- name: Print version info
|
|
45
|
+
run: |
|
|
46
|
+
echo "New version: ${{ steps.cz.outputs.version }}"
|
|
47
|
+
echo "Version bump: ${{ steps.cz.outputs.version }}"
|
|
48
|
+
|
|
49
|
+
- name: Create GitHub Release
|
|
50
|
+
env:
|
|
51
|
+
GH_TOKEN: ${{ github.token }}
|
|
52
|
+
run: |
|
|
53
|
+
gh release create "${{ steps.cz.outputs.version }}" \
|
|
54
|
+
--title "Release ${{ steps.cz.outputs.version }}" \
|
|
55
|
+
--notes-file "body.md"
|
|
56
|
+
|
|
57
|
+
build-and-publish:
|
|
58
|
+
name: Build and Publish to PyPI
|
|
59
|
+
needs: bump-version
|
|
60
|
+
runs-on: ubuntu-latest
|
|
61
|
+
permissions:
|
|
62
|
+
id-token: write # Required for PyPI OIDC
|
|
63
|
+
steps:
|
|
64
|
+
- name: Checkout code (with new version)
|
|
65
|
+
uses: actions/checkout@v6
|
|
66
|
+
with:
|
|
67
|
+
ref: main # Get the version-bumped code
|
|
68
|
+
|
|
69
|
+
- name: Setup UV
|
|
70
|
+
uses: astral-sh/setup-uv@v7
|
|
71
|
+
with:
|
|
72
|
+
version: "latest"
|
|
73
|
+
enable-cache: true
|
|
74
|
+
|
|
75
|
+
- name: Setup Python
|
|
76
|
+
uses: actions/setup-python@v6
|
|
77
|
+
with:
|
|
78
|
+
python-version: "3.13"
|
|
79
|
+
|
|
80
|
+
- name: Build package
|
|
81
|
+
run: |
|
|
82
|
+
uv build --wheel --sdist
|
|
83
|
+
ls -lh dist/
|
|
84
|
+
|
|
85
|
+
- name: Publish to PyPI
|
|
86
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
87
|
+
# No credentials needed - uses OIDC/Trusted Publishing!
|
|
88
|
+
|
|
89
|
+
test-installation:
|
|
90
|
+
name: Test PyPI Installation
|
|
91
|
+
needs: [bump-version, build-and-publish]
|
|
92
|
+
runs-on: ubuntu-latest
|
|
93
|
+
steps:
|
|
94
|
+
- name: Setup Python
|
|
95
|
+
uses: actions/setup-python@v6
|
|
96
|
+
with:
|
|
97
|
+
python-version: "3.13"
|
|
98
|
+
|
|
99
|
+
- name: Wait for package availability
|
|
100
|
+
run: sleep 60 # Wait for PyPI to index the package
|
|
101
|
+
|
|
102
|
+
- name: Test installation from PyPI
|
|
103
|
+
run: |
|
|
104
|
+
pip install tracehub-mcp==${{ needs.bump-version.outputs.new_version }}
|
|
105
|
+
python -c "import opentelemetry_mcp; print(f'Installed version: {opentelemetry_mcp.__version__}')"
|
|
106
|
+
tracehub-mcp --help
|
|
107
|
+
|
|
108
|
+
- name: Installation successful
|
|
109
|
+
run: echo "✅ Package successfully published and verified on PyPI!"
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
name: Security Scan
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch: # Manual trigger
|
|
5
|
+
schedule:
|
|
6
|
+
- cron: "0 10 * * *" # Daily at 10 AM UTC
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
actions: read
|
|
11
|
+
security-events: write
|
|
12
|
+
pull-requests: write
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
image-scan:
|
|
16
|
+
strategy:
|
|
17
|
+
fail-fast: false
|
|
18
|
+
matrix:
|
|
19
|
+
platform: [amd64, arm64]
|
|
20
|
+
include:
|
|
21
|
+
- platform: amd64
|
|
22
|
+
runs-on: ubuntu-latest
|
|
23
|
+
docker-platform: linux/amd64
|
|
24
|
+
- platform: arm64
|
|
25
|
+
runs-on: ubuntu-24.04-arm
|
|
26
|
+
docker-platform: linux/arm64
|
|
27
|
+
runs-on: ${{ matrix.runs-on }}
|
|
28
|
+
steps:
|
|
29
|
+
- uses: actions/checkout@v6
|
|
30
|
+
|
|
31
|
+
- name: Cache Trivy
|
|
32
|
+
uses: actions/cache@v4
|
|
33
|
+
with:
|
|
34
|
+
path: ~/.cache/trivy
|
|
35
|
+
key: trivy-${{ runner.os }}-${{ matrix.platform }}
|
|
36
|
+
restore-keys: |
|
|
37
|
+
trivy-${{ runner.os }}-
|
|
38
|
+
|
|
39
|
+
- name: Set up Docker Buildx
|
|
40
|
+
uses: docker/setup-buildx-action@v3
|
|
41
|
+
|
|
42
|
+
- name: Build image
|
|
43
|
+
run: |
|
|
44
|
+
docker buildx build \
|
|
45
|
+
--load \
|
|
46
|
+
--platform "${{ matrix.docker-platform }}" \
|
|
47
|
+
-t "tracehub-mcp-server:${{ github.sha }}-${{ matrix.platform }}" \
|
|
48
|
+
.
|
|
49
|
+
|
|
50
|
+
- name: Trivy scan (JSON)
|
|
51
|
+
uses: aquasecurity/trivy-action@v0.35.0
|
|
52
|
+
with:
|
|
53
|
+
image-ref: tracehub-mcp-server:${{ github.sha }}-${{ matrix.platform }}
|
|
54
|
+
format: json
|
|
55
|
+
output: trivy-results-${{ matrix.platform }}.json
|
|
56
|
+
scanners: vuln,secret,license
|
|
57
|
+
vuln-type: os,library
|
|
58
|
+
severity: CRITICAL,HIGH,MEDIUM,LOW
|
|
59
|
+
|
|
60
|
+
- name: Convert Trivy results
|
|
61
|
+
run: |
|
|
62
|
+
set -euo pipefail
|
|
63
|
+
PREFIX="trivy-results-${{ matrix.platform }}"
|
|
64
|
+
|
|
65
|
+
trivy convert --format table --output "${PREFIX}.txt" "${PREFIX}.json"
|
|
66
|
+
|
|
67
|
+
if [[ "${{ github.event_name }}" != "pull_request" && "${{ github.ref }}" == "refs/heads/main" ]]; then
|
|
68
|
+
trivy convert --format sarif --output "${PREFIX}.sarif" "${PREFIX}.json"
|
|
69
|
+
fi
|
|
70
|
+
|
|
71
|
+
- name: Upload SARIF to GitHub Security
|
|
72
|
+
if: github.event_name != 'pull_request' && github.ref == 'refs/heads/main'
|
|
73
|
+
uses: github/codeql-action/upload-sarif@v4
|
|
74
|
+
with:
|
|
75
|
+
sarif_file: trivy-results-${{ matrix.platform }}.sarif
|
|
76
|
+
category: container-security-tracehub-mcp-server-${{ matrix.platform }}
|
|
77
|
+
|
|
78
|
+
- name: Log full Trivy results
|
|
79
|
+
run: |
|
|
80
|
+
echo "::group::Full Trivy Scan Results (tracehub-mcp-server - ${{ matrix.platform }})"
|
|
81
|
+
RESULTS_FILE="trivy-results-${{ matrix.platform }}.txt"
|
|
82
|
+
if [ -s "$RESULTS_FILE" ]; then
|
|
83
|
+
cat "$RESULTS_FILE"
|
|
84
|
+
else
|
|
85
|
+
echo "✅ No vulnerabilities found!"
|
|
86
|
+
fi
|
|
87
|
+
echo "::endgroup::"
|
|
88
|
+
|
|
89
|
+
- name: Prepare PR comment
|
|
90
|
+
if: github.event_name == 'pull_request'
|
|
91
|
+
run: |
|
|
92
|
+
RESULTS_FILE="trivy-results-${{ matrix.platform }}.txt"
|
|
93
|
+
COMMENT_FILE="trivy-comment-${{ matrix.platform }}.md"
|
|
94
|
+
MAX_CHARS=60000
|
|
95
|
+
FILE_SIZE=$(wc -c < "$RESULTS_FILE")
|
|
96
|
+
|
|
97
|
+
{
|
|
98
|
+
echo "## 🔒 Container Vulnerability Scan (tracehub-mcp-server - ${{ matrix.platform }})"
|
|
99
|
+
echo ""
|
|
100
|
+
if [ ! -s "$RESULTS_FILE" ]; then
|
|
101
|
+
echo "✅ **No vulnerabilities found!**"
|
|
102
|
+
else
|
|
103
|
+
echo "<details>"
|
|
104
|
+
echo "<summary>Click to expand results</summary>"
|
|
105
|
+
echo ""
|
|
106
|
+
echo '```'
|
|
107
|
+
if [ "$FILE_SIZE" -gt "$MAX_CHARS" ]; then
|
|
108
|
+
head -c "$MAX_CHARS" "$RESULTS_FILE"
|
|
109
|
+
echo ""
|
|
110
|
+
echo "... (output truncated - exceeded ${MAX_CHARS} characters)"
|
|
111
|
+
echo "See full results in the 'Full Trivy Scan Results' step above"
|
|
112
|
+
else
|
|
113
|
+
cat "$RESULTS_FILE"
|
|
114
|
+
fi
|
|
115
|
+
echo '```'
|
|
116
|
+
echo ""
|
|
117
|
+
echo "</details>"
|
|
118
|
+
fi
|
|
119
|
+
} > "$COMMENT_FILE"
|
|
120
|
+
|
|
121
|
+
- name: Post PR comment
|
|
122
|
+
if: github.event_name == 'pull_request'
|
|
123
|
+
uses: marocchino/sticky-pull-request-comment@v2
|
|
124
|
+
with:
|
|
125
|
+
header: trivy-scan-tracehub-mcp-server-${{ matrix.platform }}
|
|
126
|
+
path: trivy-comment-${{ matrix.platform }}.md
|