sync-claude-docs
Publie le contenu Markdown de .claude/docs d'un projet vers le serveur MCP de documentation centrale (/docs/<CI_PROJECT_PATH_SLUG>/) via rsync+SSH, pour que les fichiers de contexte agent du projet soient queryables depuis tous les agents Spektrum.
Pas lié au release flow — peut être inclus seul.
Snippet d'include
include:
- component: $CI_SERVER_FQDN/spektrum/ci-templates/sync-claude-docs@<version>
inputs:
stage: deploy
stages:
- deployRemplacer <version> par un tag git du repo spektrum/ci-templates.
Inputs
| Input | Requis | Défaut | Description |
|---|---|---|---|
stage | oui | — | Stage du job. Pas de défaut : le composant ne sait pas quels stages le projet déclare. |
Trigger
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_PIPELINE_SOURCE == "web"
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
changes:
- .claude/docs/**/*Le job tourne uniquement sur la branche par défaut, dans deux cas :
- Automatiquement, sur un push branche-par-défaut qui modifie un fichier sous
.claude/docs/**/*. - Manuellement, en lançant une pipeline depuis l'UI GitLab (Build → Pipelines → "Run pipeline") ciblant la branche par défaut. Sert d'escape hatch (re-sync forcé après wipe serveur, après rotation des variables CI, etc.).
Il ne tourne jamais sur feature branches, MR pipelines ou pipelines planifiées — le serveur MCP partagé doit refléter l'état canonique (branche par défaut), pas du WIP de feature branch.
Ce que fait le job
- Installe
rsyncetopenssh-clientdans un conteneur Alpine. - Configure la clé SSH privée et
known_hostsdepuis des variables CI/CD de type File (provisionnées au niveau instance). - Lance :
rsync -avz --delete \ --include='*/' --include='*.md' --exclude='*' \ -e "ssh -p $MCP_DOCS_SSH_PORT" \ .claude/docs/ \ "$MCP_DOCS_SSH_USER@$MCP_DOCS_SSH_HOST:/docs/$CI_PROJECT_PATH_SLUG/" - Exit clean (
exit 0) si le repo n'a pas de.claude/docs/(sécurité, normalement lerules: changesempêche ce cas).
Variables CI/CD requises
Provisionnées au niveau instance GitLab — pas à configurer par projet :
| Variable | Type | Description |
|---|---|---|
MCP_DOCS_SSH_HOST | Variable | Hostname du serveur MCP (ex. mcp.internal.spektrum-suisse.ch). |
MCP_DOCS_SSH_PORT | Variable | Port SSH (ex. 2223). |
MCP_DOCS_SSH_USER | Variable | User SSH du déployeur (ex. docs-deploy). |
MCP_DOCS_SSH_KEY | File | Clé privée SSH du user de déploiement. |
MCP_DOCS_KNOWN_HOSTS | File | Sortie de ssh-keyscan pour le host MCP (skippe le prompt TOFU). |
Les deux dernières doivent être de type File (le job les consomme comme chemins, pas comme valeurs).
Layout sur le serveur
Les fichiers atterrissent sous :
/docs/<CI_PROJECT_PATH_SLUG>/
├── README.md
├── conventions/
│ └── git.md
└── runbooks/
└── deploy.mdCI_PROJECT_PATH_SLUG est le group/project slugifié par GitLab, donc chaque projet a son sous-arbre isolé — pas de risque de collision.
Notes & gotchas
--deleteest destructif côté serveur. Supprimer.claude/foo.mddu repo le supprime du serveur MCP au prochain run. C'est voulu : le but est de mirrorer le repo, pas d'accumuler.- Seul
*.mdest transféré. Les autres formats sont filtrés par les règles--include/--excludede rsync. Pour étendre, surcharger le job côté projet. - Pas de secret projet : tout est provisionné instance-wide. Le projet consommateur n'a aucun token/clé à gérer.
- Image Alpine : le
apk adddomine le startup. Si la latence CI devient un sujet sur beaucoup de projets, pré-builder une image avecrsync+openssh-clientbaked.
Voir aussi
../README.md— catalogue complet des composants.

