Une plateforme Git en un seul binaire Rust.

Dépôts, demandes de fusion avec relecture en ligne, tickets, wikis, releases, webhooks signés et un moteur de CI/CD. Un processus, un PostgreSQL, sur votre serveur.

Ouvrir FerrisGit
$docker compose up -d --build

Un seul binaire et une base de données. Aucun compte chez un tiers, aucune télémétrie envoyée nulle part. Voir comment c'est fait.

Illustration d'une demande de fusion dans FerrisGit, du push à la fusion : un push en HTTPS crée la demande, une relectrice suggère une modification sur une ligne, l'auteur l'applique en un clic, la relectrice approuve, la demande est fusionnée. La fusion déclenche le pipeline du dépôt : format et clippy s'exécutent, puis test, et les trois réussissent.

En chiffres

1
binaire Rust sert l'API REST, Git sur HTTP et l'interface web
1
PostgreSQL 18 garde chaque enregistrement ; les dépôts vivent sur le disque
5
crates Cargo, en architecture hexagonale
173
routes REST sous /api, chacune documentée
3
facteurs de connexion (TOTP, clés d'accès, codes de secours) ; la double authentification est obligatoire
2
moteurs d'exécution : runners Docker ou Pods Kubernetes

Ce que vous obtenez, tel que l'interface le montre

Chaque tuile est un morceau du vrai produit. L'interface est en français pour l'instant ; cinq langues sont prévues pour la 0.2.

src/webhooks/dispatch.rs:48 Ouvert

CA

camille · 2 min

Attente exponentielle, pour qu'un point de terminaison instable ne soit plus martelé.

Suggestion de modification

La relecture sur le diff

Un commentaire reste attaché à sa ligne. Un relecteur peut écrire une suggestion que l'auteur applique en un clic, sous forme de commit. Les approbations sont comptées, les conflits détectés.

Un pipeline à chaque push

Après chaque push, FerrisGit lit le fichier sur la branche par défaut et crée un pipeline. Les étapes sont des barrières, needs des dépendances ; les jobs tournent dans des conteneurs Docker via un petit runner, ou dans des Pods Kubernetes.

Les tickets, en liste ou en kanban

Étiquettes, jalons, assignation et quatre états. Glissez une carte pour changer son état, ou passez par le menu de la carte, au clavier.

Action Lect. Contrib. Maint.
Parcourir, cloner, lire
Pousser, ouvrir tickets et demandes, relire
Fusionner, publier, réglages, collaborateurs

Trois rôles, par dépôt ou par groupe

Un rôle donné sur un groupe s'applique à tout ce qu'il contient. Le rôle le plus élevé l'emporte.

Des webhooks signés

Douze événements sur les demandes de fusion, les tickets, les pipelines et les collaborateurs. Chaque envoi porte une signature HMAC-SHA256 de son corps brut ; le secret est chiffré au repos.

Des pages publiques, sans compte

Les visiteurs parcourent le catalogue, le README, les fichiers, les commits et les releases des dépôts publics, et les clonent. Un interrupteur d'administration éteint les pages publiques.

Double authentification, pour tout le monde

Aucun compte ne peut s'en passer. Applications d'authentification (TOTP), clés d'accès (WebAuthn) et dix codes de secours à usage unique.

La liste complète des fonctionnalités

Un push devient un pipeline

Décrivez les jobs dans .ferrisgit-ci.yml à la racine du dépôt. Après chaque push réussi, FerrisGit lit le fichier sur la branche par défaut et crée un pipeline. Basculez l'interrupteur pour voir ce que fait l'ordonnanceur quand un job échoue.

.ferrisgit-ci.yml
stages: [lint, test]

jobs:
  format:
    stage: lint
    image: rust:1
    script:
      - rustup component add rustfmt
      - cargo fmt --all -- --check

  clippy:
    stage: lint
    image: rust:1
    script:
      - rustup component add clippy
      - cargo clippy --all-targets -- -D warnings

  test:
    stage: test
    image: rust:1
    needs: [format, clippy]
    script:
      - cargo test --all-targets

Pipeline réussi

lint

formatréussi
clippyréussi

test

testréussi

format et clippy démarrent ensemble ; test déclare needs: [format, clippy] et démarre quand les deux ont réussi.

Deux façons d'exécuter un job
Runners Docker : un petit binaire ferrisgit-runner interroge le serveur et exécute chaque job dans un conteneur. Ou Kubernetes : le serveur crée un Pod par job dans votre cluster.
Les erreurs sont montrées
Un fichier présent mais invalide crée un pipeline en échec qui porte le message de l'analyseur, affiché dans l'interface.
Variables et caches
Variables CI par dépôt, chiffrées au repos en AES-256-GCM (runners Docker). Caches par job avec Kubernetes.

La référence de .ferrisgit-ci.yml

Deux minutes pour l'auto-héberger

FerrisGit est une image de conteneur avec PostgreSQL à côté. Essayez-le avec Docker Compose, installez le chart Helm sur Kubernetes, ou lancez-le depuis les sources.

Docker Compose

Démarrer la pile avec Docker Compose
git clone https://github.com/Masmarino/FerrisGit.git
cd FerrisGit
cp .env.example .env
# set POSTGRES_PASSWORD, JWT_SECRET, SETTINGS_ENCRYPTION_KEY and the admin password in .env
docker compose up -d --build

Compose construit l'image depuis les sources. Pour utiliser l'image publiée, remplacez build: . par image: masmarino/ferrisgit:0.1.1 dans docker-compose.yml.

Guide d'installation

Chart Helm

Installer le chart sur Kubernetes
git clone https://github.com/Masmarino/FerrisGit.git
cd FerrisGit
helm upgrade --install ferrisgit ./helm/ferrisgit \
  --namespace ferrisgit --create-namespace \
  --set image.tag=0.1.1 \
  --set ingress.host=git.example.com \
  --set-string ferrisgit.trustedProxyCidrs=10.42.0.0/16
kubectl -n ferrisgit rollout status deployment/ferrisgit

Laissées vides, le chart génère le mot de passe de la base, JWT_SECRET, SETTINGS_ENCRYPTION_KEY et le mot de passe du premier administrateur dans le Secret ferrisgit-secrets. La release doit s'appeler ferrisgit.

Déploiement sur Kubernetes

Depuis les sources

Lancer le backend et l'application web en local
git clone https://github.com/Masmarino/FerrisGit.git
cd FerrisGit
cp .env.example .env          # then set real secrets
./scripts/dev.sh              # PostgreSQL via Compose, cargo run on :8080, ng serve on :4201

Il faut rustup, Node.js 26, Docker avec Compose et git dans le PATH. Le script démarre PostgreSQL, applique les migrations et lance le backend sur le port 8080 et le serveur de développement Angular sur le port 4201.

Guide d'installation

Comment c'est fait

Un processus, cinq crates, une architecture hexagonale : le domaine ignore tout de la base de données, les adaptateurs ignorent tout des cas d'usage.

Architecture d'une instance FerrisGitDessin isométrique. Un client Git et un navigateur parlent à un seul binaire Rust, ferrisgit-api, composé des crates api, application, domain et infrastructure. Le binaire range ses données dans PostgreSQL et dans des dépôts Git sur disque, et exécute les jobs de pipeline soit par un ferrisgit-runner sur un hôte Docker, soit dans des Pods d'un cluster Kubernetes. Une ligne orange suit un push jusqu'à ses jobs. Sept cercles numérotés mènent aux tuiles de la page.api application domain infrastructure ferrisgit-runner ferrisgit-api : un seul binaire ferrisgit-runner Client Git HTTPS, identifiant + jeton pas encore de SSH Navigateur connecté, ou anonyme sur les pages publiques api API REST, Git en HTTP, interface web domain entités et ports, sans E/S application cas d'usage infrastructure adaptateurs : PostgreSQL, git, Docker, Kubernetes, SMTP, webhooks PostgreSQL comptes, tickets, pipelines ; migrations au démarrage Dépôts Git sur disque, wikis inclus Hôte Docker le runner interroge toutes les 5 s par défaut, un job à la fois, en conteneur Cluster Kubernetes un Pod par job, créé par le serveur git push pipeline créé jobs interroge les jobs

Fig. 1 Une instance. La ligne orange suit un push, du client jusqu'aux jobs qu'il déclenche.

  • requête ou stockage
  • un push, jusqu'à ses jobs
  • le runner interroge
  • une tuile numérotée de cette page
  1. ferrisgit-domainEntités, objets-valeurs et les ports dont le reste dépend. Aucune entrée-sortie.
  2. ferrisgit-applicationLes cas d'usage. Ne dépend que du domaine, testé contre des doublures en mémoire.
  3. ferrisgit-infrastructureAdaptateurs : PostgreSQL (sqlx), Git (gix et le binaire git), SMTP, Kubernetes, Argon2, AES-GCM, JWT.
  4. ferrisgit-apiLe serveur axum : API REST sous /api, Git smart HTTP, le bundle Angular. C'est lui, le binaire.
  5. ferrisgit-runnerLe runner Docker autonome.

Le code source sur GitHub

Sécurité et vos données

Ce qui protège une instance, nommé précisément. Les données ne quittent jamais votre serveur.

La double authentification est obligatoire
Un compte sans facteur enrôlé passe par la configuration avant de pouvoir faire quoi que ce soit d'autre. TOTP, clés d'accès et codes de secours.
Mots de passe hachés avec Argon2
Un sel par mot de passe. Un nom d'utilisateur inconnu coûte autant de calcul qu'un mot de passe faux, et reçoit la même réponse.
Secrets chiffrés en AES-256-GCM
Variables CI, secrets des webhooks, mot de passe SMTP et secrets TOTP, sous SETTINGS_ENCRYPTION_KEY.
Des jetons pour Git, jamais de mots de passe
Git sur HTTPS s'authentifie avec un jeton d'accès personnel, stocké haché : le serveur ne peut pas le relire.
Un journal d'audit
Connexions échouées, accès Git refusés, réinitialisations de mot de passe, promotions et réinitialisations de MFA par un administrateur sont enregistrées comme événements.
Pas de cookies, des en-têtes stricts
Les sessions sont des JWT. Chaque réponse porte une Content-Security-Policy, X-Frame-Options: DENY, et les routes de connexion sont limitées en débit par IP.
Vos données, sur votre serveur
PostgreSQL et un répertoire de dépôts, tous deux à vous de sauvegarder. L'image tourne avec un utilisateur sans privilège sur un système de fichiers en lecture seule.

La page Sécurité de la documentation

Où ça va

Cinq versions, aucune livrée. Un point n'est coché que lorsqu'il est livré.

  1. 0.2Branches protégées, vérifications, cinq languesPrévu
  2. 0.3Un moteur d'analyse : secrets et dépendancesPrévu
  3. 0.4Portes qualité et tableau de bordPrévu
  4. 0.5Qualité du code : métriques, règles, couverturePrévu
  5. 0.6Analyse de sécurité et ArtiFerrisPrévu

Essayez-le, puis faites tourner le vôtre.

L'instance publique montre le produit. Votre instance garde votre code.