Skip to content

Commit 0ee23d1

Browse files
committed
test: check if code is API breaking
1 parent 8f40ff4 commit 0ee23d1

3 files changed

Lines changed: 401 additions & 0 deletions

File tree

.github/workflows/api_contract.yml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
name: API Contract
2+
3+
on:
4+
push:
5+
branches: ["main"]
6+
pull_request:
7+
merge_group:
8+
9+
permissions:
10+
contents: read
11+
12+
jobs:
13+
api-contract:
14+
name: Check public API route contract
15+
runs-on: ubuntu-latest
16+
concurrency:
17+
group: ${{ github.workflow }}-${{ github.ref }}
18+
cancel-in-progress: true
19+
steps:
20+
- uses: actions/checkout@v5
21+
- name: Set up Python
22+
uses: actions/setup-python@v5
23+
with:
24+
python-version: '3.10'
25+
- name: Verify public API contract
26+
run: python test/test_api_contract.py

test/api_contract_manifest.json

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
{
2+
"version": 1,
3+
"description": "Public Lemonade API route contract. CI compares this manifest with the C++ route registrations so accidental method or path removals are caught during review.",
4+
"sources": [
5+
"src/cpp/server/server.cpp",
6+
"src/cpp/server/ollama_api.cpp",
7+
"src/cpp/server/anthropic_api.cpp",
8+
"src/cpp/server/websocket_server.cpp"
9+
],
10+
"versioned_prefixes": [
11+
"/api/v0",
12+
"/api/v1",
13+
"/v0",
14+
"/v1"
15+
],
16+
"http_routes": [
17+
{"method": "GET", "path": "/live"},
18+
{"method": "GET", "path": "/metrics"},
19+
20+
{"method": "GET", "versioned_path": "health"},
21+
{"method": "GET", "versioned_path": "models"},
22+
{"method": "GET", "versioned_path": "models/{param}"},
23+
{"method": "GET", "versioned_path": "slots"},
24+
{"method": "GET", "versioned_path": "pull/variants"},
25+
{"method": "GET", "versioned_path": "downloads"},
26+
{"method": "GET", "versioned_path": "stats"},
27+
{"method": "GET", "versioned_path": "system-info"},
28+
{"method": "GET", "versioned_path": "system-stats"},
29+
30+
{"method": "POST", "versioned_path": "chat/completions"},
31+
{"method": "POST", "versioned_path": "completions"},
32+
{"method": "POST", "versioned_path": "embeddings"},
33+
{"method": "POST", "versioned_path": "reranking"},
34+
{"method": "POST", "versioned_path": "slots/{param}"},
35+
{"method": "POST", "versioned_path": "tokenize"},
36+
{"method": "POST", "versioned_path": "audio/transcriptions"},
37+
{"method": "POST", "versioned_path": "audio/speech"},
38+
{"method": "POST", "versioned_path": "images/generations"},
39+
{"method": "POST", "versioned_path": "images/edits"},
40+
{"method": "POST", "versioned_path": "images/variations"},
41+
{"method": "POST", "versioned_path": "images/upscale"},
42+
{"method": "POST", "versioned_path": "responses"},
43+
{"method": "POST", "versioned_path": "pull"},
44+
{"method": "POST", "versioned_path": "downloads/control"},
45+
{"method": "POST", "versioned_path": "load"},
46+
{"method": "POST", "versioned_path": "unload"},
47+
{"method": "POST", "versioned_path": "delete"},
48+
{"method": "POST", "versioned_path": "params"},
49+
{"method": "POST", "versioned_path": "install"},
50+
{"method": "POST", "versioned_path": "uninstall"},
51+
{"method": "POST", "versioned_path": "log-level"},
52+
53+
{"method": "POST", "path": "/api/chat"},
54+
{"method": "POST", "path": "/api/generate"},
55+
{"method": "GET", "path": "/api/tags"},
56+
{"method": "POST", "path": "/api/show"},
57+
{"method": "DELETE", "path": "/api/delete"},
58+
{"method": "POST", "path": "/api/pull"},
59+
{"method": "POST", "path": "/api/embed"},
60+
{"method": "POST", "path": "/api/embeddings"},
61+
{"method": "GET", "path": "/api/ps"},
62+
{"method": "GET", "path": "/api/version"},
63+
{"method": "POST", "path": "/api/create"},
64+
{"method": "POST", "path": "/api/copy"},
65+
{"method": "POST", "path": "/api/push"},
66+
{"method": "POST", "path": "/api/blobs/{param}"},
67+
68+
{"method": "POST", "path": "/v1/messages"}
69+
],
70+
"websocket_routes": [
71+
{"method": "WS", "path": "/realtime"},
72+
{"method": "WS", "path": "/logs/stream"}
73+
]
74+
}

0 commit comments

Comments
 (0)