ordinarthur fc66775109 feat(claude-code): skill /push pour release automatisée
Le ritual de release Rubis demande de bumper `apps/web/src/version.ts`
et d'ajouter `apps/landing/src/content/changelog/<x.y.z>.md` dans le
*même* commit — sinon le toast SPA pointe sur une ancre absente côté
`/changelog`. Ce skill orchestre les deux pour éliminer la classe entière
des releases désynchronisées.

Workflow :
 1. `git status` + `git diff` pour inspecter les changements pendants
 2. Détection heuristique du type (feature/improvement/fix) → bump
    semver correspondant (minor pour feature, patch sinon)
 3. AskUserQuestion pour titre + highlights (au ton brand : produit-only,
    pas de jargon tech, une phrase d'attitude max)
 4. Edit `version.ts` + Write nouveau `.md` avec frontmatter Zod-validé
 5. Stage + commit Conventional Commits (scope `release`)
 6. Push gitea/main

Edge cases couverts : aucun changement à committer, branche ≠ main,
build cassé pré-existant (ne bloque pas la release, juste flag), conflits
remote, hook pre-commit échoue (jamais d'amend / no-verify), version
déjà utilisée, versionnage incohérent entre `version.ts` et le dossier
changelog.

Trigger : `/push`, "release ça", "sors une nouvelle version", "push avec
changelog", "deploy" (sauf si l'user dit explicitement "sans bump").

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-11 00:49:39 +02:00

8.8 KiB

name, description, allowed-tools
name description allowed-tools
push Release automatisée Rubis : bump de version, ajout d'une entrée changelog, commit conventionnel et push. À utiliser quand l'utilisateur tape `/push` ou demande explicitement de déployer / sortir une nouvelle version / pousser les changements. Le skill orchestre les fichiers couplés (`apps/web/src/version.ts` + `apps/landing/src/content/changelog/<x.y.z>.md`) pour éviter de pusher une version SPA dont le toast pointe sur une ancre absente.
Bash
Read
Write
Edit

/push — Release automatisée Rubis

Ce skill exécute le ritual de release complet du repo Rubis :

  1. Inspection des changements en attente (git status + git diff)
  2. Détermination du type de release (feature / improvement / fix)
  3. Bump semver de APP_VERSION dans apps/web/src/version.ts
  4. Création de apps/landing/src/content/changelog/<new-version>.md
  5. Stage + commit avec message conventionnel (scope + body)
  6. Push sur gitea/main

Le double-fichier version.ts + <version>.md doit atterrir dans le même commit, sinon le toast SPA <VersionToast/> pointera sur une ancre absente côté /changelog. C'est précisément pour éviter cette désynchronisation qu'on a un skill dédié.

Quand utiliser ce skill

Déclenche-toi automatiquement quand :

  • L'utilisateur tape /push
  • L'utilisateur demande "sors une nouvelle version", "release ça", "push avec changelog", "deploy"
  • L'utilisateur dit "commit + bump" ou variantes

Ne déclenche PAS ce skill quand :

  • L'utilisateur veut juste un commit local sans push (/commit)
  • L'utilisateur veut push une branche autre que main
  • L'utilisateur dit explicitement "sans bump" ou "pas de release" → fais un commit + push standard à la place

Step 1 — Inspecter les changements

git status --short
git diff --stat HEAD
git log --oneline -5  # pour le style de commit message

Lis aussi apps/web/src/version.ts pour récupérer la version courante :

grep -E '^export const APP_VERSION' apps/web/src/version.ts

Extrais le semver (X.Y.Z).

Si aucun changement (git status --short vide) → stop, dis à l'utilisateur "Rien à committer". Ne crée pas une release vide.

Si la branche n'est pas main → demande confirmation avant de continuer (git branch --show-current). Si l'utilisateur est sur une branche feature, peut-être qu'il veut juste commit, pas release.

Step 2 — Déterminer le type de release

Analyse les diffs et propose un type. Heuristiques :

Signal dans les diffs Type suggéré Bump
Nouveau fichier de feature (component, route, page) feature minor (X.Y.0 → X.Y+1.0)
Modif comportement utilisateur observable, nouvelle interaction feature minor
Amélioration UI/UX, refactor visible, perf improvement patch (X.Y.Z → X.Y.Z+1)
Correction d'un bug fix patch
Modif uniquement docs (/docs/, *.md hors changelog) ou tests → suggère de skip le bump
Modif uniquement assets/marketing (/docs/*.html, images) → suggère de skip le bump

Présente la suggestion à l'utilisateur et demande confirmation :

Type détecté : feature
Nouvelle version : 1.10.0 → 1.11.0

Tu valides, ou tu veux changer (feature/improvement/fix/skip) ?

Si skip → bascule vers un commit + push standard sans bump ni changelog.

Step 3 — Collecter le contenu du changelog

Pose 2 questions courtes à l'utilisateur :

  1. Titre (court, product-focused, en français, sans préfixe v1.x.0 —) — propose un titre tiré des diffs (commit messages déjà existants, noms de fichiers, etc.)
  2. Highlights (1 à 5 bullets) — chaque bullet décrit ce que l'utilisateur peut faire de nouveau. Pas de jargon tech (refactor, stack, monorepo). Propose-les d'abord depuis les diffs, l'utilisateur valide ou modifie.

Optionnel : si la release est suffisamment riche, propose aussi un body markdown (2-4 paragraphes max) qui explique le pourquoi. Sinon, body vide = entry courte uniquement avec les highlights, c'est ok.

Ton (rappel — ce sont les règles brand) :

  • Direct, concret, chaleureux, précis (cf. /CLAUDE.md §Voix)
  • "On parle comme un bon associé, pas comme une DAF"
  • Une phrase d'attitude max par entrée ("Un client remercié est un client qui revient")
  • Jamais de "we are excited to announce", jamais de superlatifs
  • Jamais de "recouvrement"
  • Variables markdown en backticks : `{{client.nom}}`

Step 4 — Écrire les fichiers

4a. Bumper apps/web/src/version.ts

export const APP_VERSION = "<new-version>";

Edit (pas Write — préserve les commentaires) avec replace_all: false.

4b. Créer apps/landing/src/content/changelog/<new-version>.md

Format strict (validé par Zod via apps/landing/src/content.config.ts) :

---
version: "<X.Y.Z>"
date: <YYYY-MM-DD>
title: "<titre court fourni par l'user>"
type: feature  # ou improvement / fix
highlights:
  - "<highlight 1>"
  - "<highlight 2>"
  - "<highlight 3>"
---

<body markdown optionnel  2-4 paragraphes max>

Règles :

  • version doit matcher le regex ^\d+\.\d+\.\d+$ et être identique à la valeur dans version.ts
  • date au format YYYY-MM-DD — utilise date +%Y-%m-%d côté bash pour avoir la vraie date du jour
  • title entre 3 et 80 caractères, sans préfixe v1.x.0 —
  • type{feature, improvement, fix}
  • highlights : 1 à 8 items, idéalement 2-5

Step 5 — Commit + push

5a. Génère le message de commit

Suis la convention du repo (Conventional Commits avec scope) :

<type>(<scope>): <description courte>

<body : 1-3 lignes qui expliquent le pourquoi, pas le quoi>
<résumé des changements majeurs si plusieurs fichiers>

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

Mappings :

Release type Commit type
feature feat
improvement feat ou refactor selon la nature
fix fix

Scope : à inférer depuis les diffs. Examples :

  • Diffs uniquement dans apps/web/ → scope web
  • Diffs uniquement dans apps/landing/ → scope landing
  • Diffs croisés (typique d'une release car version.ts + changelog/) → scope release ou pas de scope, et la description mentionne v<x.y.z>

Exemple :

feat(release): v1.11.0 — réécriture IA améliorée

Le bouton "Reformule" passe de 1 ton (ferme) à 3 (ferme, chaleureux,
court), avec un aperçu diff côté à côté avant validation. Bumpe APP_VERSION
et ajoute l'entrée changelog correspondante.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

5b. Stage + commit

# Stage les changements existants ET les nouveaux fichiers (version.ts + .md)
git add apps/web/src/version.ts apps/landing/src/content/changelog/<new-version>.md
# Plus tous les autres changements en attente (sauf si l'user a dit "stage only X")
git add <fichiers détectés au step 1>

git commit -m "$(cat <<'EOF'
<message complet via HEREDOC>
EOF
)"

⚠️ Ne JAMAIS :

  • Utiliser git add -A ou git add . (peut catch des secrets, des fichiers temporaires, etc.)
  • Utiliser --no-verify (les hooks pre-commit existent pour une raison)
  • git commit --amend (toujours un nouveau commit propre)

5c. Push

git push gitea main

Le remote gitea pointe sur https://git.arthurbarre.fr/ordinarthur/rubis.git. Le CI Gitea déclenche le build et le rollout K3s automatiquement.

Step 6 — Récap à l'utilisateur

Affiche un tableau récap après le push :

Pushed sur gitea/main :
- <commit hash> <commit subject>
- Version : <old> → <new>
- Changelog : apps/landing/src/content/changelog/<new>.md
- Toast SPA : effectif au prochain reload pour les users dont
  localStorage["rubis:last-seen-version"] < <new>

Le CI Gitea va déclencher le rebuild des images landing + web
(et la propagation sur K3s). Vérifie sur git.arthurbarre.fr.

Edge cases

  • Build SPA cassé (typecheck erreurs pré-existantes) : commit/push quand même mais flag clairement que le CI risque d'échouer. Ne tente pas de fixer ces erreurs dans le release commit — c'est un commit séparé.
  • Conflits avec le remote : si git push échoue avec [rejected] non-fast-forward, fais git pull --rebase gitea main puis re-push. Si rebase échoue → stop, demande à l'user.
  • Pre-commit hook échoue : NE fais PAS --amend, NE skip PAS avec --no-verify. Lis l'erreur, propose un fix, puis re-commit (nouveau commit, hash neuf).
  • Version déjà existante (le .md existe déjà sous ce numéro) : stop. Soit l'user a oublié de bumper version.ts, soit il y a un conflit de release parallèle. Demande clarification.
  • Versionnage incohérent : si version.ts est 1.10.0 mais le dernier .md est 1.12.0, signale-le avant tout bump. Probablement quelqu'un a oublié de commit le bump correspondant.