Skip to content

Commit 3d5d4da

Browse files
committed
docs(ci): add CircleCI integration guide — native external CI support
1 parent c65498b commit 3d5d4da

4 files changed

Lines changed: 684 additions & 0 deletions

File tree

Lines changed: 341 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,341 @@
1+
---
2+
title: "CircleCI Integration"
3+
description: "Use CircleCI as your external CI/CD provider with OpenCodeHub"
4+
---
5+
6+
> **Status:** Fully Supported | **Difficulty:** Easy | **Time:** 10 minutes
7+
8+
OpenCodeHub has **native built-in integration** with CircleCI. You don't need any custom scripts or plugins — just connect your repository to CircleCI and OpenCodeHub will automatically trigger builds, receive status updates, and block merges until CI passes.
9+
10+
---
11+
12+
## How It Works
13+
14+
```
15+
Push to PR branch
16+
|
17+
v
18+
OpenCodeHub detects push → triggers CircleCI pipeline via API
19+
|
20+
v
21+
CircleCI runs tests/builds → reports status back to OpenCodeHub
22+
|
23+
v
24+
PR checks show ✅ or ❌ → Merge queue waits for green status
25+
```
26+
27+
---
28+
29+
## Prerequisites
30+
31+
- An active [CircleCI](https://circleci.com/) account
32+
- Your repository code is on OpenCodeHub (not GitHub)
33+
- A CircleCI [Personal API Token](https://app.circleci.com/settings/user/tokens)
34+
35+
---
36+
37+
## Step 1: Configure CircleCI in OpenCodeHub
38+
39+
### Via Web UI
40+
41+
1. Go to your repository on OpenCodeHub
42+
2. Click **Settings****Integrations****External CI**
43+
3. Click **Add Integration** → Select **CircleCI**
44+
4. Fill in the form:
45+
46+
| Field | Example Value | Description |
47+
|-------|--------------|-------------|
48+
| **Name** | `CircleCI Production` | Label for this integration |
49+
| **Base URL** | `https://circleci.com` | CircleCI API base URL |
50+
| **API Token** | `cci_xxxxxxxxxx` | Your CircleCI Personal API Token |
51+
| **Project ID** | `gh/yourorg/yourrepo` | CircleCI project slug (see below) |
52+
| **Sync Status** | ✅ Enabled | Report build status back to PRs |
53+
54+
### Finding Your Project ID
55+
56+
The **Project ID** (also called "project slug") depends on where your code is hosted. Even though your code is on OpenCodeHub, CircleCI needs a project identifier.
57+
58+
**Option A: Use a CircleCI-specific identifier**
59+
```
60+
circleci/<your-org>/<your-repo>
61+
```
62+
63+
**Option B: Use VCS-style slug**
64+
```
65+
gh/<org>/<repo> # If you mirror to GitHub
66+
gl/<group>/<repo> # If you mirror to GitLab
67+
bb/<workspace>/<repo> # If you mirror to Bitbucket
68+
```
69+
70+
> **Note:** If you don't mirror to GitHub/GitLab, you can still use CircleCI by setting up a "standalone" project. Use any unique slug like `circleci/my-team/my-project`.
71+
72+
### Via API
73+
74+
```bash
75+
curl -X POST https://git.yourdomain.com/api/repos/yourname/yourrepo/integrations/external-ci \
76+
-H "Authorization: Bearer <your-opencodehub-token>" \
77+
-H "Content-Type: application/json" \
78+
-d '{
79+
"provider": "circleci",
80+
"name": "CircleCI Production",
81+
"baseUrl": "https://circleci.com",
82+
"apiToken": "cci_your_circleci_token",
83+
"projectId": "circleci/my-org/my-repo",
84+
"isEnabled": true,
85+
"syncStatus": true
86+
}'
87+
```
88+
89+
---
90+
91+
## Step 2: Set Up the Checks Endpoint
92+
93+
After saving the integration, OpenCodeHub generates a **Checks Endpoint** and a **Webhook Secret**.
94+
95+
### Get Your Endpoint
96+
97+
```bash
98+
curl https://git.yourdomain.com/api/repos/yourname/yourrepo/external-ci \
99+
-H "Authorization: Bearer <your-opencodehub-token>"
100+
```
101+
102+
Response:
103+
```json
104+
{
105+
"enabled": true,
106+
"checksEndpoint": "https://git.yourdomain.com/api/repos/yourname/yourrepo/external-ci/checks",
107+
"status": "active"
108+
}
109+
```
110+
111+
### Generate/Rotate Token
112+
113+
```bash
114+
curl -X POST https://git.yourdomain.com/api/repos/yourname/yourrepo/external-ci \
115+
-H "Authorization: Bearer <your-opencodehub-token>" \
116+
-H "Content-Type: application/json" \
117+
-d '{"name": "CircleCI"}'
118+
```
119+
120+
Response:
121+
```json
122+
{
123+
"token": "och_ext_xxxxxxxxxxxx",
124+
"rotated": false
125+
}
126+
```
127+
128+
> **Save this token securely** — you will use it in your CircleCI config to report status back.
129+
130+
---
131+
132+
## Step 3: Configure Your CircleCI Pipeline
133+
134+
Create or update `.circleci/config.yml` in your repository:
135+
136+
```yaml
137+
version: 2.1
138+
139+
jobs:
140+
test:
141+
docker:
142+
- image: cimg/node:20.0
143+
steps:
144+
- checkout
145+
- run:
146+
name: Install dependencies
147+
command: npm ci
148+
- run:
149+
name: Run tests
150+
command: npm test
151+
- run:
152+
name: Report status to OpenCodeHub
153+
command: |
154+
# Send check status to OpenCodeHub
155+
curl -X POST "${OPENCODEHUB_CHECKS_ENDPOINT}" \
156+
-H "Authorization: Bearer ${OPENCODEHUB_TOKEN}" \
157+
-H "Content-Type: application/json" \
158+
-d "{
159+
\"name\": \"circleci/test\",
160+
\"headSha\": \"${CIRCLE_SHA1}\",
161+
\"status\": \"completed\",
162+
\"conclusion\": \"success\",
163+
\"externalId\": \"${CIRCLE_WORKFLOW_ID}\",
164+
\"detailsUrl\": \"${CIRCLE_BUILD_URL}\",
165+
\"output\": {
166+
\"title\": \"Tests Passed\",
167+
\"summary\": \"All ${CIRCLE_NODE_TOTAL} test suites passed.\"
168+
}
169+
}"
170+
when: on_success
171+
172+
- run:
173+
name: Report failure to OpenCodeHub
174+
command: |
175+
curl -X POST "${OPENCODEHUB_CHECKS_ENDPOINT}" \
176+
-H "Authorization: Bearer ${OPENCODEHUB_TOKEN}" \
177+
-H "Content-Type: application/json" \
178+
-d "{
179+
\"name\": \"circleci/test\",
180+
\"headSha\": \"${CIRCLE_SHA1}\",
181+
\"status\": \"completed\",
182+
\"conclusion\": \"failure\",
183+
\"externalId\": \"${CIRCLE_WORKFLOW_ID}\",
184+
\"detailsUrl\": \"${CIRCLE_BUILD_URL}\",
185+
\"output\": {
186+
\"title\": \"Tests Failed\",
187+
\"summary\": \"Test suite failed. See build logs for details.\"
188+
}
189+
}"
190+
when: on_fail
191+
192+
workflows:
193+
ci:
194+
jobs:
195+
- test
196+
```
197+
198+
### Set Environment Variables in CircleCI
199+
200+
1. Go to your project in CircleCI dashboard
201+
2. **Project Settings** → **Environment Variables**
202+
3. Add:
203+
204+
| Variable | Value |
205+
|----------|-------|
206+
| `OPENCODEHUB_CHECKS_ENDPOINT` | `https://git.yourdomain.com/api/repos/yourname/yourrepo/external-ci/checks` |
207+
| `OPENCODEHUB_TOKEN` | `och_ext_xxxxxxxxxxxx` (from Step 2) |
208+
209+
---
210+
211+
## Step 4: Optional — CircleCI Webhook to OpenCodeHub
212+
213+
Instead of manually reporting from the config, you can set up CircleCI to send webhooks to OpenCodeHub automatically.
214+
215+
### Using CircleCI Webhooks (Recommended)
216+
217+
1. In CircleCI, go to **Project Settings** → **Webhooks**
218+
2. Click **Add Webhook**
219+
3. Configuration:
220+
- **Webhook URL**: `https://git.yourdomain.com/api/repos/yourname/yourrepo/external-ci/checks`
221+
- **Authorization Header**: `Bearer och_ext_xxxxxxxxxxxx`
222+
- **Events**: Select `workflow.completed` and `job.completed`
223+
224+
OpenCodeHub already understands CircleCI's native webhook payload format, so no translation layer is needed.
225+
226+
---
227+
228+
## Step 5: Test the Integration
229+
230+
1. Create a pull request on OpenCodeHub
231+
2. Push a commit to the PR branch
232+
3. OpenCodeHub will trigger CircleCI automatically
233+
4. CircleCI runs the pipeline
234+
5. Status appears on the PR as a check:
235+
- 🟡 **Pending** — build queued or running
236+
- 🔴 **Failure** — tests failed
237+
- 🟢 **Success** — all checks passed
238+
239+
### View Build History
240+
241+
```bash
242+
curl "https://git.yourdomain.com/api/repos/yourname/yourrepo/integrations/external-ci?summary=1" \
243+
-H "Authorization: Bearer <your-opencodehub-token>"
244+
```
245+
246+
---
247+
248+
## Merge Queue + CircleCI
249+
250+
If you use OpenCodeHub's [merge queue](/features/merge-queue/), it automatically respects CircleCI status:
251+
252+
```
253+
PR added to queue
254+
|
255+
v
256+
Queue waits for CircleCI check → "success"
257+
|
258+
v
259+
If check fails → PR removed from queue, author notified
260+
|
261+
v
262+
If check passes → PR merged automatically
263+
```
264+
265+
No extra configuration needed. The merge queue reads PR checks automatically.
266+
267+
---
268+
269+
## API Reference
270+
271+
### Trigger Build Manually
272+
273+
```bash
274+
curl -X POST "https://git.yourdomain.com/api/repos/yourname/yourrepo/integrations/external-ci/{config-id}/trigger" \
275+
-H "Authorization: Bearer <your-opencodehub-token>" \
276+
-H "Content-Type: application/json" \
277+
-d '{
278+
"branch": "feature/new-stuff",
279+
"commitSha": "abc123..."
280+
}'
281+
```
282+
283+
### Sync Build Status
284+
285+
```bash
286+
curl -X POST "https://git.yourdomain.com/api/repos/yourname/yourrepo/integrations/external-ci/{config-id}/sync" \
287+
-H "Authorization: Bearer <your-opencodehub-token>"
288+
```
289+
290+
### Delete Integration
291+
292+
```bash
293+
curl -X DELETE "https://git.yourdomain.com/api/repos/yourname/yourrepo/integrations/external-ci/{config-id}" \
294+
-H "Authorization: Bearer <your-opencodehub-token>"
295+
```
296+
297+
---
298+
299+
## Troubleshooting
300+
301+
| Problem | Solution |
302+
|---------|----------|
303+
| **"External CI integration not configured"** | Verify the integration is saved and `isEnabled: true`. Check the repo settings. |
304+
| **"Invalid external CI token"** | The token used in the `Authorization` header doesn't match. Rotate the token in repo settings and update CircleCI env vars. |
305+
| **Build triggered but no status on PR** | Make sure the `headSha` in the check payload matches the PR's latest commit SHA. |
306+
| **CircleCI pipeline not triggering** | Verify your CircleCI API token has permissions. Check that `projectId` is correct. |
307+
| **Webhook payload rejected** | OpenCodeHub accepts native CircleCI webhooks. If using custom payloads, use the normalized format with `name`, `headSha`, and `status` fields. |
308+
| **Merge queue not waiting for CircleCI** | Ensure `syncStatus` is enabled on the integration. Check that PR checks are being created (visible in PR page). |
309+
310+
---
311+
312+
## Supported CircleCI Payload Fields
313+
314+
When sending checks to `/external-ci/checks`, OpenCodeHub accepts these fields:
315+
316+
```json
317+
{
318+
"name": "circleci/test",
319+
"headSha": "abc123...",
320+
"status": "completed",
321+
"conclusion": "success",
322+
"externalId": "workflow-id-123",
323+
"detailsUrl": "https://circleci.com/gh/org/repo/123",
324+
"output": {
325+
"title": "Tests Passed",
326+
"summary": "All tests passed in 2m 34s",
327+
"text": "Optional detailed markdown output"
328+
}
329+
}
330+
```
331+
332+
**Status values:** `queued`, `in_progress`, `completed`
333+
**Conclusion values:** `success`, `failure`, `neutral`, `cancelled`, `timed_out`, `action_required`
334+
335+
---
336+
337+
## Next Steps
338+
339+
- [Set up Merge Queue](/features/merge-queue/)
340+
- [Configure Branch Protection](/guides/branch-protection/)
341+
- [Add more external CI providers](/guides/external-ci/) (GitLab CI, Jenkins, Buildkite)

docs-site/src/content/docs/index.mdx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,10 @@ OpenCodeHub is built on a modern, scalable architecture designed for performance
9090
Get OpenCodeHub running in minutes with Docker or Node.js. [Read the guide
9191
](/getting-started/installation/)
9292
</Card>
93+
<Card title="CircleCI Integration" icon="seti:check">
94+
Connect CircleCI as your external CI provider. Trigger builds and report
95+
PR checks automatically. [Set up CircleCI →](/guides/circleci-integration/)
96+
</Card>
9397
<Card title="CLI Reference" icon="seti:shell">
9498
Learn the `och` CLI commands for managing stacks and repositories. [View
9599
commands →](/reference/cli-commands/)

0 commit comments

Comments
 (0)