0Pricing
PHP Academy · Lección

CI/CD con GitHub Actions

Pruebe y despliegue PHP automáticamente con cada push

CI/CD con GitHub Actions es una lección gratuita de PHP Academy en CoddyKit. Esta es la lección 4 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de PHP Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de PHP Academy incluye 4 lecciones en total.

CI/CD para PHP

Cada push debe probarse, pasar lint y analizarse estáticamente; cuando la rama principal esté en verde, también debe convertirse en una imagen y desplegarse. GitHub Actions ejecuta este pipeline en runners administrados, activado por eventos del repositorio.

Crearemos un workflow que ejecute PHPUnit con un servicio MySQL real, almacene Composer en caché, ejecute PHPStan, compile una imagen de Docker y la despliegue.

Anatomía de un workflow

Un workflow reside en .github/workflows/*.yml. Contiene activadores on:, uno o más jobs: y cada trabajo tiene steps:. Los trabajos se ejecutan en runners aislados y en paralelo, salvo que estén vinculados mediante needs:.

name: CI
on:
  push:
    branches: [main]
  pull_request:

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

Acción setup-php

shivammathur/setup-php es la forma estándar de instalar una versión específica de PHP con las extensiones y herramientas elegidas, como Composer y PHPStan, en el runner; es mucho más rápido que compilar una imagen solo para realizar pruebas.

      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: '8.3'
          extensions: pdo_mysql, intl, redis, zip
          coverage: pcov
          tools: composer:v2, phpstan

Almacenamiento de Composer en caché

Volver a descargar las dependencias en cada ejecución desperdicia minutos. Almacene en caché el directorio de Composer usando como clave el hash de composer.lock, de modo que la caché solo se invalide cuando cambien las dependencias.

      - name: Get Composer cache dir
        id: composer-cache
        run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT

      - uses: actions/cache@v4
        with:
          path: ${{ steps.composer-cache.outputs.dir }}
          key: composer-${{ hashFiles('**/composer.lock') }}
          restore-keys: composer-

      - run: composer install --prefer-dist --no-progress

Contenedores de servicio

Los trabajos pueden iniciar contenedores de servicio: un MySQL o Redis real al que el runner puede acceder mediante 127.0.0.1. Añada una comprobación de estado mediante options para que los pasos no se ejecuten antes de que la base de datos esté lista.

  test:
    runs-on: ubuntu-latest
    services:
      mysql:
        image: mysql:8.4
        env:
          MYSQL_DATABASE: app_test
          MYSQL_ROOT_PASSWORD: root
        ports: ['3306:3306']
        options: >-
          --health-cmd="mysqladmin ping -proot"
          --health-interval=5s --health-retries=10

Ejecución de pruebas y cobertura

Con las dependencias instaladas y MySQL activo, ejecute PHPUnit. Configure el DSN de pruebas para que apunte a 127.0.0.1:3306. Genere la cobertura y, opcionalmente, haga fallar la compilación si queda por debajo de un umbral.

      - name: Run PHPUnit
        env:
          DATABASE_URL: "mysql://root:root@127.0.0.1:3306/app_test"
        run: vendor/bin/phpunit --coverage-clover=coverage.xml

      - name: Static analysis
        run: phpstan analyse src --level=8 --no-progress

Compilaciones con matriz

Las bibliotecas deberían superar las pruebas en varias versiones de PHP. Un strategy.matrix distribuye el trabajo en ejecuciones paralelas, una por cada combinación, e interpola ${{ matrix.php }} en los pasos.

  test:
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        php: ['8.2', '8.3', '8.4']
    steps:
      - uses: actions/checkout@v4
      - uses: shivammathur/setup-php@v2
        with:
          php-version: ${{ matrix.php }}

Cálculo de la etiqueta de la imagen

Los despliegues necesitan una etiqueta de imagen única y trazable. El SHA del commit es la opción convencional. Este fragmento muestra la lógica para derivar la etiqueta que expresaría en el workflow: convertir un ref y un SHA en una etiqueta del registro.

<?php
// Mirrors what the workflow computes for the image tag
$ref = 'refs/heads/main';
$sha = '9f41efadc0de1234567890abcdef0000deadbeef';

$branch = str_replace('refs/heads/', '', $ref);
$shortSha = substr($sha, 0, 7);
$tag = sprintf('registry.example.com/app:%s-%s', $branch, $shortSha);

echo $tag . PHP_EOL;          // registry.example.com/app:main-9f41efa
echo 'is_main: ' . ($branch === 'main' ? 'yes' : 'no') . PHP_EOL;
?>

Compilación y envío de la imagen

En la rama principal, compile la imagen de Docker con docker/build-push-action, usando BuildKit y la caché de GitHub Actions. Inicie primero sesión en el registro con un token secreto; nunca incluya las credenciales directamente en el código.

  build:
    needs: test
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}
      - uses: docker/build-push-action@v6
        with:
          push: true
          target: runtime
          tags: ghcr.io/${{ github.repository }}:${{ github.sha }}
          cache-from: type=gha
          cache-to: type=gha,mode=max

Secretos y OIDC

Guarde las credenciales en los secretos del repositorio o del entorno y haga referencia a ellas como ${{ secrets.NAME }}; se ocultan en los registros. Para los despliegues en la nube, prefiera OIDC: el runner obtiene un token de corta duración de AWS/GCP mediante permissions: id-token: write, por lo que no hay claves de larga duración almacenadas en el repositorio.

  deploy:
    needs: build
    runs-on: ubuntu-latest
    permissions:
      id-token: write     # enables OIDC
      contents: read
    steps:
      - uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: arn:aws:iam::123456789012:role/deploy
          aws-region: eu-central-1

Paso de despliegue y entornos

Proteja los despliegues de producción mediante un environment de GitHub, opcionalmente con revisores obligatorios. El paso de despliegue activa entonces su lanzamiento: actualiza una implementación de Kubernetes, un servicio de ECS o se conecta por SSH para extraer la nueva imagen.

  deploy:
    needs: build
    runs-on: ubuntu-latest
    environment:
      name: production       # can require manual approval
      url: https://app.example.com
    steps:
      - name: Roll out
        run: |
          kubectl set image deployment/app \
            app=ghcr.io/${{ github.repository }}:${{ github.sha }}
          kubectl rollout status deployment/app --timeout=120s

Comprobación rápida

¿Cuál es la principal ventaja de seguridad de OIDC frente a las claves de la nube almacenadas en Actions?

Resumen

Creó un pipeline de CI/CD para PHP en GitHub Actions: activadores en push/PR, setup-php con extensiones, Composer almacenado en caché mediante una clave basada en el lockfile, un contenedor de servicio MySQL con comprobación de estado, PHPUnit y PHPStan, una matriz de versiones y, después, una compilación y envío exclusivos de main con caché de GHA y un despliegue autenticado mediante OIDC y protegido por un entorno.

Principios: base la caché en hashes del lockfile, controle la disponibilidad de los servicios mediante comprobaciones de estado, etiquete las imágenes con el SHA y prefiera OIDC a las claves almacenadas.

Preguntas frecuentes

¿La lección «CI/CD con GitHub Actions» es gratis?

Sí — el texto completo de «CI/CD con GitHub Actions» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de PHP Academy, actualiza a CoddyKit PRO. El curso de PHP Academy incluye 4 lecciones en total.

¿Qué aprenderé en «CI/CD con GitHub Actions»?

Pruebe y despliegue PHP automáticamente con cada push Practicas PHP Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar PHP Academy?

No se requiere experiencia previa. PHP Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 4 de 4.

¿Cuánto tiempo toma la lección «CI/CD con GitHub Actions»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de PHP Academy?

Sí. Cada lección de PHP Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Contenerización de una aplicación PHP
  2. Compilaciones multietapa y optimización
  3. Docker Compose para entornos locales
  4. CI/CD con GitHub Actions
← Volver a PHP Academy