Skip to content

adminka-root/gitea_2_sourcegraph_sync

Repository files navigation

A synchronizer for establishing a connection to a Generic Git host in order to update the list of repositories from Gitea to Sourcegraph

Introduction

Gitea is a cross-platform software development service (similar to GitHub, Bitbucket, and GitLab) that combines ease of use with low resource consumption.
Sourcegraph is a Code Intelligence platform that deeply analyzes your code—regardless of its size or hosting location—while providing a modern user interface. It is a powerful and feature-rich tool for code analysis and reuse.

This repository contains a working solution for:

  1. Creating a connection between Gitea and Sourcegraph (if one does not already exist);
  2. Automatically retrieving the list of repositories via the Gitea API;
  3. Automatically adding these repositories to the created connection.
🌟🌟🌟 HELP CALL 🌟🌟🌟
▶ APP_LANG=en ./gitea_2_sourcegraph_sync.py -h

2025-08-22 18:31:24 [info     ] *** Application gitea_2_sourcegraph_sync.py started *** func_name=<module> lineno=40
2025-08-22 18:31:24 [info     ] *** Help called for arguments ***
usage: ./gitea_2_sourcegraph_sync.py [-h] [-s PATH] [-i] [-y] [-u SEC] [-r SEC] [-c N] [-t]

 Script to update the list of Gitea repositories in Sourcegraph.
 
 Supports input parameters via UPPER env variables (overriding default
 when defining argument). For example, these commands are equivalent:
 	LOG_LEVEL=INFO ./gitea_2_sourcegraph_sync.py -u 60 -y
 	LOG_LEVEL=INFO UPDATE_TIMEOUT=60 ALWAYS_YES=TRUE ./gitea_2_sourcegraph_sync.py
 
 For more transparency (e.g., running manually inside a Docker container),
 env variable support can be disabled:
 IGNORE_ENV=TRUE ./gitea_2_sourcegraph_sync.py
 
 Logging level LOG_LEVEL (DEFAULT="INFO") is set only via env.
 Supported values: "DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL".
 
 Changing the APP_LANG locale is only done via environment variables. 
 Supported values: "en", "ru". For example: 
 	APP_LANG=ru ./gitea_2_sourcegraph_sync.py -y
 

optional arguments:
  -h, --help            show this help message and exit

Recommended parameters:
  -s PATH, --settings PATH
                        Path to the YAML file that defines script settings
                        DEFAULT=sync_settings.yml

Optional parameters:
  -i, --interactive     Show interactive input prompt in case of problems
  -y, --always_yes      Always answer YES to interactive boolean questions
  -u SEC, --update_timeout SEC
                        How often to update git connection status
                        DEFAULT=600 (every 10 minutes)
  -r SEC, --retry_timeout SEC
                        Next git connection retry interval in case of error
                        DEFAULT=30 (every 30 seconds)
  -c N, --retry_count N
                        Number of retries for git connection on network errors
                        DEFAULT=3 (number of attempts = retries + 1)
  -t, --no_term         Do not terminate the application in case of network errors 
                        that may be caused by incorrect values in the --settings 
                        configuration file (e.g., invalid domain, token, or 
                        insufficient permissions)

Adminka-root 2025. https://github.com/adminka-root

Requirements

Attention! This repository has been tested only with the following versions:

  • Docker version 24.0.5, build ced0996
  • Python 3.8 / Python 3.11
  • Gitea v1.22.1
  • Sourcegraph v6.6.868

Compatibility with other versions is not guaranteed due to possible API changes.
Bug reports are welcome!

Pull requests are also welcome. Feel free to use git rebase -i before submitting your changes. Please follow the atomic commits practice:

  • each commit should represent a logically complete change (feature, fix, refactoring);
  • the commit should clearly show what was changed and why;
  • the history should remain readable and linear.

Getting Started...

The synchronizer setup is divided into two levels:

  • External services — configuring Gitea and Sourcegraph (setting up SSH, obtaining tokens, etc.);
  • Internal environment — launching and managing via Docker Compose.

Common Bash Variables

These variables will be used in the following instructions. Make sure to adjust them according to your needs and export them in your terminal session. They are provided here for convenience in the README, but failing to initialize them in the terminal before executing further bash commands may cause issues.

gitea_domain=gitea.local
gitea_username_or_group=adminka  # for git commands (<gitea_username_or_group>/repo)
sg_repo_dest_dir="$HOME/.local/share/my_sg_dir"
sg_domain=sourcegraph.local

External Services

Setting up the integration between Gitea and Sourcegraph is primarily the responsibility of Sourcegraph developers. Unfortunately, there is no detailed documentation on this topic. Therefore, I will describe how I configured Gitea + Sourcegraph. Please note that this guide:

  1. reflects my personal experience and settings, and is not the "ultimate truth";
  2. assumes that you have a configured Gitea with SSH support (otherwise, welcome to the excellent and detailed Gitea documentation).

Deploying Sourcegraph

We follow the official deployment recommendations to set up Sourcegraph:

🌟🌟🌟 BASH 🌟🌟🌟
cd /tmp

# Clone the repository structure (git, without project data)
git clone --bare https://github.com/sourcegraph/deploy-sourcegraph-docker/

# Push to our private repository
cd deploy-sourcegraph-docker.git
git push --mirror git@${gitea_domain}:${gitea_username_or_group}/sourcegraph.git

# Remove the local clone
cd ..
rm -rf deploy-sourcegraph-docker.git

mkdir -p "${sg_repo_dest_dir}" && cd "${sg_repo_dest_dir}"

# Clone the pushed mirror repository locally
git clone git@${gitea_domain}:${gitea_username_or_group}/sourcegraph.git

# Add upstream to synchronize our clone with the original repository in the future
cd sourcegraph/
git remote add upstream https://github.com/sourcegraph/deploy-sourcegraph-docker

# Specify the version we want to install (see available branches/tags)
export SOURCEGRAPH_VERSION=v6.6.868
# Create our private branch pointing to $SOURCEGRAPH_VERSION
git checkout $SOURCEGRAPH_VERSION -b release

Next, the developers recommend configuring a docker-compose.override.yaml file, which would layer on top of the standard configuration. However, my final Sourcegraph setup contains too many custom modifications. Therefore, I preferred a more transparent approach: creating a separate file, which I ran as follows:

cd "${sg_repo_dest_dir}/sourcegraph/docker-compose"
docker compose -f my-docker-compose.yaml up
# docker compose -f my-docker-compose.yaml down

The content of my-docker-compose.yaml is not provided because it is highly context-specific for my setup. You can review Sourcegraph service architecture on an unofficial resource to determine for yourself what is needed and in what form.

🌟🌟🌟 Architecture of Services 🌟🌟🌟

Architecture of Services

Connecting Gitea to Sourcegraph

Connecting Gitea to Sourcegraph involves:

  1. Creating a shared Docker network and attaching both Gitea and Sourcegraph to it;
  2. Generating SSH keys and integrating them into Gitea and the Sourcegraph container;
  3. Defining the code host connection (Gitea) within Sourcegraph.

Creating a Shared Docker Network

Create the shared network:

docker network create --driver bridge --subnet 172.23.0.0/16 gitea_local

Define the shared network in the corresponding Docker Compose files for Gitea and Sourcegraph:

networks:  # network definition
  gitea_local:
    external: true
    name: gitea_local

Attach all Gitea and Sourcegraph services to the network:

networks: ['gitea_local']

We define an alias for Gitea, where gitea.local is your echo ${gitea_domain}:

networks:
    gitea_local: { 'aliases': ['gitea.local'] }

When creating my-docker-compose.yaml for Sourcegraph, I decided not to use Caddy and explicitly map the internal 3080 port of the sourcegraph-frontend-0 service to the host. Therefore, the alias is defined specifically on sourcegraph-frontend-0:

networks:
    gitea_local: { 'aliases': ['sourcegraph.local'] }

where sourcegraph.local is your echo ${sg_domain}.

Creating SSH Keys and Integrating Them into Gitea and gitserver-0 (Sourcegraph)

Generate the SSH keys and add them to Gitea:

cd "${sg_repo_dest_dir}" && mkdir -p gitserver && cd gitserver
ssh-keygen -t ecdsa -b 521 -C "sourcegraph@gitea.access" -f "./sourcegraph_gitea"
cat "./sourcegraph_gitea.pub"
# Copy the stdout output into the corresponding field at:
echo "https://${gitea_domain}/user/settings/keys"

Integration into Sourcegraph. Prepare the config file to connect to Gitea:

cat <<EOF > "${sg_repo_dest_dir}/gitserver/config"
Host ${gitea_domain}
  PreferredAuthentications publickey
  IdentityFile ~/.ssh/sourcegraph_gitea
  StrictHostKeyChecking accept-new
  Port 22
EOF

Changing the entrypoint and some service settings:

🌟🌟🌟 YAML 🌟🌟🌟
services:

# ... (other service definitions)

  gitserver-0:
    container_name: gitserver-0
    image: 'index.docker.io/sourcegraph/gitserver:6.6.868@sha256:304800860a46f22dafa63730e5d16c114f857a9c21353bfaf5d64a2f0502f34a'
    cpus: 1
    mem_limit: '1.5g'
    environment:
      - 'SRC_FRONTEND_INTERNAL=sourcegraph-frontend-internal:3090'
      - 'static_dir=/STATIC'
      - 'user_name=sourcegraph'
    volumes:
      - 'gitserver-0:/data/repos'
      - '../../gitserver/gitserver:/STATIC:rw'
      - '../../gitserver/su-exec.py:/usr/local/bin/su-exec:ro'
    networks:
      - gitea_local
    restart: always
    hostname: gitserver-0
    user: root
    tty: true
    entrypoint: ["/sbin/tini", "--", "/STATIC/entry.sh"]

I am not providing my custom entrypoint, but the concept is presented in the additional/gitserver folder. Review it and configure it before proceeding further.

The next step is connection testing. Verify the functionality of git clone inside the gitserver-0 container and SSH access.

🌟🌟🌟 For example 🌟🌟🌟
docker exec -it gitserver-0 su sourcegraph -c "ssh git@${gitea_domain}"
Warning: Permanently added 'gitea.local' (ED25519) to the list of known hosts.
PTY allocation request failed on channel 0
Hi there, adminka! You've successfully authenticated with the key named sourcegraph_gitea, but Gitea does not provide shell access.
If this is unexpected, please log in with password and setup Gitea under another user.
Connection to gitea.local closed.

docker exec -it gitserver-0 su sourcegraph -c "git clone git@${gitea_domain}:${gitea_username_or_group}/sourcegraph.git /tmp/sourcegraph"
Cloning into '/tmp/sourcegraph'...
remote: Enumerating objects: 12892, done.
remote: Counting objects: 100% (12892/12892), done.
remote: Compressing objects: 100% (3187/3187), done.
remote: Total 12892 (delta 9531), reused 12577 (delta 9323), pack-reused 0 (from 0)
Receiving objects: 100% (12892/12892), 2.92 MiB | 12.62 MiB/s, done.
Resolving deltas: 100% (9531/9531), done.

Defining the Host Code Connection (Gitea) in Sourcegraph

This will not be covered in this guide, as the gitea_2_sourcegraph_sync.py script will create it automatically after execution.

Obtaining Gitea and Sourcegraph Tokens

Tokens are required for the synchronizer to read the list of repositories from Gitea and update the list in Sourcegraph.

Links to create tokens in the web application will likely look like:

cat <<EOF

Gitea:       https://${gitea_domain:-?????}/user/settings/applications
Sourcegraph: https://${sg_domain:-?????}/users/adminka/settings/tokens/new
EOF

Internal Environment

Clone this repository:

cd "$HOME/.local/share" && git clone git@github.com:adminka-root/gitea_2_sourcegraph_sync.git

Build the Docker image locally if you don't want to pull it from GitHub Container Registry.

cd ~/.local/share/gitea_2_sourcegraph_sync
docker build -t gitea_2_sourcegraph_sync:latest -f ./Dockerfile .

Based on docker-compose.example.yml, create your own docker-compose.yml in the same directory (the repository root).

Set the required environment variables for:

  • Gitea connection: GITEA_URL, GITEA_API_TOKEN, GIT_SSH_URL;
  • Sourcegraph connection: SRC_ENDPOINT, SRC_ACCESS_TOKEN;
  • Defining the target host connection name in Sourcegraph: EXTERNAL_DISPLAY_NAME.

Based on sync_settings.example.yml, create your own sync_settings.yml in the same directory (docker_static/).

This file is required to adjust the list of repositories sent to Sourcegraph during synchronization: RULE_LIST_POLICY, INCLUDE_LIST – whitelist, EXCLUDE_LIST – blacklist.

🌟🌟🌟 Running the synchronizer and example output (without variables) 🌟🌟🌟
cd ~/.local/share/gitea_2_sourcegraph_sync

▶ docker compose up
[+] Running 1/0
 ✔ Container sg_sync  Created                                                                                                                  0.0s 
Attaching to sg_sync
sg_sync  | Start time: 2025-08-23 06:17:04
sg_sync  | The current image is based on Debian GNU/Linux 12 (bookworm)
sg_sync  | Python version: 3.11.13
sg_sync  | src: Current version: 6.7.0
sg_sync  | Recommended version: 6.5.0 or later
sg_sync  | 
sg_sync  | INFO Set uid to user 0 succeeded
sg_sync  | INFO supervisord started with pid 1
sg_sync  | INFO spawned: 'gitea_2_sourcegraph_sync' with pid 19
sg_sync  | [info     ] *** Application gitea_2_sourcegraph_sync.py started ***
sg_sync  | [info     ] Additional parameter validation check
sg_sync  | [info     ] Settings normalized
sg_sync  | [info     ] [START] Synchronizing repository list...
sg_sync  | [info     ] Successfully retrieved external services list
sg_sync  | [warning  ] Target git source not found in Sourcegraph matching EXTERNAL_DISPLAY_NAME
sg_sync  | [info     ] Created git repository connection
sg_sync  | [info     ] Selected git source in Sourcegraph
sg_sync  | [info     ] Successfully retrieved repositories from Gitea
sg_sync  | [info     ] Filtered repository list received
sg_sync  | [info     ] Updated git repository connection
sg_sync  | [info     ] [START END] Resynchronization in {update_timeout} seconds update_timeout=600

Check that the connection has been created and configured at the link:

echo https://${sg_domain}/site-admin/external-services
Open the created connection and make sure that synchronization is working.

Recent sync jobs

About

Effortlessly keep your Gitea repositories in sync with Sourcegraph—automatic, configurable, and reliable.

Topics

Resources

License

Stars

Watchers

Forks

Packages