> ## Documentation Index
> Fetch the complete documentation index at: https://api-documentation.kare-app.fr/llms.txt
> Use this file to discover all available pages before exploring further.

# Branches, versions, release prod

> Modèle de branches, tags semver, contrat de mise en production

## Les branches

Une seule branche durable : **`main`**. Branches courtes (`feat/...`, `fix/...`), PR, merge, la
branche meurt. Pas de branche `release` : on déploie une **image**, pas une branche.

## Les versions

Un tag semver posé sur un commit de `main` fige une photo du **repo entier**.

```
v1.4.0
 │ │ └── correctif : bugfix
 │ └──── mineur    : fonctionnalité
 └────── majeur    : rupture de compatibilité
```

**Versionner n'est pas déployer.** Le tag photographie tout le repo ; le déploiement choisit une
cible. Chaque composant peut donc tourner une version différente — c'est normal et tracé par les tags
d'image SHA7.

## État de prod

<Warning>
  `prod` n'existe pas encore. `release.yml` et `hotfix.yml` sont en place et définissent le contrat,
  mais les scripts partagés n'acceptent que `SUPPORTED_STAGES="staging"` et `infrastructure/` n'a pas de
  racine prod. Un run prod échouera tant que le stage n'a pas été cloné : nouveau state, nouveaux
  credentials, domaines, sizing et propriété des secrets.
</Warning>

Quand prod existera, sa topologie de départ est plus petite que staging : trois audiences API
(`rs`, `bo`, `ad`) et les fronts `backoffice` et `audit`. Le target `all` de prod exclut donc `api-pr`,
`kare` et `provider`, et les cibler explicitement est rejeté.

## Release

**Actions → Release (prod) → Run workflow**.

| Entrée    | Valeur                                                                                |
| --------- | ------------------------------------------------------------------------------------- |
| `version` | semver sans `v`, par exemple `1.4.0`                                                  |
| `target`  | `all`, `api`, `api-{rs,bo,ad}`, `front-{backoffice,audit}`, `pair-{backoffice,audit}` |

```mermaid theme={null}
flowchart LR
    V["validate<br/>branche main, format semver,<br/>tags accessibles"] --> D["deploy-stack<br/>stage=prod, ref=SHA courant"]
    D --> T["tag v1.4.0 + GitHub Release"]
```

**Le tag est posé en dernier**, après un verdict sain. Une release échouée ou annulée reste donc
rejouable, et aucune version orpheline ne revendique du code qui n'est jamais arrivé en production.
L'approbation humaine vient de l'environment GitHub `prod` (required reviewers) : chaque job du stack
qui touche prod le déclare.

## Hotfix

Pour ne pousser **que** le correctif, on part du code en prod, pas de `main`.

| Entrée    | Valeur                                                           |
| --------- | ---------------------------------------------------------------- |
| `version` | semver du patch, par exemple `1.4.1`                             |
| `ref`     | branche ou SHA **complet de 40 caractères** à déployer et tagger |
| `target`  | même liste que la release                                        |

```mermaid theme={null}
flowchart LR
    A["main : commits pas prêts"]
    B["tag v1.4.0 en prod"] --> C["branche hotfix + fix"]
    C --> D["hotfix.yml → deploy → tag v1.4.1"]
    D --> E["PR de report sur main (obligatoire)"]
```

`validate` résout le ref en un SHA immuable unique, déploie ce SHA, puis tague après succès. Le report
sur `main` est obligatoire : sans lui, la prochaine release écrase le correctif.

## Rollback

Le rollback ne rejoue pas un build : il repointe un container sur une **image déjà construite**. Voir
[Déployer](/devops/deploy#rollback) — aujourd'hui `rollback.yml` est staging uniquement.

<Warning>
  Le rollback ne reverte **jamais** la base. C'est la raison de la règle expand/contract :
  [Migrations](/devops/migrations).
</Warning>
