Metadata-Version: 2.4
Name: lcdp-back-merge
Version: 1.0.2
Summary: Cross-platform automated back-merge bot (Bitbucket / GitHub) with AI-assisted conflict resolution
Author: Le Comptoir Des Pharmacies
Author-email: webmaster@lecomptoirdespharmacies.fr
Requires-Python: >=3.9,<4.0
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Requires-Dist: anthropic (>=0.40.0)
Requires-Dist: pyjwt[crypto] (>=2.4.0)
Requires-Dist: requests (>=2.31.0,<3.0.0)
Description-Content-Type: text/markdown

# 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 :

1. Crée une branche `auto-merge/<source>-into-<target>`
2. Tente le merge ; si conflit, demande à Claude une proposition de résolution par fichier
3. Ouvre une PR avec une description riche (statut, fichiers en conflit, suggestions IA)
4. **Auto-merge** si pas de conflit OU si l'IA a résolu tous les fichiers avec confiance `high`
5. **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 `push` et `pull_request`.
> - **Bitbucket** : saute les *builds de branche* uniquement — **pas** les
>   pipelines `pull-requests:` ([BCLOUD-17676](https://jira.atlassian.com/browse/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 de
> `develop` tourne donc normalement après le merge.

## 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

```yaml
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

```yaml
- 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()`.

