merge(main): integrate dev #4
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Create Release | |
| on: | |
| push: | |
| tags: | |
| - 'v*' # Se dispara cuando se crea un tag que empieza con 'v' | |
| jobs: | |
| create-release: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write # Necesario para crear releases | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 # Necesario para obtener todo el historial de tags | |
| token: ${{ secrets.GITHUB_TOKEN }} # Necesario para poder hacer push del changelog | |
| - name: Get tag name | |
| id: tag | |
| run: | | |
| TAG_NAME=${GITHUB_REF#refs/tags/} | |
| echo "tag_name=$TAG_NAME" >> $GITHUB_OUTPUT | |
| echo "Tag name: $TAG_NAME" | |
| - name: Get previous tag | |
| id: previous_tag | |
| run: | | |
| TAG_NAME="${{ steps.tag.outputs.tag_name }}" | |
| TAG_PREFIX=$(echo "$TAG_NAME" | sed 's/^\([^0-9]*\).*/\1/') | |
| if [ -z "$TAG_PREFIX" ]; then | |
| TAG_PREFIX="v" | |
| fi | |
| # Intentar obtener el último tag de release antes del actual | |
| LAST_TAG=$(git describe --tags --abbrev=0 --match "${TAG_PREFIX}*" "${TAG_NAME}^" 2>/dev/null || echo "") | |
| if [ -z "$LAST_TAG" ]; then | |
| # Si no se encuentra, buscar en todos los tags con prefijo ordenados por fecha | |
| LAST_TAG=$(git tag --sort=-creatordate | grep "^${TAG_PREFIX}" | grep -v "^${TAG_NAME}$" | head -n 1 || echo "") | |
| fi | |
| if [ -n "$LAST_TAG" ] && [ "$LAST_TAG" != "$TAG_NAME" ]; then | |
| echo "previous_tag=$LAST_TAG" >> $GITHUB_OUTPUT | |
| echo "Previous tag: $LAST_TAG" | |
| else | |
| echo "previous_tag=" >> $GITHUB_OUTPUT | |
| echo "No previous tag found" | |
| fi | |
| - name: Generate changelog | |
| id: changelog | |
| run: | | |
| set -e # Salir si hay errores | |
| TAG_NAME="${{ steps.tag.outputs.tag_name }}" | |
| LAST_TAG="${{ steps.previous_tag.outputs.previous_tag }}" | |
| echo "Current tag: $TAG_NAME" | |
| echo "Previous tag: ${LAST_TAG:-none}" | |
| # Crear directorio de releases si no existe | |
| mkdir -p releases | |
| # Generar contenido del changelog desde commits | |
| # Mostrar TODOS los commits entre el último tag y el actual (sin filtrar por fecha) | |
| # Excluir commits de merge usando --no-merges y filtrar mensajes que empiecen con "merge(" | |
| if [ -n "$LAST_TAG" ] && [ "$LAST_TAG" != "$TAG_NAME" ]; then | |
| echo "Generating changelog from $LAST_TAG to $TAG_NAME" | |
| # Obtener todos los commits entre los tags excluyendo merges | |
| # --no-merges excluye commits de merge automáticamente | |
| # grep -v filtra commits cuyo mensaje contenga "merge(" | |
| CHANGELOG_CONTENT=$(git log --no-merges --pretty=format:"- %ad \`%h\` %s (%an)" --date=format:"%Y-%m-%d %H:%M" "${LAST_TAG}..${TAG_NAME}" 2>/dev/null | grep -vE "merge\(|^$" || echo "") | |
| else | |
| echo "No previous tag found, generating changelog for all commits up to $TAG_NAME" | |
| # Si no hay tag anterior, mostrar commits del tag actual (limitado a 50 para no ser demasiado largo) | |
| # Excluir merges también | |
| CHANGELOG_CONTENT=$(git log --no-merges --pretty=format:"- %ad \`%h\` %s (%an)" --date=format:"%Y-%m-%d %H:%M" "${TAG_NAME}" -n 50 2>/dev/null | grep -vE "merge\(|^$" || echo "") | |
| fi | |
| if [ -z "$CHANGELOG_CONTENT" ]; then | |
| echo "Warning: No changelog content generated" | |
| fi | |
| # Categorizar commits (Conventional Commits) | |
| FEAT_ITEMS=$(echo "$CHANGELOG_CONTENT" | grep -E "`[^`]*` (feat|feature)" || true) | |
| FIX_ITEMS=$(echo "$CHANGELOG_CONTENT" | grep -E "`[^`]*` fix" || true) | |
| DOCS_ITEMS=$(echo "$CHANGELOG_CONTENT" | grep -E "`[^`]*` docs" || true) | |
| REFACTOR_ITEMS=$(echo "$CHANGELOG_CONTENT" | grep -E "`[^`]*` refactor" || true) | |
| TEST_ITEMS=$(echo "$CHANGELOG_CONTENT" | grep -E "`[^`]*` test" || true) | |
| STYLE_ITEMS=$(echo "$CHANGELOG_CONTENT" | grep -E "`[^`]*` style" || true) | |
| CHORE_ITEMS=$(echo "$CHANGELOG_CONTENT" | grep -E "`[^`]*` chore" || true) | |
| OTHER_ITEMS=$(echo "$CHANGELOG_CONTENT" | grep -vE "`[^`]*` (feat|feature|fix|docs|refactor|test|style|chore)" || true) | |
| # Construir contenido categorizado | |
| CATEGORIZED_CONTENT="" | |
| if [ -n "$FEAT_ITEMS" ]; then | |
| CATEGORIZED_CONTENT+="### ✨ Added"$'\n'"$FEAT_ITEMS"$'\n\n' | |
| fi | |
| if [ -n "$FIX_ITEMS" ]; then | |
| CATEGORIZED_CONTENT+="### 🐛 Fixed"$'\n'"$FIX_ITEMS"$'\n\n' | |
| fi | |
| if [ -n "$DOCS_ITEMS" ]; then | |
| CATEGORIZED_CONTENT+="### 📚 Documentation"$'\n'"$DOCS_ITEMS"$'\n\n' | |
| fi | |
| if [ -n "$REFACTOR_ITEMS" ]; then | |
| CATEGORIZED_CONTENT+="### ♻️ Refactored"$'\n'"$REFACTOR_ITEMS"$'\n\n' | |
| fi | |
| if [ -n "$TEST_ITEMS" ]; then | |
| CATEGORIZED_CONTENT+="### ✅ Tests"$'\n'"$TEST_ITEMS"$'\n\n' | |
| fi | |
| if [ -n "$STYLE_ITEMS" ]; then | |
| CATEGORIZED_CONTENT+="### 💅 Style"$'\n'"$STYLE_ITEMS"$'\n\n' | |
| fi | |
| if [ -n "$CHORE_ITEMS" ]; then | |
| CATEGORIZED_CONTENT+="### 🔧 Chores"$'\n'"$CHORE_ITEMS"$'\n\n' | |
| fi | |
| if [ -n "$OTHER_ITEMS" ]; then | |
| CATEGORIZED_CONTENT+="### 📝 Other"$'\n'"$OTHER_ITEMS"$'\n\n' | |
| fi | |
| # Si no hay contenido categorizado, usar el contenido completo | |
| if [ -z "$CATEGORIZED_CONTENT" ]; then | |
| CATEGORIZED_CONTENT="$CHANGELOG_CONTENT" | |
| fi | |
| # Obtener fecha del tag para el archivo de release | |
| TAG_DATE=$(git log -1 --format="%ad" --date=short "${TAG_NAME}" 2>/dev/null || date +%Y-%m-%d) | |
| # Calcular total de commits | |
| TOTAL_COMMITS=$(echo "$CHANGELOG_CONTENT" | grep -c "^-" || echo "0") | |
| # Crear archivo de release | |
| { | |
| echo "# Release ${TAG_NAME}" | |
| echo "" | |
| echo "**Fecha:** ${TAG_DATE}" | |
| if [ -n "$LAST_TAG" ]; then | |
| echo "**Previous Release:** ${LAST_TAG}" | |
| fi | |
| echo "" | |
| echo "## Changes" | |
| echo "" | |
| echo "$CATEGORIZED_CONTENT" | |
| echo "" | |
| echo "## Technical Details" | |
| echo "- Tag: ${TAG_NAME}" | |
| echo "- Previous tag: ${LAST_TAG:-Initial release}" | |
| echo "- Total commits: ${TOTAL_COMMITS}" | |
| } > "releases/${TAG_NAME}.md" | |
| echo "Changelog generated: releases/${TAG_NAME}.md" | |
| echo "Total commits: $TOTAL_COMMITS" | |
| # Verificar que el archivo se creó correctamente | |
| if [ -f "releases/${TAG_NAME}.md" ]; then | |
| echo "✅ Release file created successfully" | |
| echo "File size: $(wc -l < releases/${TAG_NAME}.md) lines" | |
| else | |
| echo "❌ ERROR: Release file was not created!" | |
| exit 1 | |
| fi | |
| - name: Commit changelog file | |
| continue-on-error: true | |
| run: | | |
| TAG_NAME="${{ steps.tag.outputs.tag_name }}" | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| # Hacer checkout de main para poder hacer commit (cuando se crea un tag, estamos en detached HEAD) | |
| git checkout main || git checkout dev || echo "Could not checkout branch, skipping commit" | |
| # Verificar si el archivo existe y tiene cambios | |
| if [ -f "releases/${TAG_NAME}.md" ]; then | |
| git add "releases/${TAG_NAME}.md" | |
| if ! git diff --cached --quiet; then | |
| git commit -m "docs(release): add changelog for ${TAG_NAME}" || echo "Commit failed" | |
| git push || echo "Push failed (may need permissions)" | |
| else | |
| echo "No changes to commit (file already exists and is up to date)" | |
| fi | |
| else | |
| echo "Changelog file not found, skipping commit" | |
| fi | |
| - name: Verify release file exists | |
| run: | | |
| TAG_NAME="${{ steps.tag.outputs.tag_name }}" | |
| if [ ! -f "releases/${TAG_NAME}.md" ]; then | |
| echo "❌ ERROR: Release file releases/${TAG_NAME}.md does not exist!" | |
| ls -la releases/ || echo "Releases directory does not exist" | |
| exit 1 | |
| fi | |
| echo "✅ Release file found: releases/${TAG_NAME}.md" | |
| echo "Preview of first 20 lines:" | |
| head -n 20 "releases/${TAG_NAME}.md" | |
| - name: Create Release | |
| uses: softprops/action-gh-release@v1 | |
| with: | |
| tag_name: ${{ steps.tag.outputs.tag_name }} | |
| name: Release ${{ steps.tag.outputs.tag_name }} | |
| body_path: releases/${{ steps.tag.outputs.tag_name }}.md | |
| draft: false | |
| prerelease: false | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |