Triggering a repository workflow in response to a commit on a different repository is not a trivial problem. This is particularly useful for projects that have git dependencies, where breaking changes need to be detected as soon as possible.
This project attempts to solve this problem
by providing a server that acts as an intermediary
between the repositories containing the dependencies
and the repositories that need those dependencies.
This project uses
axum to handle incoming requests,
reqwest to send requests to the GitHub API,
git ls-remote to check the last commit on a remote branch,
and sqlx connected to a SQLite database to hold state.
Usage
Setup GitHub App.
To authorize the server to trigger a workflow in your repository,
set up and install a GitHub App
with Contents set to Read and write permissions.
Then,
annotate your client id
and download your private PEM key.
Setup workflow on target repository.
Set up your GitHub Actions workflow
to be triggered by a repository_dispatch event:
on:
repository_dispatch:
types:
EVENT_TYPE is a string containing up to 100 characters.
It is used to distinguish the event
from other repository_dispatch events.
Run the server. Follow the instructions in the "Setup" and "Security" sections to install and run the server (such as via Docker, Cargo, or Nix).
Populate the database.
Populate the database with the subscriptions you need.
Usage of the Scalar UI,
accessible by navigating to /scalar on your server
(e.g., http://localhost:3000/scalar),
is preferred.
The curl command below is left as an example
on how to subscribe to a branch.
curl -X POST http://localhost:3000/subscriptions \
-H "Content-Type: application/json" \
-d '{
"source_repo_url": "SOURCE_REPOSITORY",
"source_branch_name": "BRANCH_NAME",
"target_repo": "YOUR_REPOSITORY",
"event_type": "EVENT_TYPE",
"gh_app_installation_id": YOUR_INSTALLATION_ID
}'
Make sure that EVENT_TYPE is the same
as the one defined in the workflow.
Wait for changes. At this point, the server is ready to listen to the source repository and trigger your workflow shortly after a new commit is pushed (about 5 minutes or less).
Setup
First,
create a .env file with your GitHub App configuration
or set the corresponding environment variables:
CBRIDGE__AUTH__CLIENT_ID: Your GitHub App's Client ID.CBRIDGE__AUTH__PEM_PATH: The path to your GitHub App private key.
If you have cloned the repository, you can copy the example file:
cp .env.example .env
Then, follow one of the installation options below.
[!warning]
.envfiles are only suggested for development environments. In production environments, storing the.envfile beside the server might introduce security risks. Therefore, always prefer storing configuration in system environment variables, or keeping the.envfile separated from the server.
Docker deployment
For containerized deployment,
you can use the pre-built Docker image from Docker Hub.
Create a docker-compose.yaml
by copying the example in this repository
or using the template below:
services:
commit-bridge:
image: nilirad/commit-bridge:latest
container_name: commit-bridge-server
restart: unless-stopped
ports:
- "3000:3000"
volumes:
- commit_bridge_data:/app/data
- ./YOUR_PEM_FILE.pem:/app/data/YOUR_PEM_FILE.pem:ro
env_file:
- .env
volumes:
commit_bridge_data:
Ensure that your private key file
(./YOUR_PEM_FILE.pem in the example above)
exists on the host machine before launching the container
to prevent Docker from auto-creating it as an empty directory.
Once the path is correctly mapped,
start the container:
docker compose up -d
Cargo installation
You can install and run the server directly from crates.io:
cargo install commit-bridge
Ensure git is installed (runtime dependency)
and that your environment variables or .env are configured.
Then, launch the server:
commit-bridge
Nix flake (development)
Nix is recommended
to set up the development environment.
Ensure flakes are enabled.
Just run nix develop
to enter a shell with the required environment.
If you use nix-direnv,
you can automatically enter the shell
just by entering the workspace directory with a terminal.
Launch the server using one of the following commands:
cargo run
cargo run --release
nix run
Manual setup (from source)
If you prefer not to use Nix or a container, you can build and run this server by manually configuring the environment:
- Install Rust (build-time dependency).
- Install
git(runtime dependency).
Then, launch the server:
cargo run
cargo run --release
Security
By default, this server mandates authentication for all /subscriptions endpoints.
-
Configure: Set the
CBRIDGE__AUTH__API_KEYenvironment variable to a secure value in your.envfile. -
Authenticate: Include the key in the
X-API-KEYheader for all requests:curl -X GET http://localhost:3000/subscriptions \ -H "X-API-KEY: YOUR_API_KEY"
API Key Security
To mitigate timing attacks,
the server uses constant-time comparison for API keys.
Note that while this protects against key content discovery,
an attacker may still be able to infer the length of the API key
by measuring response times.
For maximum security,
ensure that your CBRIDGE__AUTH__API_KEY is long
and generated using a cryptographically secure random source.
Disabling Authentication (Not Recommended)
[!warning] Enabling this flag allows unrestricted access to endpoints capable of triggering remote GitHub workflows. Use only in trusted development environments.
If you require an unauthenticated setup for rapid local prototyping, you can explicitly opt-in by setting the following environment variable:
CBRIDGE__AUTH__ALLOW_UNAUTHENTICATED=true
License
This repository is dual-licensed under the following, unless otherwise noted:
at your option.