11name : Release
22
33on :
4- push :
5- branches :
6- - master
4+ workflow_run :
5+ workflows : [ "CI" ]
6+ types :
7+ - completed
8+ branches : [ master ]
79
810permissions :
911 contents : write
10- pull-requests : write
12+ packages : write
1113 issues : write
1214
1315jobs :
14- release-flow :
16+ release :
17+ name : Create Release
1518 runs-on : ubuntu-latest
19+ if : |
20+ github.event.workflow_run.conclusion == 'success' &&
21+ !contains(github.event.workflow_run.head_commit.message, 'chore(release)') &&
22+ !contains(github.event.workflow_run.head_commit.message, '[skip ci]')
23+
1624 steps :
17- # 1. GENERAR TOKEN DE APP (LLAVE MAESTRA)
25+ # 1. AUTENTICACIÓN
1826 - name : Generate GitHub App token
1927 id : generate_token
2028 uses : tibdex/github-app-token@v2
2129 with :
2230 app_id : ${{ secrets.APP_ID }}
2331 private_key : ${{ secrets.APP_PRIVATE_KEY }}
2432
33+ # 2. CHECKOUT COMPLETO
2534 - name : Checkout
2635 uses : actions/checkout@v4
2736 with :
2837 fetch-depth : 0
2938 token : ${{ steps.generate_token.outputs.token }}
39+ ref : ${{ github.event.workflow_run.head_branch }}
3040
3141 - name : Setup Node.js
3242 uses : actions/setup-node@v4
@@ -36,103 +46,82 @@ jobs:
3646 - name : Install dependencies
3747 run : npm ci
3848
39- # 2 . CÁLCULO DE VERSIÓN (LÓGICA ANTI-BUCLE )
49+ # 3 . CÁLCULO MANUAL (Infalible )
4050 - name : Calculate Next Version
41- id : analyze
51+ id : calc
4252 run : |
4353 git fetch --tags --force
4454
45- # 1. Detectar último tag de Git
55+ # Buscar último tag válido
4656 LATEST_TAG=$(git tag --list 'v[0-9]*' | sort -V | tail -n 1)
4757 [ -z "$LATEST_TAG" ] && LATEST_TAG="v0.0.0"
48- CLEAN_TAG_VERSION=${LATEST_TAG#v}
49-
50- # 2. Leer versión actual del package.json
51- PKG_VERSION=$(node -p "require('./package.json').version")
58+ CLEAN_VERSION=${LATEST_TAG#v}
5259
53- echo "🏷️ Git Tag: $CLEAN_TAG_VERSION"
54- echo "Pgk Json: $PKG_VERSION"
55-
56- # 3. Lógica de recuperación
57- # Si package.json (4.4.0) es mayor que el tag (4.3.0), significa que el release anterior falló a medias.
58- # Forzamos el uso de la versión del package.json para terminar el trabajo.
59- if [ "$(node -pe "require('semver').gt('$PKG_VERSION', '$CLEAN_TAG_VERSION')")" == "true" ]; then
60- echo "⚠️ Detectado release incompleto ($PKG_VERSION > $CLEAN_TAG_VERSION)."
61- NEXT_VERSION=$PKG_VERSION
62- TYPE="recovery"
60+ # Analizar commits
61+ if [ "$LATEST_TAG" = "v0.0.0" ]; then
62+ COMMITS=$(git log --pretty=format:"%s" HEAD)
6363 else
64- # Cálculo normal
65- if [ "$LATEST_TAG" = "v0.0.0" ]; then
66- COMMITS=$(git log --pretty=format:"%s" HEAD)
67- else
68- COMMITS=$(git log ${LATEST_TAG}..HEAD --pretty=format:"%s")
69- fi
64+ COMMITS=$(git log ${LATEST_TAG}..HEAD --pretty=format:"%s")
65+ fi
7066
71- if echo "$COMMITS" | grep -qE "BREAKING[ -]CHANGE|^[a-z]+(\([^)]+\))?!:"; then
72- TYPE="major"
73- elif echo "$COMMITS" | grep -q "^feat"; then
74- TYPE="minor"
75- else
76- TYPE="patch"
77- fi
78- NEXT_VERSION=$(node -pe "require('semver').inc('$CLEAN_TAG_VERSION', '$TYPE')")
67+ # Determinar tipo
68+ if echo "$COMMITS" | grep -qE "BREAKING[ -]CHANGE|^[a-z]+(\([^)]+\))?!:"; then
69+ TYPE="major"
70+ elif echo "$COMMITS" | grep -q "^feat"; then
71+ TYPE="minor"
72+ else
73+ TYPE="patch"
7974 fi
8075
81- echo "🚀 Versión Objetivo: $NEXT_VERSION ($TYPE)"
82- echo "should_release=true" >> $GITHUB_OUTPUT
76+ # Calcular siguiente versión con Node
77+ NEXT_VERSION=$(node -pe "require('semver').inc('$CLEAN_VERSION', '$TYPE')")
78+
79+ echo "🚀 Versión calculada: $NEXT_VERSION ($TYPE)"
8380 echo "next_version=$NEXT_VERSION" >> $GITHUB_OUTPUT
8481
85- # 3. APLICAR Y SUBIR (PUSH EXPLÍCITO )
82+ # 4. EJECUCIÓN (Dividida para evitar errores )
8683 - name : Apply Version & Push
87- if : steps.analyze.outputs.should_release == 'true'
8884 env :
89- NEXT_VER : ${{ steps.analyze .outputs.next_version }}
85+ NEXT_VER : ${{ steps.calc .outputs.next_version }}
9086 GH_TOKEN : ${{ steps.generate_token.outputs.token }}
9187 run : |
9288 git config user.name "github-actions[bot]"
9389 git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
9490
95- echo "⬇️ Sincronizando..."
96- git pull origin master --rebase
91+ echo "📝 Aplicando versión $NEXT_VER..."
9792
98- echo "✨ Generando versión $NEXT_VER..."
99-
100- # Actualizar JSONs
93+ # A) ACTUALIZAR JSONs (Usamos npm nativo, nunca falla)
10194 npm version $NEXT_VER --no-git-tag-version --allow-same-version
10295
103- # Generar Changelog
96+ # B) GENERAR CHANGELOG (Usamos standard-version SOLO para texto)
97+ # --skip.bump: No toques el json
98+ # --skip.tag: No crees tags
99+ # --skip.commit: No hagas commit
104100 npx standard-version --release-as $NEXT_VER --skip.bump --skip.tag --skip.commit
105101
106- # Limpieza [null]
102+ # Limpieza preventiva
107103 sed -i "s/\[null\]/\[$NEXT_VER\]/g" CHANGELOG.md || true
108-
109- # Commit (Si es necesario)
104+
105+ # C) GIT COMMIT & TAG MANUAL
110106 git add package.json package-lock.json CHANGELOG.md
111- if git diff --staged --quiet; then
112- echo "⚠️ Nada que commitear"
113- else
114- git commit -m "chore(release): v$NEXT_VER [skip ci]"
115- fi
107+ git commit -m "chore(release): v$NEXT_VER [skip ci]"
116108
117- # CONFIGURACIÓN DE PUSH BLINDADA
109+ # Configurar URL con token de App
118110 git remote set-url origin https://x-access-token:${GH_TOKEN}@github.com/${{ github.repository }}.git
119111
120- # --- AQUÍ ESTÁ EL ARREGLO CLAVE ---
121- echo "🏷️ Forzando creación y subida de tag v$NEXT_VER..."
122- git tag -f v$NEXT_VER
112+ echo "🏷️ Creando tag v$NEXT_VER..."
113+ git tag v$NEXT_VER
123114
124- # 1. Subir master primero
115+ echo "🚀 Subiendo..."
125116 git push origin master
126- # 2. Subir el tag EXPLÍCITAMENTE (follow-tags a veces falla)
127- git push origin v$NEXT_VER --force
117+ git push origin v$NEXT_VER
128118
129- # 4. CREAR RELEASE EN GITHUB UI
119+ # 5. RELEASE VISUAL
130120 - name : Create GitHub Release
131- if : steps.analyze.outputs.should_release == 'true'
132121 uses : softprops/action-gh-release@v2
133122 with :
134- tag_name : v${{ steps.analyze .outputs.next_version }}
135- name : v${{ steps.analyze .outputs.next_version }}
123+ tag_name : v${{ steps.calc .outputs.next_version }}
124+ name : v${{ steps.calc .outputs.next_version }}
136125 body_path : CHANGELOG.md
137126 token : ${{ steps.generate_token.outputs.token }}
138127 make_latest : true
0 commit comments