Repository navigation
172 lines (153 loc) · 6.42 KB
/
Copy pathmcp.yml
File metadata and controls
172 lines (153 loc) · 6.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
name: MCP Foundation
on:
pull_request:
paths:
- "backend/**"
- "mcp_server/**"
- ".commitrail/initiatives/WS-MCP-002/**"
- "docs/roadmap_status.md"
- ".github/workflows/mcp.yml"
push:
branches: [main]
paths:
- "backend/**"
- "mcp_server/**"
- ".commitrail/initiatives/WS-MCP-002/**"
- "docs/roadmap_status.md"
- ".github/workflows/mcp.yml"
concurrency:
group: mcp-foundation-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
permissions:
contents: read
jobs:
package:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
with:
persist-credentials: false
fetch-depth: 0
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065
with:
python-version: "3.12"
- name: Bind exact checked-out tree
shell: bash
run: |
set -euo pipefail
test "$(git rev-parse HEAD)" = "${GITHUB_SHA}"
test -z "$(git status --porcelain)"
test "$(git rev-parse "${GITHUB_SHA}^{tree}")" = "$(git rev-parse HEAD^{tree})"
- name: Install locked package tooling
run: python -m pip install "uv==0.10.7"
- name: Lint, type-check, test, and build the adapter
working-directory: mcp_server
shell: bash
run: |
set -euo pipefail
uv sync --frozen --extra dev
uv run --frozen ruff check workstream_mcp tests
uv run --frozen mypy workstream_mcp
uv run --frozen pytest -q --ignore=tests/integration --cov=workstream_mcp --cov-report=term-missing
uv build --wheel --out-dir dist
- name: Prove wheel independence from backend source
working-directory: mcp_server
shell: bash
run: |
set -euo pipefail
python -m venv "${RUNNER_TEMP}/workstream-mcp-wheel"
"${RUNNER_TEMP}/workstream-mcp-wheel/bin/pip" install --upgrade pip
"${RUNNER_TEMP}/workstream-mcp-wheel/bin/pip" install dist/*.whl
WORKSTREAM_MCP_WHEEL_PYTHON="${RUNNER_TEMP}/workstream-mcp-wheel/bin/python" \
uv run --frozen pytest -q tests/test_package_independence.py
- name: Build and run the independent container
shell: bash
run: |
set -euo pipefail
image="workstream-mcp-foundation:${GITHUB_SHA}"
docker build --tag "${image}" mcp_server
docker run --detach --rm --name workstream-mcp-foundation \
--publish 127.0.0.1:18080:8080 \
--env WORKSTREAM_API_URL=http://127.0.0.1:9 \
"${image}"
trap 'docker logs workstream-mcp-foundation; docker stop workstream-mcp-foundation' EXIT
for attempt in $(seq 1 30); do
if curl --fail --silent --show-error \
--header 'Accept: application/json, text/event-stream' \
--header 'Content-Type: application/json' \
--data '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' \
http://127.0.0.1:18080/mcp \
| python -c 'import json, sys; assert [tool["name"] for tool in json.load(sys.stdin)["result"]["tools"]] == ["workstream_profile_get", "workstream_profile_update", "workstream_authorization_context_get", "workstream_permissions_list", "workstream_admin_roles_list", "workstream_admin_grants_list", "workstream_actor_admin_grants_list", "workstream_actor_get", "workstream_actor_identity_link_get"]'; then
exit 0
fi
sleep 1
done
exit 1
real-api-contract:
needs: package
runs-on: ubuntu-latest
timeout-minutes: 20
services:
postgres:
image: public.ecr.aws/docker/library/postgres:16@sha256:33f923b05f64ca54ac4401c01126a6b92afe839a0aa0a52bc5aeb5cc958e5f20
env:
POSTGRES_DB: workstream_test
POSTGRES_USER: workstream
POSTGRES_PASSWORD: workstream
ports:
- 5433:5432
options: >-
--health-cmd "pg_isready -U workstream -d workstream_test"
--health-interval 5s
--health-timeout 5s
--health-retries 10
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
with:
persist-credentials: false
fetch-depth: 0
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065
with:
python-version: "3.12"
- name: Bind exact checked-out tree
shell: bash
run: |
set -euo pipefail
test "$(git rev-parse HEAD)" = "${GITHUB_SHA}"
test -z "$(git status --porcelain)"
test "$(git rev-parse "${GITHUB_SHA}^{tree}")" = "$(git rev-parse HEAD^{tree})"
- name: Install backend and adapter test environments
shell: bash
run: |
set -euo pipefail
python -m pip install --upgrade pip
python -m pip install -e "./backend[dev,agents]"
python -m pip install "uv==0.10.7"
cd mcp_server
uv sync --frozen --extra dev
uv build --wheel --out-dir dist
python -m venv "${RUNNER_TEMP}/workstream-mcp-wheel"
"${RUNNER_TEMP}/workstream-mcp-wheel/bin/pip" install --upgrade pip
"${RUNNER_TEMP}/workstream-mcp-wheel/bin/pip" install dist/*.whl
- name: Compare selected OpenAPI contract
working-directory: mcp_server
shell: bash
run: |
set -euo pipefail
export WORKSTREAM_MCP_OPENAPI_COMMAND="$(command -v python) -c 'import json; from app.main import app; print(json.dumps(app.openapi()))'"
uv run --frozen pytest -q tests/test_contract_drift.py
- name: Run real isolated API-to-MCP lifecycle parity
working-directory: backend
env:
WORKSTREAM_MCP_EXECUTABLE: ${{ runner.temp }}/workstream-mcp-wheel/bin/workstream-mcp
WORKSTREAM_TEST_ADMIN_DATABASE_URL: postgresql+asyncpg://workstream:workstream@localhost:5433/postgres
shell: bash
run: |
set -euo pipefail
for suite in test_profile_flow test_access_reads; do
python scripts/run_isolated_tests.py \
--metadata-json "${RUNNER_TEMP}/workstream-mcp-${suite}-evidence.json" \
--timeout-seconds 240 \
-- env PYTHONPATH="../mcp_server" python -m pytest -q "../mcp_server/tests/integration/${suite}.py"
done