Docs

Documentation / Setup

Connect your source control

Connect your GitHub, GitLab or Azure DevOps repositories to EJO; tokens, webhooks, commit statuses and the merge gate for each SCM.

Overview#

EJO works with three SCMs: GitHub, GitLab and Azure DevOps. One organization can use all three at the same time; each repository binding picks its own SCM. Once connected, EJO:

  • gives agents credentials to clone your repositories,
  • receives push, pull request (merge request on GitLab) and tag events and starts runs,
  • writes an ejo status and a comment on commits and pull requests,
  • can also enforce the merge gate on the SCM side,
  • scans SCM groups, reads .ejo files and fills the repository search in the binding form.

The three SCMs do the same jobs, but they connect differently:

GitHub GitLab Azure DevOps
How it connects The shared EJO Cloud GitHub App, Settings > GitHub App A personal access token and a project webhook A personal access token (PAT) and service hooks
Clone access Short-lived installation token limited to the repositories you pick With the token; without one, public repositories only With the PAT; without one, public repositories only
Events Arrive by themselves through the App A webhook saved under Settings > Webhooks; EJO creates it with the token or you add it by hand A webhook saved under Settings > Webhooks; EJO creates the service hooks with the PAT or you add them by hand
Status Commit statuses ejo and ejo/preview Commit statuses ejo and ejo/preview Commit and pull request statuses, genre ejo, names pipeline and preview
Comment Pull request comment Merge request note Pull request thread
Merge gate Ruleset that requires the ejo status on the target branch Pipelines must succeed (only_allow_merge_if_pipeline_succeeds) on the project Status branch policy on the target branch
Repository search in bindings Yes Yes Yes
SCM group (.ejo scan) Organization or team Group Project (org/project)
Preview label Yes Yes No, every pull request gets a preview
Required approving reviews, breaking API check Yes No No

Note: The repository search in the binding form does not query the SCM live; it comes from the last scan of your SCM groups. When you save a webhook under Settings > Webhooks, the GitHub organization, GitLab group or Azure DevOps project it covers is added as an SCM group and scanned. You can always type the name of a repository the search does not show.

GitHub#

On EJO Cloud, customers do not create a GitHub App of their own. There is one shared EJO Cloud GitHub App: you install it on your GitHub account or organization and choose which repositories it can see during the install. This flow exists for GitHub only.

Once connected:

  • Agents clone your private repositories with short-lived installation tokens limited to the repositories you picked.
  • GitHub events (push, pull request, release) reach EJO by themselves. You do not add webhooks to your repositories.
  • EJO writes the ejo status on commits, comments on pull requests and, if you want, manages a ruleset for the merge gate.

Note: Until GitHub is connected, agents can only clone public GitHub repositories and commit statuses are not posted.

Prerequisites#

  • The admin role in your EJO organization.
  • Permission to install apps on the GitHub account or organization you want to use. For organizations this is usually an organization owner.

Connect#

  1. In the console, open Settings > GitHub App.
  2. Press Install EJO on GitHub. You are sent to GitHub.
  3. Pick the account or organization to install the EJO Cloud app on.
  4. Choose All repositories or only selected repositories and confirm the install. GitHub also asks you to authorize with your account; this lets EJO check that the installation really is yours.
  5. GitHub sends you to a confirmation page on ejocloud.com: "Connect this GitHub account?" It shows the GitHub account name and the name of your EJO organization.
  6. If both are right, press Connect. You are back on Settings > GitHub App in the console with the message "GitHub App connected".

Warning: The confirmation page exists so that an install link someone else sent you cannot connect your account to the wrong organization. If you do not recognize the organization name, press Cancel. The confirmation page is valid for 10 minutes.

Requested permissions#

Permission Why
Contents (read & write) Clone the repository and let GitOps steps write commits or tags.
Commit statuses (read & write) Write the ejo and ejo/preview statuses.
Issues (read & write) Comment on pull requests with run and preview results.
Administration (read & write) Create and update the branch ruleset for the merge gate.
Pull requests (read) Read pull request details and labels.
Metadata (read) The base permission GitHub requires for every app.

The app subscribes to these events: Push, Pull request, Pull request review and Release.

Merge gate#

With Block merge until this pipeline succeeds on the binding, EJO adds a ruleset that requires the ejo status on the PR target branch. Required GitHub approving reviews is added to the same ruleset; with Also wait for the Review App URL, the ejo/preview status is required too. Private repositories on the GitHub Free plan have no rulesets, so the merge button may not be blocked; the main pipeline still stays WAITING.

Change repository access#

You can change which repositories the app sees later on GitHub, in the settings of the installed app. EJO gets its token from the current installation for every operation, so there is nothing else to do.

Disconnect#

Press Disconnect on Settings > GitHub App. This removes the EJO app from that GitHub account; webhooks and status checks stop until you install it again. If you uninstall the app on GitHub instead, EJO notices and removes the connection too.

Each EJO organization can be connected to one GitHub installation at a time. To switch accounts, disconnect the current one first.

Common errors#

Message What to do
The installation needs approval from a GitHub organization owner. A GitHub organization owner has to approve the install. Start the install again after that.
This GitHub installation is already connected to another EJO organization. Disconnect it there, or use a different GitHub account.
This EJO organization is already connected to a GitHub account. Disconnect it first. Disconnect the current connection first.
Your GitHub account has no access to that installation. Finish the install with a GitHub account that can access it.
This GitHub link is invalid or has expired. The confirmation link expired. Start again from Settings > GitHub App.

GitLab#

GitLab has no shared app. EJO connects to GitLab with a personal access token, and events arrive through project webhooks. The default GitLab address is https://gitlab.com.

Prerequisites#

  • The admin role in your EJO organization (Settings > Webhooks is open to admins).
  • A GitLab personal access token with the api and read_repository scopes. EJO uses it in clone URLs, for commit statuses, merge request notes, merge request lookup, creating webhooks and the merge gate setting.
  • The token's owner must be able to add webhooks and change project settings. GitLab requires at least the Maintainer role on the project for that.

Warning: The EJO Cloud console has no field for a GitLab token yet. The token lives in your EJO's server settings (gitlab.token); for a self-managed GitLab, its address (gitlab.base_url) is set there too. To have it set, write to us at the address on the Support page and do not put the token itself in your request. A self-managed GitLab must be reachable from EJO Cloud over the internet.

Without a token, EJO only clones public repositories; commit statuses, merge request notes, SCM group scans, reading .ejo and the merge gate do not work. Webhooks and runs still work.

Connect#

  1. On Settings > Webhooks, press New webhook.
  2. Enter a Name and pick GitLab as the Provider.
  3. Enter the project's path_with_namespace under Project, for example acme/web or acme/platform/web. On GitLab each webhook covers one project.
  4. If you leave Secret empty, EJO generates one. The secret is stored encrypted.
  5. Save with Create the hook on the SCM now ticked. With a token set, EJO adds the webhook to the project on GitLab itself.
  6. When you save, the form is replaced by the Delivery URL, the Header / secret field (X-Gitlab-Token) and the Secret. Copy the secret now; EJO will not show it again.
  7. If the hook was created automatically, you see "Created on the SCM". If not, a "Could not create the hook on the SCM" warning appears; add the webhook by hand as below.
  8. Create the binding with Delivery > Repositories > Bind repository: pick GitLab as the Provider, enter group/project under GitLab repository and pick the webhook you just saved from the Webhook secret list.

Add the webhook by hand#

On GitLab, add a webhook under the project's Settings > Webhooks:

Field Value
URL https://<your-subdomain>.ejocloud.com/api/v1/webhooks/gitlab, for example https://acme.ejocloud.com/api/v1/webhooks/gitlab
Secret token The secret EJO showed. GitLab sends it as the X-Gitlab-Token header.
Trigger Push events, Tag push events, Merge request events
SSL verification On

After saving, send a push event with Test on GitLab and check the response under Recent events.

Statuses and merge request comments#

For every run EJO writes a commit status named ejo on the commit; merge request runs with a preview also get ejo/preview, and promote and rollback runs get ejo/promote and ejo/rollback. The result of a merge request run is added to the merge request as a note and updated on every push.

Merge gate#

With Block merge until this pipeline succeeds on the binding, EJO turns on Pipelines must succeed (only_allow_merge_if_pipeline_succeeds) on the GitLab project. EJO's commit statuses show up as an external pipeline on GitLab, so the merge is blocked until ejo succeeds. The main (commit) pipeline also stays WAITING until the merge request pipeline succeeds.

  • The setting is project-wide. When you turn the merge gate off, EJO does not revert it, because it may have been on before EJO.
  • If the token lacks the api scope or the permission, the setting is not applied; the EJO-side WAITING gate still works. In that case turn on Pipelines must succeed on GitLab by hand.
  • If no token is set at all, the merge gate is rejected when you save the binding.
  • For Also wait for the Review App URL, EJO changes nothing extra on GitLab; the wait happens on the EJO side.

Common errors#

Message What to do
SCM token is not configured; copy the delivery URL and secret into the SCM UI EJO has no GitLab token. Add the webhook on GitLab by hand.
gitlab token is not configured; merge gate requires gitlab.token with api scope ... The merge gate needs a token. Keep Block merge until this pipeline succeeds off until a token is set.
gitlab token is not configured (on an SCM group) Group scans need a token.
gitlab group "..." was not found The group path is wrong, or the token's owner cannot access the group.
401 invalid webhook token under GitLab Recent events The Secret token on GitLab does not match the secret in EJO. Enter the secret again.
500 gitlab webhook secret is not configured on the master under GitLab Recent events EJO has no saved webhook for GitLab. Create one under Settings > Webhooks.
200 with no repository binding for this repo There is no binding for this project, or the repository name on the binding is not exactly the path_with_namespace.

Azure DevOps#

Azure DevOps has no shared app either. EJO connects to Azure DevOps with a personal access token (PAT), and events arrive through service hooks. EJO works with Azure DevOps Services on dev.azure.com; Azure DevOps Server running on your own servers is not supported.

Prerequisites#

  • The admin role in your EJO organization.
  • An Azure DevOps PAT. Clone and statuses need at least Code (Read) and Code (Status). For EJO to set up the merge gate's branch policies itself, grant Code (Read & write), Code (Status) and Policy (Read & write).

Warning: The EJO Cloud console has no field for an Azure DevOps PAT yet. The PAT lives in your EJO's server settings (azure_devops.pat). To have it set, write to us at the address on the Support page and do not put the PAT itself in your request.

Without a PAT, EJO only clones public repositories; commit and pull request statuses, pull request comments, SCM group scans, reading .ejo and the merge gate do not work. Webhooks and runs still work.

Connect#

  1. On Settings > Webhooks, press New webhook.
  2. Enter a Name and pick Azure DevOps as the Provider.
  3. Enter org/project (every repository in that project) or org/project/repo under Project.
  4. If you leave Secret empty, EJO generates one.
  5. Save with Create the hook on the SCM now ticked. With a PAT set, EJO creates three service hook subscriptions on the project: Code pushed, Pull request created and Pull request updated.
  6. When you save, the form is replaced by the Delivery URL, the Header / secret field (X-Ejo-Webhook-Secret) and the Secret. Copy the secret now.
  7. If the service hooks could not be created, a "Could not create the hook on the SCM" warning appears; add them by hand as below.
  8. Create the binding with Delivery > Repositories > Bind repository: pick Azure DevOps as the Provider, enter org/project/repo under Azure Repos repository and pick the webhook from the Webhook secret list.

Add the service hooks by hand#

On Azure DevOps, under Project Settings > Service hooks, create one Web Hooks subscription per event:

Field Value
Event Code pushed, Pull request created and Pull request updated (three separate subscriptions)
URL https://<your-subdomain>.ejocloud.com/api/v1/webhooks/azuredevops
HTTP headers X-Ejo-Webhook-Secret: <secret>
Resource details to send All

A completed or abandoned pull request arrives as a Pull request updated event; previews are removed on that event.

Statuses and pull request comments#

For every run EJO writes the same status on both the commit and the pull request: genre ejo, name pipeline. Pull request runs with a preview use the name preview, and promote and rollback runs use promote and rollback. The result of a pull request run is added to the pull request as a thread and updated on every push.

Merge gate#

With Block merge until this pipeline succeeds on the binding, EJO creates a blocking Status branch policy on the PR target branch: genre ejo, name pipeline. With Also wait for the Review App URL, it adds a second policy for the name preview; turning that option off deletes that policy. Turning the merge gate off deletes both policies. The main (commit) pipeline also stays WAITING until the pull request pipeline succeeds.

  • Without Policy (Read & write) on the PAT, the policy cannot be created; the EJO-side WAITING gate still works. In that case add a branch policy on the target branch that requires the status with genre ejo and name pipeline by hand.
  • If no PAT is set at all, the merge gate is rejected when you save the binding.

Common errors#

Message What to do
SCM token is not configured; copy the delivery URL and secret into the SCM UI EJO has no Azure DevOps PAT. Add the service hooks by hand.
azure devops PAT is not configured; merge gate requires azure_devops.pat ... The merge gate needs a PAT. Keep the merge gate off until a PAT is set, or add the status policy by hand.
azure devops token is not configured (on an SCM group) Project scans need a PAT.
use organization/project On Azure DevOps the SCM group name must be org/project.
azure devops project "..." was not found The project name is wrong, or the PAT cannot access the project.
401 invalid webhook secret in the service hook history The X-Ejo-Webhook-Secret header is missing or the secret does not match. Enter the header as X-Ejo-Webhook-Secret: <secret>.
500 azure devops webhook secret is not configured on the master in the service hook history EJO has no saved webhook for Azure DevOps. Create one under Settings > Webhooks.
200 with no repository binding for this repo There is no binding for this repository, or the name on the binding is not exactly org/project/repo.

Next steps#

Last updated: October 16, 2026