Skip to main content

Guía de Semantic Versioning y Git Flow

Tabla de Contenidos

    Semantic Versioning (SemVer) Estrategia de Branches Workflow de Desarrollo Proceso de Release Ejemplos Prácticos Comandos Git Útiles

    Semantic Versioning (SemVer)

    Formato: MAJOR.MINOR.PATCH (ejemplo: 1.2.3)

    ¿Cuándo incrementar cada número?

    MAJOR (1.x.x → 2.x.x)

    Cambios que ROMPEN compatibilidad hacia atrás (Breaking Changes)

    Ejemplos:

    • Cambiar la firma de un método público
    • Eliminar un método o clase pública
    • Cambiar el comportamiento de un método de forma incompatible
    • Renombrar propiedades públicas
    // v1.x.x
    public function base100Attributes(): array
    
    // v2.0.0 - BREAKING CHANGE
    public function base100Attributes(): Collection  // Cambió el return type
    
    

    Impacto: Los usuarios DEBEN revisar su código antes de actualizar.


    MINOR (x.1.x → x.2.x)

    Nuevas características que SÍ son compatibles hacia atrás

    Ejemplos:

    • Añadir un nuevo método público
    • Añadir un nuevo trait
    • Añadir parámetros opcionales a métodos existentes
    • Añadir nuevas opciones de configuración
    // v1.1.0
    class Base100 implements CastsAttributes
    {
        // Métodos existentes...
        
        // NUEVO método añadido
        public function withPrecision(int $decimals): self
        {
            // ...
        }
    }
    
    

    Impacto: Los usuarios pueden actualizar sin cambios en su código.


    PATCH (x.x.1 → x.x.2)

    Correcciones de bugs que NO cambian funcionalidad

    Ejemplos:

    • Corregir un bug
    • Mejorar rendimiento sin cambiar API
    • Actualizar documentación
    • Refactoring interno sin cambios en API pública
    • Corregir tests
    // v1.1.0 - Bug: redondeo incorrecto
    return (int) $value * 100;  // Error
    
    // v1.1.1 - Patch: corregir redondeo
    return (int) round($value * 100);  // Correcto
    
    

    Impacto: Actualización segura, solo mejoras y correcciones.


    Estrategia de Branches

    Branches Principales

    1. main (Branch Principal)

    • Propósito: Código estable y listo para producción
    • Protección: Protected (no push directo)
    • Contiene: Solo código que ha pasado tests y revisión
    • Tags: Todas las releases se tagean desde aquí

    2. develop (Branch de Desarrollo) - OPCIONAL

    • Propósito: Integración de features antes de release
    • Uso: Si tienes múltiples features en paralelo
    • Para este proyecto: NO necesario (proyecto pequeño)

    Branches de Trabajo

    Feature Branches: feature/*

    Para nuevas características

    feature/add-precision-option
    feature/base1000-support
    feature/custom-rounding
    
    

    Ejemplo de uso:

    # Crear feature branch desde main
    git checkout main
    git pull origin main
    git checkout -b feature/add-precision-option
    
    # Trabajar en la feature...
    git add .
    git commit -m "feat: add precision option to Base100 cast"
    
    # Cuando esté listo
    git push origin feature/add-precision-option
    # Crear Pull Request en GitHub
    
    

    Bugfix Branches: fix/*

    Para correcciones de bugs

    fix/rounding-precision
    fix/null-handling
    fix/trait-initialization
    
    

    Ejemplo de uso:

    # Crear bugfix branch
    git checkout main
    git checkout -b fix/rounding-precision
    
    # Corregir el bug
    git add .
    git commit -m "fix: correct rounding precision in Base100 cast"
    
    # Push y PR
    git push origin fix/rounding-precision
    
    

    Hotfix Branches: hotfix/*

    Para bugs CRÍTICOS en producción

    hotfix/security-vulnerability
    hotfix/data-corruption
    
    

    Diferencia con fix/*:

    • Hotfix: Bug crítico que necesita release inmediata
    • Fix: Bug normal que puede esperar al próximo release

    Release Branches: release/* - OPCIONAL

    Para preparar una release

    release/1.2.0
    release/2.0.0
    
    

    Uso: Solo si necesitas "congelar" features antes de release.


    Workflow de Desarrollo

    Opción 1: GitHub Flow (RECOMENDADO para este proyecto)

    main (protegido)
      ↑
      └── feature/nueva-caracteristica (trabajo aquí)
      └── fix/bug-menor (trabajo aquí)
    
    

    Ventajas:

    • Simple y directo
    • Ideal para proyectos pequeños-medianos
    • Deployments/releases frecuentes

    Flujo:

    1. Crear branch desde main

    2. Desarrollar la feature/fix

    3. Abrir Pull Request

    4. Code review + Tests automáticos (GitHub Actions)

    5. Merge a main

    6. Tag y release


    Opción 2: Git Flow (Para proyectos grandes)

    main (producción)
      ↑
    develop (desarrollo)
      ↑
      ├── feature/feature-1
      ├── feature/feature-2
      └── release/1.2.0
    
    

    Ventajas:

    • Mejor para equipos grandes
    • Releases planificadas
    • Múltiples versiones en paralelo

    Desventaja:

    • Más complejo
    • Overkill para proyectos pequeños

    Proceso de Release

    Release MINOR (nueva feature - 1.1.0 → 1.2.0)

    # 1. Asegurarte que main está actualizado
    git checkout main
    git pull origin main
    
    # 2. Actualizar CHANGELOG.md
    ## 1.2.0 - 2025-10-15
    
    ### Added
    
    - New `withPrecision()` method for custom decimal precision
    - Support for negative values in HasBase100 trait
    
    ### Fixed
    
    - Rounding precision issue in edge cases
    
    # 3. Commit el changelog
    git add CHANGELOG.md
    git commit -m "docs: update changelog for v1.2.0"
    
    # 4. Crear tag
    git tag -a v1.2.0 -m "Release v1.2.0 - Add precision support"
    
    # 5. Push tag y código
    git push origin main
    git push origin v1.2.0
    
    # 6. Crear GitHub Release
    gh release create v1.2.0 \
      --title "v1.2.0 - Precision Support" \
      --notes "See CHANGELOG.md for details"
    

    Release PATCH (bugfix - 1.1.0 → 1.1.1)

    # 1. Checkout main
    git checkout main
    git pull origin main
    
    # 2. Actualizar CHANGELOG.md
    ## 1.1.1 - 2025-10-12
    
    ### Fixed
    
    - Correct rounding precision when handling values > 1000
    
    # 3. Commit y tag
    git add CHANGELOG.md
    git commit -m "docs: update changelog for v1.1.1"
    git tag -a v1.1.1 -m "Release v1.1.1 - Fix rounding precision"
    
    # 4. Push
    git push origin main
    git push origin v1.1.1
    
    # 5. Release
    gh release create v1.1.1 \
      --title "v1.1.1 - Bugfix Release" \
      --notes "Fix rounding precision issue"
    

    Release MAJOR (breaking changes - 1.x.x → 2.0.0)

    # 1. Crear rama para v2
    git checkout main
    git checkout -b release/2.0.0
    
    # 2. Hacer cambios breaking
    # ... código ...
    
    # 3. Actualizar CHANGELOG.md con sección BREAKING CHANGES
    
    

    Ejemplo de CHANGELOG para v2.0.0:

    ## 2.0.0 - 2025-11-01
    
    ### BREAKING CHANGES
    
    - `base100Attributes()` now returns `Collection` instead of `array`
    - Minimum PHP version raised to 8.4
    - Removed deprecated `base100()` method
    
    ### Migration Guide
    
    **Before (v1.x):**
    ```php
    protected function base100Attributes(): array
    {
        return ['price', 'cost'];
    }
    
    

    After (v2.0):

    protected function base100Attributes(): Collection
    {
        return collect(['price', 'cost']);
    }
    
    

    Added

    • New Base100Collection class
    • Support for custom transformers
    
    Continuación del proceso:
    
    ```bash
    # 4. Mergear a main
    git checkout main
    git merge release/2.0.0
    
    # 5. Tag y release
    git tag -a v2.0.0 -m "Release v2.0.0 - Major overhaul"
    git push origin main
    git push origin v2.0.0
    
    # 6. GitHub Release con ADVERTENCIA
    gh release create v2.0.0 \
      --title "v2.0.0 - BREAKING CHANGES" \
      --notes "See CHANGELOG.md for migration guide"
    

    Ejemplos Prácticos

    Ejemplo 1: Añadir nueva feature (MINOR)

    Escenario: Quieres añadir soporte para Base1000

    # 1. Crear feature branch
    git checkout main
    git checkout -b feature/base1000-support
    
    # 2. Desarrollar la feature
    # - Crear src/Casts/Base1000.php
    # - Añadir tests
    # - Actualizar README
    
    # 3. Commits durante desarrollo
    git add .
    git commit -m "feat: add Base1000 cast class"
    git add .
    git commit -m "test: add Base1000 tests"
    git add .
    git commit -m "docs: document Base1000 usage"
    
    # 4. Push y crear PR
    git push origin feature/base1000-support
    gh pr create --title "Add Base1000 support" --body "Adds support for base-1000 conversions"
    
    # 5. Después de aprobación y merge
    git checkout main
    git pull origin main
    
    # 6. Release como 1.2.0 (MINOR - nueva feature)
    git tag -a v1.2.0 -m "Release v1.2.0 - Add Base1000 support"
    git push origin v1.2.0
    gh release create v1.2.0
    
    

    Ejemplo 2: Corregir bug (PATCH)

    Escenario: Hay un bug en el redondeo

    # 1. Crear fix branch
    git checkout main
    git checkout -b fix/rounding-issue
    
    # 2. Corregir el bug
    # - Editar src/Casts/Base100.php
    # - Añadir test que reproduce el bug
    # - Verificar que el test pasa
    
    # 3. Commit
    git add .
    git commit -m "fix: correct rounding for values > 10000"
    
    # 4. Push y PR
    git push origin fix/rounding-issue
    gh pr create --title "Fix rounding issue" --body "Fixes #42"
    
    # 5. Después del merge
    git checkout main
    git pull origin main
    
    # 6. Release como 1.1.1 (PATCH - bugfix)
    git tag -a v1.1.1 -m "Release v1.1.1 - Fix rounding issue"
    git push origin v1.1.1
    gh release create v1.1.1
    
    

    Ejemplo 3: Hotfix crítico (PATCH urgente)

    Escenario: Descubriste un bug que causa pérdida de datos

    # 1. Crear hotfix branch DESDE main
    git checkout main
    git checkout -b hotfix/data-loss-prevention
    
    # 2. Corregir RÁPIDAMENTE
    # - Solo el fix necesario, nada más
    # - Test mínimo que demuestre el fix
    
    # 3. Commit
    git add .
    git commit -m "fix: prevent data loss in null handling (critical)"
    
    # 4. Merge DIRECTO a main (sin PR si es muy urgente)
    git checkout main
    git merge hotfix/data-loss-prevention
    
    # 5. Release INMEDIATA
    git tag -a v1.1.2 -m "Release v1.1.2 - Critical hotfix"
    git push origin main
    git push origin v1.1.2
    gh release create v1.1.2 --title "v1.1.2 - Critical Hotfix"
    
    # 6. Notificar usuarios en GitHub/Packagist
    
    

    Comandos Git Útiles

    Gestión de Branches

    # Ver todas las branches
    git branch -a
    
    # Eliminar branch local
    git branch -d feature/mi-feature
    
    # Eliminar branch remoto
    git push origin --delete feature/mi-feature
    
    # Actualizar main desde remoto
    git checkout main && git pull origin main
    
    # Crear branch desde un commit específico
    git checkout -b fix/bug abc1234
    
    

    Gestión de Tags

    # Listar todos los tags
    git tag
    
    # Ver detalles de un tag
    git show v1.0.0
    
    # Eliminar tag local
    git tag -d v1.0.0
    
    # Eliminar tag remoto
    git push origin --delete v1.0.0
    
    # Crear tag desde un commit antiguo
    git tag -a v1.0.1 abc1234 -m "Release v1.0.1"
    
    

    Revertir Cambios

    # Revertir un commit (crea nuevo commit)
    git revert abc1234
    
    # Revertir último commit (antes de push)
    git reset --soft HEAD~1
    
    # Descartar cambios locales
    git checkout -- archivo.php
    
    

    Checklist de Release

    Antes de Release

    • Todos los tests pasan (composer test)
    • PHPStan sin errores (composer phpstan)
    • Código formateado (composer format)
    • CHANGELOG.md actualizado
    • README.md actualizado (si hay cambios en uso)
    • Versión en composer.json coincide? (NO - Packagist lo maneja)
    • Pull Request revisado y aprobado

    Durante Release

    • Main actualizado (git pull origin main)
    • Tag creado con mensaje descriptivo
    • Tag pusheado a GitHub
    • GitHub Release creada con notas
    • Packagist se actualizó automáticamente (webhook)

    Después de Release

    • Verificar que aparece en Packagist
    • Badges del README actualizados
    • Anunciar en redes/comunidad (si es relevante)
    • Crear issues/milestones para próxima versión

    Recomendaciones Específicas

    Estrategia Recomendada

    Para proyecto pequeño:

    1. Usar GitHub Flow (simple)

    2. Main siempre deployable

    3. Feature branches para TODO

    4. Pull Requests siempre (aunque seas solo tú - para CI)

    5. Tags para cada release

    Naming Conventions

    # Features
    feature/add-base1000
    feature/custom-precision
    feature/collection-support
    
    # Fixes
    fix/rounding-precision
    fix/null-handling
    fix/trait-initialization
    
    # Hotfixes
    hotfix/security-vulnerability
    hotfix/data-corruption
    
    # Docs
    docs/update-readme
    docs/add-examples
    docs/api-documentation
    
    # Chores
    chore/update-dependencies
    chore/ci-improvements
    
    

    Commits Convencionales

    feat: add new feature
    fix: bug correction
    docs: documentation only
    style: formatting, no code change
    refactor: code restructure
    test: add/update tests
    chore: maintenance tasks
    perf: performance improvements
    ci: CI/CD changes
    
    # Ejemplos:
    git commit -m "feat: add withPrecision() method"
    git commit -m "fix: correct rounding for negative values"
    git commit -m "docs: add usage examples to README"
    
    

    Recursos Adicionales

    • Semantic Versioning: https://semver.org/
    • Git Flow: https://nvie.com/posts/a-successful-git-branching-model/
    • GitHub Flow: https://guides.github.com/introduction/flow/
    • Conventional Commits: https://www.conventionalcommits.org/

    Preguntas Frecuentes

    ¿Cuándo hago MAJOR vs MINOR?

    MAJOR (2.0.0): Si un usuario actualiza y su código se ROMPE → MAJOR

    MINOR (1.1.0): Si un usuario actualiza y todo sigue funcionando → MINOR

    ¿Debo crear branch para cada pequeño cambio?

    SÍ. Siempre trabaja en branches, incluso para cambios pequeños:

    • Permite que GitHub Actions verifique antes de merge
    • Historial más limpio
    • Puedes descartar fácilmente si algo sale mal

    ¿Cuándo hacer release?

    Flexible, pero algunas guías:

    • PATCH: Cuando tengas 1+ bugfix importante
    • MINOR: Cuando completes 1+ nueva feature
    • MAJOR: Cuando hagas breaking changes (con cuidado)

    Frecuencia recomendada:

    • Patches: Cada 1-2 semanas
    • Minor: Cada 1-2 meses
    • Major: Solo cuando sea necesario

    ¿Puedo cambiar un tag después de crearlo?

    NO recomendado una vez pusheado. Si lo haces:

    • Los usuarios que ya instalaron la versión tendrán problemas
    • Packagist se confunde
    • Rompe la confianza

    Si DEBES hacerlo:

    # Eliminar tag
    git tag -d v1.0.0
    git push origin --delete v1.0.0
    
    # Crear nuevo tag
    git tag -a v1.0.0 nuevo_commit -m "..."
    git push origin v1.0.0
    
    

    Última actualización: 2025-10-10
    Autor: Abdelkarim Mateos Sanchez

    Aviso

    Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como está, sin que ello implique ningún obligación ni responsabilidad por parte de Castris

    Si necesitas soporte profesional puedes contratar con Castris soporte profesional.