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 |
AUTO_MERGE_SOURCE_BRANCH |
branche CI | Branche à back-merger, à la place de celle qui a déclenché la CI |
GitHub : ne pas surcharger
GITHUB_*pour changer la source. Actions ignore en silence unenv: GITHUB_REF_NAME: mainposé sur un step. Un workflow lancé depuisrelease/vXqui doit back-mergermainposeAUTO_MERGE_SOURCE_BRANCH: main. Le log de démarrage affiche la source effective et la variable lue :Source branch: main (from AUTO_MERGE_SOURCE_BRANCH).
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.5
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.5.tar.gz | 23.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| lcdp_back_merge-1.0.5-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 51.0 kB
Release files / lcdp_back_merge-1.0.5.tar.gz
| Download URL | lcdp_back_merge-1.0.5.tar.gz |
|---|---|
| Size | 23.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
0f907350306bb4f24b00089bf46ae34cd78bc009b38103e77beda72503a9ebda
|
|
BLAKE2b-256 checksum How to use checksums |
5551db214402d4a05dea95fccaf7c1f03fe57dce25ac24b89bdc4c91120b32d7
|
| 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.5-py3-none-any.whl
| Download URL | lcdp_back_merge-1.0.5-py3-none-any.whl |
|---|---|
| Size | 27.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
6a7473da6ff38d1c4c15aaeed3f4b7d52e3201a1ebb162403682213c85c8d17b
|
|
BLAKE2b-256 checksum How to use checksums |
002b36bb0e932f1e26d68eaa2cbc6ca2fc42d582f8b43ac49eb1f56e867ede14
|
| 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
|