grove
Documentation menu

Code hosts

Grove discovers repositories through the APIs of GitHub, GitLab and Bitbucket Server. Connect as many hosts as you like and mix providers: a GitHub organization, a self-hosted GitLab and a Bitbucket Server can share one Grove instance.

Adding a connection

As a superuser, go to Settings → Code hosts, click Add code host and pick the provider. Edit the JSON configuration (the editor validates it as you type) and save. Grove syncs right away and again every RESYNC_INTERVAL minutes (30 by default); Sync now starts a sync on demand.

Tokens are encrypted with SECRET_KEY before they’re stored. When you edit a host later, a stored token shows as <REDACTED> and is kept unless you replace it.

A GitHub code host with its JSON configuration and sync statusA GitHub code host with its JSON configuration and sync status

GitHub

Personal access token

Create a token at GitHub → Settings → Developer settings → Personal access tokens → Fine-grained tokens (or classic tokens). The minimum scopes required are:

  • Contents — read (to clone repositories)
  • Metadata — read (to list repositories)

The token must be able to see every repository you want indexed; for a fine-grained token, set its resource owner to the organisation.

{
	"url": "https://github.com",
	"authToken": "github_pat_…",
	"organisations": ["myorg"],
	"projectQueries": ["otherorg/some-repo"]
}

Config fields

Field Required Description
url Yes https://github.com, or your GitHub Enterprise Server URL
apiURL No API base URL, for GitHub Enterprise Server installations with a non-standard API path
authToken Yes Personal access token
organisations No Index every repository in these organisations
projectQueries No Individual repositories to index, as exact owner/repo paths
excludes No owner/repo patterns to skip (see Excluding repositories)

GitHub Enterprise Server

Point url at your GHES instance and optionally set apiURL if your API lives at a non-standard path:

{
	"url": "https://github.example.com",
	"apiURL": "https://github.example.com/api/v3",
	"authToken": "ghp_…",
	"projectQueries": ["myorg/myrepo"]
}

GitLab

Personal access token

Create a token at GitLab → User settings → Access tokens. Required scopes:

  • read_api — to list groups and projects
  • read_repository — to clone repositories
{
	"gitlabURL": "https://gitlab.com",
	"authToken": "glpat-…",
	"groups": ["mygroup"],
	"projects": ["mygroup/myproject"]
}

Config fields

Field Required Description
gitlabURL Yes https://gitlab.com or your self-hosted GitLab URL
authToken Yes Personal access token
groups No Sync all projects in these groups (including subgroups)
projects No Sync specific projects by namespace/path
excludes No namespace/path patterns to skip

Projects without a default branch (empty projects) are skipped. To skip a group’s subgroups, append ?include_subgroups=false to its name, e.g. "mygroup?include_subgroups=false".

Token rotation

Grove automatically rotates expiring GitLab personal access tokens. When a token has an expiry date, Grove schedules rotation ahead of it (35 days before for tokens expiring in more than 2 months; 7 days before otherwise). The rotated token is persisted back to the database — no manual intervention needed.

Token rotation requires the token to have been created as a personal access token (not a project or group token), and the GitLab instance must support the /api/v4/personal_access_tokens/self/rotate endpoint (GitLab 16.0+).

Self-hosted GitLab

Point gitlabURL at your instance:

{
	"gitlabURL": "https://gitlab.example.com",
	"authToken": "glpat-…",
	"groups": ["platform-team"]
}

Bitbucket

Grove supports Bitbucket Server / Data Center.

Personal access token

Create a token under Manage account → Personal access tokens with Repository read permission.

{
	"baseURL": "https://bitbucket.example.com",
	"username": "myusername",
	"authToken": "…",
	"projects": ["PLATFORM"],
	"repos": ["TOOLS/deploy-scripts"]
}

Config fields

Field Required Description
baseURL Yes Your Bitbucket Server URL
username Yes Your Bitbucket username (used for cloning)
authToken Yes Personal access token
projects No Index every repository in these projects, by project key
repos No Individual repositories to index, as PROJECTKEY/slug
excludes No PROJECTKEY/slug patterns to skip

If neither projects nor repos is set, Grove indexes every repository the token can access.


Excluding repositories

All three providers support an excludes field. Each entry is matched against the repository’s full path (owner/repo on GitHub, namespace/path on GitLab, PROJECTKEY/slug on Bitbucket). Entries can be exact paths or wildcard patterns, where * matches any characters except /:

{
	"excludes": ["myorg/legacy-monolith", "myorg/sandbox-*"]
}

Patterns use glob syntax, so myorg/sandbox-* matches every repository with that prefix.

Removed and archived repositories

Archived repositories are indexed but left out of search results unless a query says archived:yes or archived:only. Repositories that disappear from a code host, or that a new exclude matches, are marked as deleted (see the Deleted filter under Settings → Repositories). Set ENABLE_REPO_DELETION=true to have Grove remove them, including their mirrors and indices.

Fetch schedule

After the first clone, Grove fetches each repository on its own schedule, more often for repositories that change often. Settings → Repositories shows the last and next fetch for each one and lets you fetch or reindex a repository right away.