Transportadores CI/CD: GitHub Actions, GitLab CI
Transportadores CI/CD: GitHub Actions, GitLab CI
1) Tarea CI/CD y lugar en la plataforma
CI/CD es el ensamblaje continuo, las pruebas y la entrega de los cambios desde el repositorio a los entornos de trabajo. Objetivos:- Velocidad y previsibilidad de los lanzamientos (tiempo de lectura corto).
- Calidad (autotestos, análisis estático/dinámico).
- Seguridad de la cadena de suministro (firma de artefactos, control de accesos).
- Fiabilidad (despojos canarios, retroceso rápido).
- Observabilidad (seguimiento y métricas en cada etapa).
Principios clave: «pipeline as code», artefactos inmutables, «build once - run many», «shift-left security», «least privilege», conjuntos deterministas.
2) Patrones de transportadores arquitectónicos
Stage-gate: build → test → security → package → deploy → post-deploy checks.
Fan-out/Fan-in: conjuntos de matrices paralelas (lenguajes/plataformas) con la combinación de resultados.
Promoción: el mismo artefacto avanza a través de los alrededores (dev → stage → prod) en lugar de superponerse.
Trunk-based + ramas cortas: minimización de la deriva, comprobaciones automatizadas en PR/MR.
Reusable: patrones/flujo de trabajo reutilizables (Actions: reusable workflows; GitLab: includes/child-pipelines).
GitOps (opcional): separación de «ensamblaje» y «entrega» (Argo CD/Flux monitoriza el repo declarativo de los alrededores).
3) Seguridad de la cadena de suministro (cadena de suministro)
Identificación: Federación OIDC de runner 'a a cloud (sin llaves de larga vida).
Secretos: almacenamiento centralizado, limitación del contexto, prohibición de la entrada en los registros.
Firma de artefactos/contenedores (cosign/Sigstore), verificación de la firma en control admission.
SBOM (CycloneDX/SPDX) y SCA, SAST/DAST/Container Scan - «puerta obligatoria».
Políticas: OPA/Conftest para IaC/manifiestos, «no latest», prohibición de contenedores privilegiados.
Aislamiento runner's: prod-runner en una red privada, separar de la internet pública los accesos salientes.
4) GitHub Actions - estructura y prácticas
4. 1 Estructura de flujos de trabajo
`.github/workflows/.yml` — триггеры (`on: push, pull_request, schedule, workflow_call`).
Reusable workflows para estandarización (linter, SCA, conjunto contenedor, deboy).
4. 2 Ejemplo: pipeline multiestadio con OIDC y firma de imagen
yaml name: ci-cd
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
permissions:
id-token: write # для OIDC contents: read packages: write
jobs:
build_test_matrix:
runs-on: ubuntu-latest strategy:
matrix:
node: [18, 20]
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4 with: { node-version: ${{ matrix. node }} }
- name: Cache npm uses: actions/cache@v4 with:
path: ~/.npm key: npm-${{ runner. os }}-${{ matrix. node }}-${{ hashFiles('/package-lock. json') }}
- run: npm ci
- run: npm run lint && npm test -- --ci
docker_build_sign:
runs-on: ubuntu-latest needs: build_test_matrix steps:
- uses: actions/checkout@v4
- name: Login to GHCR uses: docker/login-action@v3 with:
registry: ghcr. io username: ${{ github. actor }}
password: ${{ secrets. GITHUB_TOKEN }}
- name: Build image run:
docker build --pull --no-cache -t ghcr. io/org/app:${{ github. sha }}.
docker push ghcr. io/org/app:${{ github. sha }}
- name: Generate SBOM uses: anchore/syft-action@v0 with:
image: ghcr. io/org/app:${{ github. sha }}
format: cyclonedx-json output-file: sbom. json
- name: Cosign sign (OIDC)
uses: sigstore/cosign-installer@v3
- name: Sign image run:
cosign sign ghcr. io/org/app:${{ github. sha }} \
--yes \
--identity-token $ACTIONS_ID_TOKEN_REQUEST_TOKEN \
--rekor-url https://rekor. sigstore. dev
deploy_stage:
runs-on: ubuntu-latest needs: docker_build_sign environment:
name: stage url: https://stage. example. com steps:
- uses: actions/checkout@v4
- name: Assume cloud role via OIDC uses: aws-actions/configure-aws-credentials@v4 with:
role-to-assume: arn:aws:iam::123456789012:role/github-deployer aws-region: eu-central-1
- name: Helm deploy (canary 10%)
run:
helm upgrade --install app charts/app \
--set image. tag=${{ github. sha }} \
--set canary. enabled=true --set canary. traffic=10
- name: Smoke checks run:./scripts/smoke. sh
promote_prod:
runs-on: ubuntu-latest needs: deploy_stage environment:
name: production url: https://app. example. com concurrency: prod-release steps:
- name: Manual approval gate run: echo "Requires environment approvers in repo settings"
- name: Promote canary → 100% (blue-green)
run:
helm upgrade --install app charts/app \
--set image. tag=${{ github. sha }} \
--set canary. enabled=false
- name: Post-deploy checks & rollback on SLO breach run:./scripts/verify_or_rollback. sh
Claves:
- 'permissions' minimizado, incluido' id-token: write 'para OIDC.
- Environments con approvers y URL, 'concurrency' protege de las carreras.
- Activación del tráfico canario y retroceso automático por SLO.
4. 3 Flujo de trabajo reusable (ejemplo de llamada)
yaml jobs:
security_suite:
uses: org/.github/.github/workflows/security. yml@v1 with:
severity_threshold: high
5) GitLab CI - estructura y prácticas
5. 1 Estructura básica
`.gitlab-ci. yml 'en la raíz; entidades clave: 'stages', 'jobs',' rules ',' needs', 'artifacts',' environments ',' manual '.
Reuse: 'include:' (plantillas locales/remotas), pipelines child/parent para monorepos complejos.
5. 2 Ejemplo: matriz, caché, firma, entorno y approvals
yaml stages: [lint, test, build, security, deploy]
variables:
DOCKER_TLS_CERTDIR: "" # docker: dind acceleration
IMAGE_TAG: $CI_COMMIT_SHA
lint:
stage: lint image: node:20 script:
- npm ci
- npm run lint cache:
key: "npm-${CI_COMMIT_REF_SLUG}"
paths: [node_modules/]
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
test:
stage: test image: node:20 parallel:
matrix:
- NODE_VERSION: ["18", "20"]
script:
- nvm install $NODE_VERSION true
- npm ci
- npm test -- --ci artifacts:
when: always reports:
junit: report. xml
build_image:
stage: build image: docker:26. 1 services: [ "docker:26. 1-dind" ]
script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker build -t $CI_REGISTRY_IMAGE:$IMAGE_TAG.
- docker push $CI_REGISTRY_IMAGE:$IMAGE_TAG artifacts:
expire_in: 1 week paths: [ "sbom. json" ]
after_script:
- syft $CI_REGISTRY_IMAGE:$IMAGE_TAG -o cyclonedx-json > sbom. json
security_scans:
stage: security image: alpine:3. 20 script:
- trivy image --exit-code 0 --severity HIGH,CRITICAL $CI_REGISTRY_IMAGE:$IMAGE_TAG rules:
- if: '$CI_COMMIT_BRANCH == "main"'
deploy_stage:
stage: deploy image: bitnami/kubectl:1. 30 environment:
name: stage url: https://stage. example. com on_stop: stop_stage script:
- kubectl set image deploy/app app=$CI_REGISTRY_IMAGE:$IMAGE_TAG -n stage
-./scripts/smoke. sh needs: [build_image, security_scans]
when: manual allow_failure: false
stop_stage:
stage: deploy image: bitnami/kubectl:1. 30 environment:
name: stage action: stop script:
- kubectl rollout undo deploy/app -n stage
deploy_prod:
stage: deploy image: alpine/k8s:1. 30. 2 environment:
name: production url: https://app. example. com rules:
- if: '$CI_COMMIT_BRANCH == "main"'
when: manual allow_failure: false script:
-./scripts/canary_traffic. sh 10
-./scripts/verify_or_rollback. sh
Claves:
- `parallel. matrix 'simula conjuntos de matriz.
- 'artefactos' + informes de pruebas.
- Environments con 'on _ stop', manual 'when: manual' para approvals.
- DIND para ensamblar una imagen (mejor - Kaniko/BuildKit en k8s-ranner).
5. 3 Child pipelines e include para monorepos
yaml include:
- local:.gitlab/ci/includes/security. yml
- project: org/platform/pipelines file: /k8s/deploy. yml ref: v1
stages: [prepare, component_a, component_b, deploy]
component_a:
stage: component_a trigger:
include:.gitlab/ci/component_a. yml strategy: depend
component_b:
stage: component_b trigger:
include:.gitlab/ci/component_b. yml strategy: depend
6) Monopositivos y multiservicio
Directory-based ownership: CODEOWNERS y pruebas scoped por paths.
Incremental builds: identificamos los paquetes/listas afectados; caché de claves de ruta y archivos de bloqueo.
Pipelines dinámicos: child-pipelines/' workflow _ call' sólo se ejecutan para los componentes modificados.
Versioning: semver para cada módulo, changelog en la etapa release.
7) Almacenamiento en caché y aceleración
Caché de direcciones de contenido (hashFiles/lockfile).
Caché separado para dependencias y artefactos.
Pre-warm runner images (toolchains, SDK).
Espejos de paquetes locales (npm/pip/maven) y caché de registro de contenedores.
8) Estrategias de lanzamiento y retroceso
Canarias: aumento gradual del porcentaje de tráfico; auto-parada en la degradación de SLO.
Blue-Green: pilas paralelas, conmutación instantánea.
Shadow: duplicación de solicitudes sin afectar al cliente.
Feature flags: rollout a nivel de bandera, no de lanzamiento.
Rollback: scripts claros «con un solo botón», la versión del artefacto se almacena en los metadatos de lanzamiento.
9) Infraestructura y GitOps
IaC: Terraform/Ansible/Helm se administran en repos separados; policy-as-code como puerta.
GitOps-contorno: Argo CD/Flux observan el repo con los manifiestos de los alrededores; el transportador sólo crea el artefacto y actualiza las versiones en Git.
Ventajas: historia clara de cambios en el entorno, idempotencia, retrocesos estándar a través de Git.
10) Observabilidad CI/CD
DORA-métricas: frecuencia de los deployes, tiempo de commita a producción, porcentaje de fallas, MTTR.
Telemetría: tiempo de colas job's, duración de las etapas, hit-rate caché, frecuencia de pruebas flaky.
Registros de seguridad: quién inició la liberación, qué puertas se pasaron, qué excepciones se emitieron.
11) Control de acceso y aplicaciones
Protección Branch y verificaciones obligatorias.
Environment-approvals: listas individuales de approvers en stage/prod.
Acceso JIT para pasos manuales, sesión de registro.
Reparto de responsabilidades: diferentes roles para «escribe código», «aprueba», «libera».
12) Errores frecuentes (anti-patrones)
Llaves de nube de larga vida en los secretos del repo en lugar de roles OIDC.
Ensamblar diferentes artefactos para stage y prod (infracción «build once»).
etiquetas 'latest' e imágenes mutables.
Publicación de secretos en los logs de pasos (masking sin clave).
Un común public-runner para prod-deployes.
Ninguna «puerta» de seguridad (SAST/SCA/Policy) y comprobaciones post-deploy.
13) Lista de verificación de implementación (0-60 días)
0-15 días
Configurar reglas trunk-based, PR/MR, verificaciones estáticas obligatorias.
Incluir la federación OIDC en la nube; mínimas 'permissions'.
Divergir runner's: público - para CI, privado - para CD.
16-30 días
Agregar SBOM, firma de imagen; en el clúster, comprobación de la firma.
Introduzca canary/blue-green; auto-rollback por SLO.
Caché de dependencias y artefactos, imágenes pre-warm.
31-60 días
Separar conjunto y entrega (GitOps), política-as-code puerta.
Establecer DORA-métricas y alertas de degradación de paipelines.
Plantillas de paipeline (reusable/child) para todos los servicios.
14) Consejos prácticos sobre la fiabilidad
Mantenga pequeños y rápidos pipelines (10-12 min antes de la señal en PR).
Matar pruebas flaky: quarantine-tags + fix paralelo.
No mezcle artefactos CI y artefactos release; almacenar metadatos (commit, tiempo, SBOM, firmas).
Proporcione a los desarrolladores scripts locales idénticos a los pasos de canalización (dev-prod parity).
15) Plantillas de reutilización
15. 1 GitHub Actions - security reusable workflow (simplificado)
yaml name: security-suite on:
workflow_call:
inputs:
severity_threshold:
type: string required: false default: high jobs:
sast_sca:
runs-on: ubuntu-latest steps:
- uses: actions/checkout@v4
- run:./sec/sast. sh --threshold ${{ inputs. severity_threshold }}
- run:./sec/sca. sh --format cyclonedx-json --out sbom. json artifacts: # if using actions/upload-artifact
- sbom. json
15. 2 GitLab - Plantilla deploy incluida (simplificada)
yaml
.deployment_template:
image: alpine/k8s:1. 30 script:
- helm upgrade --install $APP charts/$APP --set image. tag=$IMAGE_TAG rules:
- if: '$CI_COMMIT_BRANCH == "main"'
16) Conclusión
GitHub Actions y GitLab CI proporcionan mecanismos maduros para un ciclo rápido y seguro de "código → prod'. La clave del éxito es la estandarización y la seguridad: OIDC en lugar de llaves, firma y SBOM, puerta de calidad, artefacto único con promoción, entrega de GitOps y observabilidad a través de DORA. Construya pipelines como un producto: mida, simplifique, acelere, y los lanzamientos se convertirán en una rutina, no en un evento.