# Automatizar tus compilaciones con GitHub Actions


## Requisitos previos

Completa todas las secciones anteriores de esta guía, comenzando con [Contenedorizar una aplicación React.js](/guides/reactjs/configure-github-actions/containerize/).

También debes tener:
- Una cuenta de [GitHub](https://github.com/signup).
- Una cuenta verificada de [Docker Hub](https://hub.docker.com/signup).

---

## Descripción general

En esta sección, configurarás una **canalización de CI/CD** (pipeline de CI/CD) usando [GitHub Actions](https://docs.github.com/en/actions) para:

- Compilar tu aplicación React.js automáticamente dentro de un contenedor Docker.
- Ejecutar pruebas en un entorno consistente.
- Subir la imagen lista para producción a [Docker Hub](https://hub.docker.com).

---

## Conectar tu repositorio de GitHub a Docker Hub

Para permitir que GitHub Actions compile y suba imágenes de Docker, almacenarás de forma segura tus credenciales de Docker Hub en tu nuevo repositorio de GitHub.

### Paso 1: Conectar tu repositorio de GitHub a Docker Hub

1. Crea un Token de Acceso Personal (PAT) desde [Docker Hub](https://hub.docker.com)
   1. Ve a tu **cuenta de Docker Hub → Account Settings (Configuración de la cuenta) → Security (Seguridad)**.
   2. Genera un nuevo Token de Acceso con permisos de **Read/Write** (Lectura/Escritura).
   3. Nómbralo con algo descriptivo como `docker-reactjs-sample`.
   4. Copia y guarda el token; lo necesitarás en el Paso 4.

2. Crea un repositorio en [Docker Hub](https://hub.docker.com/repositories/)
   1. Ve a tu **cuenta de Docker Hub → Create a repository** (Crear un repositorio).
   2. Para el nombre del repositorio (Repository Name), utiliza algo descriptivo, por ejemplo: `reactjs-sample`.
   3. Una vez creado, copia y guarda el nombre del repositorio; lo necesitarás en el Paso 4.

3. Crea un nuevo [repositorio de GitHub](https://github.com/new) para tu proyecto de React.js.

4. Agrega las credenciales de Docker Hub como secretos del repositorio de GitHub

   En tu repositorio de GitHub recién creado:
   
   1. Navega a:
   **Settings (Configuración) → Secrets and variables (Secretos y variables) → Actions (Acciones) → New repository secret (Nuevo secreto de repositorio)**.

   2. Agrega los siguientes secretos:

   | Nombre              | Valor                          |
   |-------------------|--------------------------------|
   | `DOCKER_USERNAME` | Tu nombre de usuario de Docker Hub |
   | `DOCKERHUB_TOKEN` | Tu token de acceso de Docker Hub (creado en el Paso 1) |
   | `DOCKERHUB_PROJECT_NAME` | Tu nombre de proyecto de Docker (creado en el Paso 2) |

   Estos secretos permiten que GitHub Actions se autentique de forma segura con Docker Hub durante los flujos de trabajo automatizados.

5. Conectar tu proyecto local a GitHub

   Vincula tu proyecto local `docker-reactjs-sample` al repositorio de GitHub que acabas de crear ejecutando el siguiente comando desde la raíz de tu proyecto:

   ```console
   $ git remote set-url origin https://github.com/{your-username}/{your-repository-name}.git
   ```

   >[!IMPORTANT]
   >Reemplaza `{your-username}` y `{your-repository}` con tu usuario y nombre de repositorio reales de GitHub.

   Para confirmar que tu proyecto local está correctamente conectado al repositorio remoto de GitHub, ejecuta:

   ```console
   $ git remote -v
   ```

   Deberías ver una salida similar a:

   ```console
   origin  https://github.com/{your-username}/{your-repository-name}.git (fetch)
   origin  https://github.com/{your-username}/{your-repository-name}.git (push)
   ```

   Esto confirma que tu repositorio local está vinculado correctamente y listo para subir tu código fuente a GitHub.

6. Sube tu código fuente a GitHub

   Sigue estos pasos para confirmar y subir tu proyecto local a tu repositorio de GitHub:

   1. Prepara todos los archivos para la confirmación.

      ```console
      $ git add -A
      ```
      Este comando prepara todos los cambios —incluyendo archivos nuevos, modificados y eliminados— para la confirmación.

   2. Confirma tus cambios.

      ```console
      $ git commit -m "Initial commit"
      ```
      Este comando crea una confirmación que captura una instantánea de los cambios preparados con un mensaje descriptivo.

   3. Sube el código a la rama `main`.

      ```console
      $ git push -u origin main
      ```
      Este comando sube tus confirmaciones locales a la rama `main` del repositorio remoto de GitHub y establece la rama de seguimiento (upstream).

   Una vez completado, tu código estará disponible en GitHub, y cualquier flujo de trabajo de GitHub Actions que hayas configurado se ejecutará automáticamente.

> [!NOTE]  
> Obtén más información sobre los comandos de Git utilizados en este paso:
> - [Git add](https://git-scm.com/docs/git-add) – Prepara los cambios (nuevos, modificados, eliminados) para la confirmación.
> - [Git commit](https://git-scm.com/docs/git-commit) – Guarda una instantánea de tus cambios preparados.
> - [Git push](https://git-scm.com/docs/git-push) – Sube confirmaciones locales a tu repositorio de GitHub.
> - [Git remote](https://git-scm.com/docs/git-remote) – Visualiza y gestiona las URL de los repositorios remotos.

---

### Paso 2: Configurar el flujo de trabajo

Ahora crearás un flujo de trabajo de GitHub Actions que compile tu imagen de Docker, ejecute las pruebas y suba la imagen a Docker Hub.

1. Ve a tu repositorio en GitHub y selecciona la pestaña **Actions** (Acciones) en el menú superior.

2. Selecciona **Set up a workflow yourself** (Configurar un flujo de trabajo tú mismo) cuando se te indique.

   Esto abre un editor en línea para crear un nuevo archivo de flujo de trabajo. Por defecto, se guardará en:
   `.github/workflows/main.yml`

3. Agrega la siguiente configuración de flujo de trabajo al nuevo archivo:

```yaml
name: CI/CD – React.js Application with Docker

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]
    types: [opened, synchronize, reopened]

jobs:
  build-test-push:
    name: Build, Test and Push Docker Image
    runs-on: ubuntu-latest

    steps:
      # 1. Checkout source code
      - name: Checkout source code
        uses: actions/checkout@v6
        with:
          fetch-depth: 0 # Fetches full history for better caching/context

      # 2. Set up Docker Buildx
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v4

      # 3. Cache Docker layers
      - name: Cache Docker layers
        uses: actions/cache@v5
        with:
          path: /tmp/.buildx-cache
          key: ${{ runner.os }}-buildx-${{ github.sha }}
          restore-keys: ${{ runner.os }}-buildx-

      # 4. Cache npm dependencies
      - name: Cache npm dependencies
        uses: actions/cache@v5
        with:
          path: ~/.npm
          key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }}
          restore-keys: ${{ runner.os }}-npm-

      # 5. Extract metadata
      - name: Extract metadata
        id: meta
        run: |
          echo "REPO_NAME=${GITHUB_REPOSITORY##*/}" >> "$GITHUB_OUTPUT"
          echo "SHORT_SHA=${GITHUB_SHA::7}" >> "$GITHUB_OUTPUT"

      # 6. Build dev Docker image
      - name: Build Docker image for tests
        uses: docker/build-push-action@v7
        with:
          context: .
          file: Dockerfile.dev
          tags: ${{ steps.meta.outputs.REPO_NAME }}-dev:latest
          load: true # Load to local Docker daemon for testing
          cache-from: type=local,src=/tmp/.buildx-cache
          cache-to: type=local,dest=/tmp/.buildx-cache,mode=max

      # 7. Run Vitest tests
      - name: Run Vitest tests and generate report
        run: |
          docker run --rm \
            --workdir /app \
            --entrypoint "" \
            ${{ steps.meta.outputs.REPO_NAME }}-dev:latest \
            sh -c "npm ci && npx vitest run --reporter=verbose"
        env:
          CI: true
          NODE_ENV: test
        timeout-minutes: 10

      # 8. Login to Docker Hub
      - name: Log in to Docker Hub
        uses: docker/login-action@v4
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      # 9. Build and push prod image
      - name: Build and push production image
        uses: docker/build-push-action@v7
        with:
          context: .
          file: Dockerfile
          push: true
          platforms: linux/amd64,linux/arm64
          tags: |
            ${{ secrets.DOCKER_USERNAME }}/${{ secrets.DOCKERHUB_PROJECT_NAME }}:latest
            ${{ secrets.DOCKER_USERNAME }}/${{ secrets.DOCKERHUB_PROJECT_NAME }}:${{ steps.meta.outputs.SHORT_SHA }}
          cache-from: type=local,src=/tmp/.buildx-cache
```

Este flujo de trabajo realiza las siguientes tareas para tu aplicación React.js:
- Se activa con cada `push` o `pull request` dirigido a la rama `main`.
- Compila una imagen de Docker de desarrollo utilizando `Dockerfile.dev`, optimizada para pruebas.
- Ejecuta pruebas unitarias utilizando Vitest dentro de un entorno limpio y contenedorizado para garantizar la coherencia.
- Detiene el flujo de trabajo inmediatamente si alguna prueba falla, aplicando control de calidad del código.
- Almacena en caché tanto las capas de compilación de Docker como las dependencias de npm para ejecuciones de CI más rápidas.
- Se autentica de forma segura con Docker Hub utilizando secretos del repositorio de GitHub.
- Compila una imagen lista para producción utilizando la etapa `prod` en el `Dockerfile`.
- Etiqueta y sube la imagen final a Docker Hub con las etiquetas `latest` y el SHA corto del commit para trazabilidad.

> [!NOTE]
> Para obtener más información sobre `docker/build-push-action`, consulta el [README de GitHub Action](https://github.com/docker/build-push-action/blob/master/README.md).

---

### Paso 3: Ejecutar el flujo de trabajo

Después de haber agregado tu archivo de flujo de trabajo, es hora de activar y observar el proceso de CI/CD en acción.

1. Confirma y sube tu archivo de flujo de trabajo

   Selecciona "Commit changes..." (Confirmar cambios...) en el editor de GitHub.

   - Esta subida activará automáticamente la canalización de GitHub Actions.

2. Monitorea la ejecución del flujo de trabajo

   1. Ve a la pestaña **Actions** (Acciones) en tu repositorio de GitHub.
   2. Haz clic en la ejecución del flujo de trabajo para seguir cada paso: **build**, **test** y (si tiene éxito) **push**.

3. Verifica la imagen de Docker en Docker Hub

   - Después de una ejecución exitosa del flujo de trabajo, visita tus [repositorios de Docker Hub](https://hub.docker.com/repositories).
   - Deberías ver una nueva imagen en tu repositorio con:
      - Nombre del repositorio: `${your-repository-name}`
      - Las etiquetas incluyen:
         - `latest` – representa la compilación exitosa más reciente; ideal para pruebas rápidas o despliegue.
         - `<short-sha>` – un identificador único basado en el hash del commit, útil para el seguimiento de versiones, reversiones y trazabilidad.

> [!TIP] Proteger tu rama principal
> Para mantener la calidad del código y evitar subidas directas accidentales, activa las reglas de protección de ramas:
>  - Navega a tu **repositorio de GitHub → Settings (Configuración) → Branches (Ramas)**.
>  - En las reglas de protección de ramas (Branch protection rules), haz clic en **Add rule** (Agregar regla).
>  - Especifica `main` como el nombre de la rama.
>  - Activa opciones como:
>     - *Require a pull request before merging* (Requerir un pull request antes de fusionar).
>     - *Require status checks to pass before merging* (Requerir que las comprobaciones de estado pasen antes de fusionar).
>
> Esto garantiza que solo el código probado y revisado se fusione en la rama `main`.
---

## Resumen

En esta sección, configuraste una canalización de CI/CD completa para tu aplicación React.js contenedorizada utilizando GitHub Actions.

Esto es lo que lograste:

- Creaste un nuevo repositorio de GitHub específicamente para tu proyecto.
- Generaste un token de acceso seguro de Docker Hub y lo agregaste a GitHub como secreto.
- Definiste un flujo de trabajo de GitHub Actions para:
   - Compilar tu aplicación dentro de un contenedor Docker.
   - Ejecutar pruebas en un entorno consistente y contenedorizado.
   - Subir una imagen lista para producción a Docker Hub si las pruebas pasan.
- Activaste y verificaste la ejecución del flujo de trabajo a través de GitHub Actions.
- Confirmaste que tu imagen se publicó correctamente en Docker Hub.

Con esta configuración, tu aplicación React.js ahora está lista para pruebas y despliegues automatizados en distintos entornos, lo que aumenta la confianza, la coherencia y la productividad del equipo.

---

## Recursos relacionados

Profundiza tu comprensión de la automatización y las mejores prácticas para aplicaciones contenedorizadas:

- [Introducción a GitHub Actions](/guides/gha/) – Aprende cómo GitHub Actions automatiza tus flujos de trabajo
- [GitHub Actions de Docker Build](/build/ci/github-actions/) – Configura compilaciones de contenedores con GitHub Actions
- [Sintaxis de flujo de trabajo para GitHub Actions](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions) – Referencia completa para escribir flujos de trabajo de GitHub
- [Referencia del archivo Compose](/compose/compose-file/) – Referencia de configuración completa para `compose.yaml`
- [Mejores prácticas para escribir Dockerfiles](/develop/develop-images/dockerfile_best-practices/) – Optimiza tu imagen para rendimiento y seguridad

---

## Pasos siguientes

A continuación, aprende cómo probar y depurar localmente tus cargas de trabajo de React.js en Kubernetes antes de realizar el despliegue. Esto te ayuda a asegurarte de que tu aplicación se comporte como se espera en un entorno similar al de producción, reduciendo sorpresas durante el despliegue.

