Skip to content

CircleCI Integration

Status: Fully Supported | Difficulty: Easy | Time: 10 minutes

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.


Push to PR branch
|
v
OpenCodeHub detects push → triggers CircleCI pipeline via API
|
v
CircleCI runs tests/builds → reports status back to OpenCodeHub
|
v
PR checks show ✅ or ❌ → Merge queue waits for green status


  1. Go to your repository on OpenCodeHub
  2. Click SettingsIntegrationsExternal CI
  3. Click Add Integration → Select CircleCI
  4. Fill in the form:
FieldExample ValueDescription
NameCircleCI ProductionLabel for this integration
Base URLhttps://circleci.comCircleCI API base URL
API Tokencci_xxxxxxxxxxYour CircleCI Personal API Token
Project IDgh/yourorg/yourrepoCircleCI project slug (see below)
Sync Status✅ EnabledReport build status back to PRs

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.

Option A: Use a CircleCI-specific identifier

circleci/<your-org>/<your-repo>

Option B: Use VCS-style slug

gh/<org>/<repo> # If you mirror to GitHub
gl/<group>/<repo> # If you mirror to GitLab
bb/<workspace>/<repo> # If you mirror to Bitbucket

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.

Terminal window
curl -X POST https://git.yourdomain.com/api/repos/yourname/yourrepo/integrations/external-ci \
-H "Authorization: Bearer <your-opencodehub-token>" \
-H "Content-Type: application/json" \
-d '{
"provider": "circleci",
"name": "CircleCI Production",
"baseUrl": "https://circleci.com",
"apiToken": "cci_your_circleci_token",
"projectId": "circleci/my-org/my-repo",
"isEnabled": true,
"syncStatus": true
}'

After saving the integration, OpenCodeHub generates a Checks Endpoint and a Webhook Secret.

Terminal window
curl https://git.yourdomain.com/api/repos/yourname/yourrepo/external-ci \
-H "Authorization: Bearer <your-opencodehub-token>"

Response:

{
"enabled": true,
"checksEndpoint": "https://git.yourdomain.com/api/repos/yourname/yourrepo/external-ci/checks",
"status": "active"
}
Terminal window
curl -X POST https://git.yourdomain.com/api/repos/yourname/yourrepo/external-ci \
-H "Authorization: Bearer <your-opencodehub-token>" \
-H "Content-Type: application/json" \
-d '{"name": "CircleCI"}'

Response:

{
"token": "och_ext_xxxxxxxxxxxx",
"rotated": false
}

Save this token securely — you will use it in your CircleCI config to report status back.


Create or update .circleci/config.yml in your repository:

version: 2.1
jobs:
test:
docker:
- image: cimg/node:20.0
steps:
- checkout
- run:
name: Install dependencies
command: npm ci
- run:
name: Run tests
command: npm test
- run:
name: Report status to OpenCodeHub
command: |
# Send check status to OpenCodeHub
curl -X POST "${OPENCODEHUB_CHECKS_ENDPOINT}" \
-H "Authorization: Bearer ${OPENCODEHUB_TOKEN}" \
-H "Content-Type: application/json" \
-d "{
\"name\": \"circleci/test\",
\"headSha\": \"${CIRCLE_SHA1}\",
\"status\": \"completed\",
\"conclusion\": \"success\",
\"externalId\": \"${CIRCLE_WORKFLOW_ID}\",
\"detailsUrl\": \"${CIRCLE_BUILD_URL}\",
\"output\": {
\"title\": \"Tests Passed\",
\"summary\": \"All ${CIRCLE_NODE_TOTAL} test suites passed.\"
}
}"
when: on_success
- run:
name: Report failure to OpenCodeHub
command: |
curl -X POST "${OPENCODEHUB_CHECKS_ENDPOINT}" \
-H "Authorization: Bearer ${OPENCODEHUB_TOKEN}" \
-H "Content-Type: application/json" \
-d "{
\"name\": \"circleci/test\",
\"headSha\": \"${CIRCLE_SHA1}\",
\"status\": \"completed\",
\"conclusion\": \"failure\",
\"externalId\": \"${CIRCLE_WORKFLOW_ID}\",
\"detailsUrl\": \"${CIRCLE_BUILD_URL}\",
\"output\": {
\"title\": \"Tests Failed\",
\"summary\": \"Test suite failed. See build logs for details.\"
}
}"
when: on_fail
workflows:
ci:
jobs:
- test
  1. Go to your project in CircleCI dashboard
  2. Project SettingsEnvironment Variables
  3. Add:
VariableValue
OPENCODEHUB_CHECKS_ENDPOINThttps://git.yourdomain.com/api/repos/yourname/yourrepo/external-ci/checks
OPENCODEHUB_TOKENoch_ext_xxxxxxxxxxxx (from Step 2)

Step 4: Optional — CircleCI Webhook to OpenCodeHub

Section titled “Step 4: Optional — CircleCI Webhook to OpenCodeHub”

Instead of manually reporting from the config, you can set up CircleCI to send webhooks to OpenCodeHub automatically.

  1. In CircleCI, go to Project SettingsWebhooks
  2. Click Add Webhook
  3. Configuration:
    • Webhook URL: https://git.yourdomain.com/api/repos/yourname/yourrepo/external-ci/checks
    • Authorization Header: Bearer och_ext_xxxxxxxxxxxx
    • Events: Select workflow.completed and job.completed

OpenCodeHub already understands CircleCI’s native webhook payload format, so no translation layer is needed.


  1. Create a pull request on OpenCodeHub
  2. Push a commit to the PR branch
  3. OpenCodeHub will trigger CircleCI automatically
  4. CircleCI runs the pipeline
  5. Status appears on the PR as a check:
    • 🟡 Pending — build queued or running
    • 🔴 Failure — tests failed
    • 🟢 Success — all checks passed
Terminal window
curl "https://git.yourdomain.com/api/repos/yourname/yourrepo/integrations/external-ci?summary=1" \
-H "Authorization: Bearer <your-opencodehub-token>"

If you use OpenCodeHub’s merge queue, it automatically respects CircleCI status:

PR added to queue
|
v
Queue waits for CircleCI check → "success"
|
v
If check fails → PR removed from queue, author notified
|
v
If check passes → PR merged automatically

No extra configuration needed. The merge queue reads PR checks automatically.


Terminal window
curl -X POST "https://git.yourdomain.com/api/repos/yourname/yourrepo/integrations/external-ci/{config-id}/trigger" \
-H "Authorization: Bearer <your-opencodehub-token>" \
-H "Content-Type: application/json" \
-d '{
"branch": "feature/new-stuff",
"commitSha": "abc123..."
}'
Terminal window
curl -X POST "https://git.yourdomain.com/api/repos/yourname/yourrepo/integrations/external-ci/{config-id}/sync" \
-H "Authorization: Bearer <your-opencodehub-token>"
Terminal window
curl -X DELETE "https://git.yourdomain.com/api/repos/yourname/yourrepo/integrations/external-ci/{config-id}" \
-H "Authorization: Bearer <your-opencodehub-token>"

ProblemSolution
”External CI integration not configured”Verify the integration is saved and isEnabled: true. Check the repo settings.
”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.
Build triggered but no status on PRMake sure the headSha in the check payload matches the PR’s latest commit SHA.
CircleCI pipeline not triggeringVerify your CircleCI API token has permissions. Check that projectId is correct.
Webhook payload rejectedOpenCodeHub accepts native CircleCI webhooks. If using custom payloads, use the normalized format with name, headSha, and status fields.
Merge queue not waiting for CircleCIEnsure syncStatus is enabled on the integration. Check that PR checks are being created (visible in PR page).

When sending checks to /external-ci/checks, OpenCodeHub accepts these fields:

{
"name": "circleci/test",
"headSha": "abc123...",
"status": "completed",
"conclusion": "success",
"externalId": "workflow-id-123",
"detailsUrl": "https://circleci.com/gh/org/repo/123",
"output": {
"title": "Tests Passed",
"summary": "All tests passed in 2m 34s",
"text": "Optional detailed markdown output"
}
}

Status values: queued, in_progress, completed Conclusion values: success, failure, neutral, cancelled, timed_out, action_required