|
4 | 4 | # Run once every 24 hours at midnight UTC to catch API changes |
5 | 5 | schedule: |
6 | 6 | - cron: '0 0 * * *' |
7 | | - |
| 7 | + |
8 | 8 | # Allow manual trigger |
9 | 9 | workflow_dispatch: |
10 | | - |
11 | | - # Run on relevant code changes |
| 10 | + |
| 11 | + # Run when the build inputs change |
12 | 12 | push: |
13 | 13 | branches: [main] |
14 | 14 | paths: |
15 | | - - 'scripts/generate-api-docs.sh' |
16 | | - - 'scripts/add-mcp-config.sh' |
17 | | - - 'scripts/add-mcp-config-to-endpoints.sh' |
18 | | - - 'scripts/create-merged-openapi.py' |
| 15 | + - 'scripts/build-public-openapi.py' |
| 16 | + - 'docs.json' |
19 | 17 |
|
20 | 18 | jobs: |
21 | 19 | update-api-docs: |
22 | 20 | runs-on: ubuntu-latest |
23 | 21 | permissions: |
24 | 22 | contents: write |
25 | | - |
| 23 | + |
26 | 24 | steps: |
27 | 25 | - name: Checkout repository |
28 | 26 | uses: actions/checkout@v4 |
29 | 27 | with: |
30 | 28 | persist-credentials: true |
31 | | - |
| 29 | + |
32 | 30 | - name: Setup Node.js |
33 | 31 | uses: actions/setup-node@v4 |
34 | 32 | with: |
35 | 33 | node-version: '18' |
36 | | - |
| 34 | + |
37 | 35 | - name: Setup Python |
38 | 36 | uses: actions/setup-python@v4 |
39 | 37 | with: |
40 | | - python-version: '3.9' |
41 | | - |
| 38 | + python-version: '3.11' |
| 39 | + |
42 | 40 | - name: Install Mintlify scraper |
43 | 41 | run: npm install -g @mintlify/scraping |
44 | | - |
| 42 | + |
45 | 43 | - name: Download OpenAPI specs |
46 | 44 | run: | |
47 | | - echo "📥 Downloading OpenAPI specifications..." |
48 | | - |
49 | | - # Download Customer API spec |
50 | | - echo "📥 Fetching Customer API spec..." |
51 | | - curl -o openapi-customer.json https://api-doc.trykintsugi.com/openapi.json |
52 | | - |
53 | | - # Download Partners API spec |
54 | | - echo "📥 Fetching Partners API spec..." |
55 | | - curl -o openapi-partners.json https://api.trykintsugi.com/openapi.json |
56 | | - |
57 | | - echo "✅ OpenAPI specs downloaded successfully!" |
58 | | - |
59 | | - - name: Create OpenAPI file for MCP |
60 | | - run: | |
61 | | - echo "🔧 Creating OpenAPI file for MCP from 'API Reference - Partners' endpoints..." |
62 | | - |
63 | | - # Make script executable |
64 | | - chmod +x scripts/create-merged-openapi.py |
65 | | - |
66 | | - # Run script to create openapi-mcp.json with only endpoints from "API Reference - Partners" |
67 | | - # The script will create openapi-mcp.json instead of openapi.json |
68 | | - OUTPUT_FILE=openapi-mcp.json python3 scripts/create-merged-openapi.py |
69 | | - |
70 | | - echo "✅ OpenAPI file for MCP created!" |
71 | | - echo " - Filtered/merged spec saved to openapi-mcp.json (for MCP)" |
72 | | - echo " - Contains only endpoints explicitly listed in 'API Reference - Partners'" |
73 | | - echo " - Includes Customer API endpoints + additional Partners endpoints" |
74 | | - echo " - All endpoints have MCP enabled" |
75 | | - |
76 | | - - name: Save full Customer API spec for API Reference tab |
| 45 | + echo "Downloading Customer API spec..." |
| 46 | + curl -fsSL -o openapi-customer.json https://api-doc.trykintsugi.com/openapi.json |
| 47 | +
|
| 48 | + echo "Downloading Partners API spec..." |
| 49 | + curl -fsSL -o openapi-partners.json https://api.trykintsugi.com/openapi.json |
| 50 | +
|
| 51 | + echo "OpenAPI specs downloaded." |
| 52 | +
|
| 53 | + - name: Build public Partner API spec |
77 | 54 | run: | |
78 | | - echo "💾 Saving full Customer API spec for 'API Reference' tab..." |
79 | | - # Copy the full Customer API spec to openapi.json for the API Reference tab |
80 | | - # This ensures the API Reference tab shows all Customer API endpoints, not just filtered ones |
81 | | - cp openapi-customer.json openapi.json |
82 | | - |
83 | | - # Merge enhanced descriptions from Partners API for specific endpoints |
84 | | - # This ensures documentation shows the most up-to-date descriptions even if Customer API hasn't been updated yet |
85 | | - echo "🔧 Merging enhanced descriptions from Partners API where available..." |
86 | | - python3 << 'EOF' |
87 | | - import json |
88 | | - |
89 | | - # Load both specs |
90 | | - with open('openapi-customer.json', 'r') as f: |
91 | | - customer_spec = json.load(f) |
92 | | - with open('openapi-partners.json', 'r') as f: |
93 | | - partners_spec = json.load(f) |
94 | | - |
95 | | - # Merge descriptions from Partners API for endpoints that exist in both specs |
96 | | - # This ensures documentation shows the most up-to-date descriptions |
97 | | - merged_count = 0 |
98 | | - for path in customer_spec.get('paths', {}): |
99 | | - if path in partners_spec.get('paths', {}): |
100 | | - for method in ['get', 'post', 'put', 'patch', 'delete']: |
101 | | - if method in customer_spec['paths'][path] and method in partners_spec['paths'][path]: |
102 | | - partners_desc = partners_spec['paths'][path][method].get('description', '') |
103 | | - customer_desc = customer_spec['paths'][path][method].get('description', '') |
104 | | - # Merge if Partners description exists and is different (likely more up-to-date) |
105 | | - if partners_desc and partners_desc != customer_desc: |
106 | | - # Check if Partners description contains "retrieve supported" or is significantly longer |
107 | | - if 'retrieve supported' in partners_desc.lower() or len(partners_desc) > len(customer_desc) * 1.2: |
108 | | - customer_spec['paths'][path][method]['description'] = partners_desc |
109 | | - merged_count += 1 |
110 | | - print(f" ✅ Merged {method.upper()} {path}: Enhanced description from Partners API") |
111 | | - |
112 | | - # Save updated spec |
113 | | - with open('openapi.json', 'w') as f: |
114 | | - json.dump(customer_spec, f, indent=2) |
115 | | - |
116 | | - if merged_count > 0: |
117 | | - print(f"✅ Merged {merged_count} enhanced description(s) from Partners API") |
118 | | - else: |
119 | | - print("ℹ️ No descriptions needed merging") |
120 | | - EOF |
121 | | - |
122 | | - echo "✅ Full Customer API spec saved to openapi.json" |
123 | | - echo " - This file is used by the 'API Reference' tab in docs.json" |
124 | | - echo " - Contains all Customer API endpoints from https://api-doc.trykintsugi.com/openapi.json" |
125 | | - echo " - Enhanced with updated descriptions from Partners API where available" |
126 | | - |
| 55 | + # Produces openapi-partners-public.json: the partner spec filtered to the |
| 56 | + # endpoints documented under the "API Reference - Partners" tab, with |
| 57 | + # v1<->v2 fallback rewriting, X-API-KEY-only auth, and MCP enabled. |
| 58 | + # The script FAILS if a documented endpoint cannot be resolved, so a |
| 59 | + # backend version bump can never silently empty a page. |
| 60 | + python3 scripts/build-public-openapi.py |
| 61 | +
|
127 | 62 | - name: Validate OpenAPI specs |
128 | 63 | run: | |
129 | | - echo "🔍 Validating OpenAPI specifications..." |
130 | | - |
131 | | - # Validate full Customer API spec (for API Reference tab) |
132 | | - if [ ! -s openapi.json ]; then |
133 | | - echo "❌ Customer API spec (openapi.json) is empty or missing" |
| 64 | + echo "Validating Customer API spec (openapi-customer.json)..." |
| 65 | + if [ ! -s openapi-customer.json ]; then |
| 66 | + echo "Customer API spec is empty or missing" |
134 | 67 | exit 1 |
135 | 68 | fi |
136 | | - customer_path_count=$(jq '.paths | length' openapi.json) |
137 | | - echo "✅ Customer API spec (openapi.json) contains $customer_path_count paths" |
138 | | - |
139 | | - # Validate MCP filtered spec (if it exists) |
140 | | - if [ -s openapi-mcp.json ]; then |
141 | | - echo "🔍 Verifying MCP configuration..." |
142 | | - jq -e '."x-mint".mcp.enabled == true' openapi-mcp.json > /dev/null && echo "✅ MCP OpenAPI has MCP enabled" || echo "❌ MCP OpenAPI missing MCP config" |
143 | | - mcp_path_count=$(jq '.paths | length' openapi-mcp.json) |
144 | | - echo "✅ MCP OpenAPI spec contains $mcp_path_count paths" |
| 69 | + customer_paths=$(jq '.paths | length' openapi-customer.json) |
| 70 | + echo "Customer API spec contains $customer_paths paths" |
| 71 | +
|
| 72 | + echo "Validating public Partner API spec (openapi-partners-public.json)..." |
| 73 | + if [ ! -s openapi-partners-public.json ]; then |
| 74 | + echo "Public Partner API spec is empty or missing" |
| 75 | + exit 1 |
| 76 | + fi |
| 77 | + jq -e '."x-mint".mcp.enabled == true' openapi-partners-public.json > /dev/null \ |
| 78 | + && echo "Public Partner spec has MCP enabled" \ |
| 79 | + || { echo "Public Partner spec missing MCP config"; exit 1; } |
| 80 | + if jq -e '.components.securitySchemes | has("HTTPBearer")' openapi-partners-public.json > /dev/null; then |
| 81 | + echo "Public Partner spec must not expose bearer (internal-only) auth" |
| 82 | + exit 1 |
145 | 83 | fi |
146 | | - |
147 | | - echo "✅ All OpenAPI specs are valid!" |
148 | | - |
149 | | - - name: Generate API documentation |
| 84 | + partner_paths=$(jq '.paths | length' openapi-partners-public.json) |
| 85 | + echo "Public Partner spec contains $partner_paths paths" |
| 86 | +
|
| 87 | + - name: Generate Customer API reference pages |
150 | 88 | run: | |
151 | | - echo "🚀 Generating API documentation from merged OpenAPI spec..." |
152 | | - mkdir -p reference/api reference/partners |
153 | | - |
154 | | - echo "📥 Generating API reference documentation..." |
155 | | - npx @mintlify/scraping openapi-file openapi.json -o reference/api |
156 | | - |
157 | | - echo "✅ API documentation generated successfully!" |
158 | | - |
| 89 | + # Regenerate the Customer "API Reference" tab pages from the public |
| 90 | + # customer spec. The Partner reference pages are intentionally curated |
| 91 | + # by hand (thin MDX frontmatter); they are validated by the build step |
| 92 | + # above rather than auto-scraped, to keep the published surface a |
| 93 | + # deliberate decision. |
| 94 | + mkdir -p reference/api |
| 95 | + npx @mintlify/scraping openapi-file openapi-customer.json -o reference/api |
| 96 | + echo "Customer API reference pages generated." |
| 97 | +
|
159 | 98 | - name: Check for changes |
160 | 99 | id: changes |
161 | 100 | run: | |
162 | 101 | if git diff --quiet && git diff --cached --quiet && [ -z "$(git ls-files --others --exclude-standard)" ]; then |
163 | | - echo "No changes to commit" |
164 | 102 | echo "changed=false" >> $GITHUB_OUTPUT |
165 | 103 | else |
166 | | - echo "Changes detected" |
167 | 104 | echo "changed=true" >> $GITHUB_OUTPUT |
168 | 105 | fi |
169 | | - |
| 106 | +
|
170 | 107 | - name: Commit and push changes |
171 | 108 | if: steps.changes.outputs.changed == 'true' |
172 | 109 | run: | |
173 | 110 | git config user.name "GitHub Actions" |
174 | 111 | git config user.email "actions@github.com" |
175 | | - |
176 | | - # Add all changes (source OpenAPI files + Customer API spec + MCP spec + generated docs) |
177 | | - git add openapi-customer.json openapi-partners.json openapi.json openapi-mcp.json reference/api/ |
178 | | - git commit -m "🤖 Auto-update API documentation and OpenAPI spec [skip ci] |
179 | | -
|
180 | | - - Updated openapi.json with full Customer API spec (for API Reference tab) |
181 | | - - Updated openapi-mcp.json with filtered endpoints from 'API Reference - Partners' (for MCP) |
182 | | - - Source: Customer API from https://api-doc.trykintsugi.com/openapi.json |
183 | | - - Source: Partners API from https://api.trykintsugi.com/openapi.json |
184 | | - - MCP spec includes only endpoints explicitly listed in 'API Reference - Partners' |
185 | | - - All MCP endpoints have MCP enabled for /mcp route |
186 | | - - Regenerated API reference documentation |
187 | | - - Generated on: $(date)" |
| 112 | + git add openapi-customer.json openapi-partners-public.json reference/api/ |
| 113 | + git commit -m "Auto-update API documentation and OpenAPI specs [skip ci] |
| 114 | +
|
| 115 | + - openapi-customer.json: full Customer API (powers 'API Reference' tab) |
| 116 | + - openapi-partners.json: internal source, downloaded fresh each run and |
| 117 | + kept untracked (gitignored); never published |
| 118 | + - openapi-partners-public.json: curated public Partner endpoints with MCP |
| 119 | + enabled (powers 'API Reference - Partners' tab) |
| 120 | + - Regenerated Customer API reference pages |
| 121 | + - Sources: https://api-doc.trykintsugi.com/openapi.json and |
| 122 | + https://api.trykintsugi.com/openapi.json" |
188 | 123 | git push |
189 | | - |
190 | | - echo "✅ API documentation and OpenAPI spec updated and committed" |
191 | | - |
| 124 | + echo "API documentation updated and committed." |
| 125 | +
|
192 | 126 | - name: No changes message |
193 | 127 | if: steps.changes.outputs.changed == 'false' |
194 | | - run: echo "ℹ️ No changes to API documentation" |
| 128 | + run: echo "No changes to API documentation" |
0 commit comments