This is a viewer only at the moment see the article on how this works.
To update the preview hit Ctrl-Alt-R (or ⌘-Alt-R on Mac) or Enter to refresh. The Save icon lets you save the markdown file to disk
This is a preview from the server running through my markdig pipeline
Thursday, 04 December 2025
El principio básico: hacer liberaciones rápidas e indoloras, y se liberarán más a menudo. Esto es fundamental para el desarrollo ágil: los despliegues rápidos y fiables crean el bucle de retroalimentación rápido que necesita. Cuando el despliegue es aterrador o lento, los equipos cambian por lotes, aumentando el riesgo. Cuando el despliegue es aburrido y automático, envía cambios pequeños con frecuencia.
Esta guía cubre las estrategias de lanzamiento que utilizo en la producción, desde implementaciones simples basadas en etiquetas hasta publicaciones monorepo multi-paquete. Acciones de GitHub flujos de trabajo en este repositorio.
Antes de sumergirse en detalles, aquí está cómo se comparan las estrategias comunes:
Estrategia Mejor para la Complejidad Común |----------|----------|------------|-----------| | Basado en etiquetas Aplicaciones, lanzamientos explícitos Low Startups, devs en solitario, equipos maduros | Sucursales Despliegue continuo Bajo Startups, equipos de movimiento rápido | GitFlow Releases reguladas, múltiples versiones High Enterprise, cumplimiento-pesado | Banderas basadas en troncos + características Equipos de alta velocidad Medio Gran tecnología, startups maduras | Monorepo multi-paquete Bibliotecas, bases de código compartidas Equipos de plataformas, proyectos OSS
Startups & Small Teams: Comience con la implementación basada en etiquetas o sucursales. Manténgalo simple - siempre puede agregar complejidad más tarde. Desarrollo basado en troncos con banderas de características es popular a escala, pero en exceso para equipos pequeños.
Empresa: A menudo requiere GitFlow o similar para el cumplimiento, seguimientos de auditoría y gestión de liberaciones. Múltiples entornos (dev, QA, estadificación, prod) con puertas de aprobación.
Desarrolladores en solitario: A base de etiquetas es ideal. Empujar una etiqueta, el despliegue ocurre. No hay ceremonia, no hay gastos generales.
Equipos de plataforma/biblioteca: Necesita estrategias monorepo con versión independiente por paquete. La versión semántica es fundamental para los consumidores intermedios.
La estrategia más simple y confiable. Diferentes prefijos de etiquetas se dirigen a diferentes entornos o desencadenan diferentes acciones.
on:
push:
tags:
- 'release-*' # Production
- 'local-*' # Dev environment
- name: Build Docker image
run: |
TAG_NAME=${GITHUB_REF#refs/tags/}
if [[ "$TAG_NAME" == local-* ]]; then
docker build -t myapp:local .
else
docker build -t myapp:latest -t myapp:$(date +%s) .
fi
¿Por qué funciona?: Modelo mental simple, implementaciones explícitas, fácil retroceso a través de etiquetas de tiempo.
# Deploy to production
git tag release-v2024.12.01 && git push origin release-v2024.12.01
# Deploy to dev
git tag local-feature-test && git push origin local-feature-test
Para monorepos con varios paquetes publicables, utilice prefijos de etiquetas para identificar qué paquete lanzar:
# Different workflows, different tag patterns
# umami-net.yml
on:
push:
tags: ['umamiv*.*.*'] # e.g., umamiv1.0.5
# fetchextension.yml
on:
push:
tags: ['fetchextension-v*.*.*'] # e.g., fetchextension-v1.2.0
Extraer la versión y utilizarla en todo:
- name: Extract version
run: echo "VERSION=${GITHUB_REF#refs/tags/umamiv}" >> $GITHUB_OUTPUT
- name: Build & Pack
run: |
dotnet build -c Release -p:Version=${{ steps.version.outputs.VERSION }}
dotnet pack -c Release -p:PackageVersion=${{ steps.version.outputs.VERSION }}
Para la versión automática, MinVer calcula las versiones de las etiquetas Git:
<PackageReference Include="MinVer" Version="6.0.0" PrivateAssets="all" />
<PropertyGroup>
<MinVerTagPrefix>umamiv</MinVerTagPrefix>
</PropertyGroup>
Desplegarse automáticamente cuando el código aterriza en ramas específicas. Común en startups y equipos de rápido movimiento.
on:
push:
branches: [main] # → Production
# branches: [develop] # → Staging
Pros: No hay paso manual, se despliega en la fusión Contras: Despliegues accidentales posibles, historia menos explícita
Utilizo un enfoque híbrido - construir sobre el empuje de la rama (comprobación de CI), pero sólo publicar en etiquetas:
on:
push:
tags: ['scheduler-*']
branches: [main, local]
jobs:
build:
# Always build
publish:
if: startsWith(github.ref, 'refs/tags/') # Only publish on tags
Para los despliegues auto-anfitriones, Watchtower automáticamente tira de nuevas imágenes:
services:
app:
image: myapp:latest
labels:
- "com.centurylinklabs.watchtower.enable=true"
watchtower:
image: containrrr/watchtower
volumes:
- /var/run/docker.sock:/var/run/docker.sock
command: --interval 300 # Check every 5 minutes
Flujo de despliegue: Push tag → GitHub Acciones se construye → Push to register → Watchtower tira → Contenedor se reinicia. Tiempo total: ~5 minutos.
Las implementaciones rápidas son inútiles si implementas errores. Cada flujo de trabajo debe incluir puertas:
- name: Run tests
run: dotnet test --configuration Release
- name: Build
run: dotnet build --configuration Release
# Tests or build fail → workflow stops → no publish
Para paquetes multiframework, construya todos los objetivos:
- run: dotnet build -c Release --framework net8.0
- run: dotnet build -c Release --framework net9.0
Enfoque moderno - sin secretos para rotar, sin claves para filtrar:
permissions:
id-token: write
contents: read
- uses: NuGet/login@v1
with:
user: 'myusername'
- run: dotnet nuget push *.nupkg --api-key ${{ steps.login.outputs.NUGET_API_KEY }}
GitHub intercambia su token OIDC por una clave de API NuGet de corta duración. Configure confianza en NuGet.org para habilitarlo.
Atestaciones de artefactos prueban que sus artefactos fueron construidos en CI, no manipulados, cada vez más requeridos por las empresas.
permissions:
id-token: write
attestations: write
- uses: docker/build-push-action@v6
id: push
with:
push: true
tags: myapp:latest
- uses: actions/attest-build-provenance@v2
with:
subject-name: index.docker.io/myuser/myapp
subject-digest: ${{ steps.push.outputs.digest }}
push-to-registry: true
Los consumidores verifican con: gh attestation verify oci://index.docker.io/myuser/myapp:latest --owner myuser
Esto logra SLSA Nivel 2. Para el nivel 3, use Flujos de trabajo reutilizables.
Los equipos necesitan que las partes interesadas previsualicen los cambios antes de fusionarse.
Enfoque empresarial - Entornos de vista previa basados en ramas:
on:
pull_request:
types: [opened, synchronize]
- run: |
BRANCH=$(echo ${{ github.head_ref }} | sed 's/[^a-zA-Z0-9]/-/g')
docker build -t myapp:preview-$BRANCH .
# Deploy to k8s namespace, cloud platform, etc.
Método de puesta en marcha/solo - Túnel de su máquina local:
# Cloudflare Tunnel (free)
cloudflared tunnel run --url http://localhost:5000 my-preview
# → https://my-preview.cfargotunnel.com
O usar Alambre VPN para el acceso interno del equipo a su máquina de desarrollo.
Limpieza de etiquetas: Las etiquetas Git se quedan para siempre.
git tag -d old-test-tag # Delete local
git push origin :refs/tags/old-test-tag # Delete remote
Convenios sobre la designación de nombres: Sea consistente.
release-YYYY.MM.DD para la producciónlocal-feature-name para devpackagev1.2.3 para las bibliotecasSecretos: Almacenar en Secretos de GitHub, nunca en código. Secretos requeridos típicamente:
DOCKER_HUB_ACCESS_TOKENNUGET_API_KEY (o utilizar OIDC)NPM_TOKENDesarrollo de Monorepo: Utilice las referencias del proyecto durante el desarrollo, cambie a las referencias del paquete para la verificación del despliegue:
<ProjectReference Include="..\MyLib\MyLib.csproj" />
<!-- <PackageReference Include="MyLib" Version="1.0.0" /> -->
Los mismos principios, diferentes herramientas:
Docker Compositor Kubernetes |----------------|------------|
docker-compose.yml ambientes Namespaces Reanudación de contenedores Despliegue de rollos GitOps rollback
Los flujos de trabajo mostrados aquí se ejecutan en este repositorio - check .github/workflows/ para las implementaciones completas.
Recuerda.: Las implementaciones rápidas y confiables son la base del desarrollo ágil.
© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.