lcdp-back-merge
Bot de back-merge automatique multi-plateforme (Bitbucket Cloud / GitHub) avec résolution IA des conflits.
Quoi ça fait
Pour chaque branche divergente de la branche source courante :
- Crée une branche
auto-merge/<source>-into-<target> - Tente le merge ; si conflit, demande à Claude une proposition de résolution par fichier
- Ouvre une PR avec une description riche (statut, fichiers en conflit, suggestions IA)
- Auto-merge si pas de conflit OU si l'IA a résolu tous les fichiers avec confiance
high - Notifie Slack sinon (review requise)
Les commits créés par le bot sur la branche
auto-merge/*portent[skip ci]pour éviter une CI redondante sur cette branche éphémère :
- GitHub Actions : saute les workflows sur
pushetpull_request.- Bitbucket : saute les builds de branche uniquement — pas les pipelines
pull-requests:(BCLOUD-17676, limite Bitbucket sans contournement).Sans effet sur la branche de destination : le bot merge en vrai merge commit (
merge_commit/merge), dont le message ne contient pas le tag. La CI dedeveloptourne donc normalement après le merge.
Auto-merge et mergeabilité asynchrone (GitHub). GitHub calcule
mergeableaprès coup : une PR qui vient d'être créée renvoienull, et unPUT /mergeimmédiat est rejeté en405 Base branch was modified. Le bot attend donc quemergeablesoit tranché avant de merger, et retente un 405/409 sur le merge lui-même. Unmergeable: falseest un verdict — conflit réel, pas de retry. Sans cette attente, l'auto-merge perdait la course et laissait la PR ouverte avec un simple WARN : surlcdp-inventorist-app, le back-merge de v2.2.0 est resté ouvert sept semaines et a fait échouer la release v2.2.1 sur le conflit correspondant. Corollaire : ce WARN reste le seul signal siSLACK_WEBHOOK_URLn'est pas fourni — le passer aux jobs qui lancent le bot.
Tests
poetry install --with dev
poetry run pytest tests
Configuration
Variables d'environnement requises
| Variable | Plateforme | Description |
|---|---|---|
BB_AUTH_STRING |
Bitbucket | client_id:client_secret OAuth pour l'API Bitbucket |
GITHUB_APP_ID |
GitHub | App ID du GitHub App (auth App uniquement, pas de PAT) |
GITHUB_APP_PRIVATE_KEY |
GitHub | Clé privée PEM du GitHub App. Permissions requises : contents:write + pull-requests:write |
La plateforme est détectée automatiquement via les variables CI standard (BITBUCKET_BRANCH, GITHUB_ACTIONS).
GitHub : l'auth se fait exclusivement via GitHub App (le script génère lui-même un installation token court). L'App doit être installée sur le repo cible.
Variables d'environnement optionnelles
| Variable | Défaut | Description |
|---|---|---|
ANTHROPIC_API_KEY |
— | Active la résolution IA des conflits |
ANTHROPIC_MODEL |
claude-sonnet-4-6 |
Modèle Claude utilisé pour la résolution |
SLACK_WEBHOOK_URL |
— | Active les notifications Slack |
AUTO_MERGE_TARGET_PATTERNS |
(toutes) | Globs séparés par virgule : develop,release/* |
AUTO_MERGE_BRANCH_MAP |
— | Mapping source→patterns : master:develop;develop:feature/* |
AUTO_MERGE_DEFAULT_REVIEWERS |
— | Reviewers fallback en CSV (UUIDs Bitbucket ou logins GitHub) |
AUTO_MERGE_PR_RUN_LIMIT |
-1 (illimité) | Nombre max de PR créées par run |
Utilisation en pipeline
Bitbucket Pipelines
branches:
"{master}":
- step:
name: Back merge
# image uv officielle (debian bookworm) → uv + git déjà présents
image: ghcr.io/astral-sh/uv:python3.11-bookworm
clone:
depth: full # toutes les branches divergentes
script:
- export AUTO_MERGE_TARGET_PATTERNS="develop"
- uvx lcdp-back-merge
# Variables (repository/deployment) : BB_AUTH_STRING, ANTHROPIC_API_KEY, SLACK_WEBHOOK_URL
GitHub Actions
- uses: actions/checkout@v4
with:
fetch-depth: 0 # toutes les branches divergentes
persist-credentials: false # le script gère l'auth git via le token App
- uses: astral-sh/setup-uv@v5
- name: Back-merge
run: uvx lcdp-back-merge
env:
# Noms des secrets GitHub explicites (à gauche = ce que lit le script,
# à droite = le secret/variable côté repo, nommé sans ambiguïté).
GITHUB_APP_ID: ${{ vars.LCDP_BACKMERGE_APP_ID }}
GITHUB_APP_PRIVATE_KEY: ${{ secrets.LCDP_BACKMERGE_APP_PRIVATE_KEY }}
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
Architecture
lcdp_back_merge/
├── cli.py # argparse, entry point
├── runner.py # boucle principale, orchestration
├── ai_resolver.py # résolution de conflits via Claude
├── slack.py # notifications Slack
├── git_utils.py # wrappers subprocess git
└── platforms/
├── base.py # abstract Platform
├── bitbucket.py # adaptateur Bitbucket Cloud
└── github.py # adaptateur GitHub
Ajouter une plateforme = ajouter une sous-classe de Platform dans platforms/, l'enregistrer dans platforms.__init__.detect_platform().
Release files for lcdp-back-merge 1.0.4
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| lcdp_back_merge-1.0.4.tar.gz | 22.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| lcdp_back_merge-1.0.4-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 49.8 kB
Release files / lcdp_back_merge-1.0.4.tar.gz
| Download URL | lcdp_back_merge-1.0.4.tar.gz |
|---|---|
| Size | 22.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7b1a883da7d3f564140dedeb70e0bdbe7832a750b489802275defcf24ecb32da
|
|
BLAKE2b-256 checksum How to use checksums |
b9edb95dfab5904e85ff19ac9fc14791c3efef05e8c234d6fad4cf95faae9d19
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/2.4.1 CPython/3.12.3 Linux/6.18.35
|
Release files / lcdp_back_merge-1.0.4-py3-none-any.whl
| Download URL | lcdp_back_merge-1.0.4-py3-none-any.whl |
|---|---|
| Size | 26.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a58ee4199e10bad5443cff29eca6ed15b3d583ff99f101c8dc81a3dab4b1c446
|
|
BLAKE2b-256 checksum How to use checksums |
0992596094a86f1e95d77ac7765bad416ecc964d4f879a5b4a1a0a1da1057c1b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/2.4.1 CPython/3.12.3 Linux/6.18.35
|