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@v4Acció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, phpstanAlmacenamiento 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-progressContenedores 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=10Ejecució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-progressCompilaciones 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=maxSecretos 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-1Paso 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=120sComprobació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
- Contenerización de una aplicación PHP
- Compilaciones multietapa y optimización
- Docker Compose para entornos locales
- CI/CD con GitHub Actions