# Automatizar tus compilaciones con GitHub Actions


## Requisitos previos

Completa todas las secciones anteriores de esta guía, empezando por [Containerizar una aplicación Angular](/guides/angular/configure-github-actions/containerize/).

También necesitas:

- 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 un pipeline de CI/CD con [GitHub Actions](https://docs.github.com/en/actions) para que automáticamente:

- Compile tu aplicación Angular dentro de un contenedor Docker.
- Ejecute pruebas en un entorno consistente.
- Envíe la imagen lista para producción a [Docker Hub](https://hub.docker.com).

---

## Conectar tu repositorio de GitHub con Docker Hub

Para que GitHub Actions compile y envíe imágenes Docker, guardarás de forma segura tus credenciales de Docker Hub en tu nuevo repositorio de GitHub.

### Paso 1: Generar credenciales de Docker Hub y configurar secretos de GitHub

1. Crea un token de acceso personal (PAT) en [Docker Hub](https://hub.docker.com)
   1. Ve a **tu cuenta de Docker Hub → Account Settings → Security**.
   2. Genera un nuevo Access Token con permisos de **Read/Write**.
   3. Ponle un nombre como `docker-angular-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**.
   2. En Repository Name, usa un nombre descriptivo, por ejemplo: `angular-sample`.
   3. Una vez creado, copia y guarda el nombre del repositorio; lo necesitarás en el paso 4.

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

4. Añade las credenciales de Docker Hub como secretos del repositorio de GitHub

   En tu repositorio de GitHub recién creado:
   1. Ve a:
      **Settings → Secrets and variables → Actions → New repository secret**.

   2. Añade 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` | El nombre de tu proyecto Docker (creado en el paso 2)  |

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

5. Conectar tu proyecto local con GitHub

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

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

   > [!IMPORTANT]
   > Sustituye `{your-username}` y `{your-repository}` por tu nombre de usuario y el nombre real del repositorio en GitHub.

   Para confirmar que tu proyecto local está conectado correctamente 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 enviar el código fuente a GitHub.

6. Enviar tu código fuente a GitHub

   Sigue estos pasos para hacer commit y push de tu proyecto local al repositorio de GitHub:
   1. Prepara todos los archivos para el commit.

      ```console
      $ git add -A
      ```

      Este comando prepara todos los cambios (nuevos, modificados y eliminados) para el commit.

   2. Haz commit de los cambios preparados con un mensaje descriptivo.

      ```console
      $ git commit -m "Initial commit"
      ```

      Este comando crea un commit que guarda una instantánea de los cambios preparados con un mensaje descriptivo.

   3. Haz push del código a la rama `main`.

      ```console
      $ git push -u origin main
      ```

      Este comando envía tus commits locales a la rama `main` del repositorio remoto de GitHub y configura la rama upstream.

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

> [!NOTE]
> Más información sobre los comandos git de este paso:
>
> - [Git add](https://git-scm.com/docs/git-add) – Prepara cambios (nuevos, modificados, eliminados) para el commit
> - [Git commit](https://git-scm.com/docs/git-commit) – Guarda una instantánea de los cambios preparados
> - [Git push](https://git-scm.com/docs/git-push) – Sube commits locales a tu repositorio de GitHub
> - [Git remote](https://git-scm.com/docs/git-remote) – Consulta y gestiona URLs de repositorios remotos

---

### Paso 2: Configurar el flujo de trabajo

Ahora crearás un flujo de GitHub Actions que compile tu imagen Docker, ejecute pruebas y envíe la imagen a Docker Hub.

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

2. Cuando se te pida, selecciona **Set up a workflow yourself**.

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

3. Añade la siguiente configuración de flujo de trabajo al archivo nuevo:

```yaml
name: CI/CD – Angular 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

      # 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
          cache-from: type=local,src=/tmp/.buildx-cache
          cache-to: type=local,dest=/tmp/.buildx-cache,mode=max

      # 7. Run Angular tests with Jasmine
      - name: Run Angular Jasmine tests inside container
        run: |
          docker run --rm \
            --workdir /app \
            --entrypoint "" \
            ${{ steps.meta.outputs.REPO_NAME }}-dev:latest \
            sh -c "npm ci && npm run test -- --ci --runInBand"
        env:
          CI: true
          NODE_ENV: test
        timeout-minutes: 10

      # 8. Log in 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 production 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 Angular:

- Se activa en cada `push` o pull request dirigido a la rama `main`.
- Compila una imagen Docker de desarrollo con `Dockerfile.dev`, optimizada para pruebas.
- Ejecuta pruebas unitarias con Vitest dentro de un entorno containerizado limpio para garantizar consistencia.
- Detiene el flujo de inmediato si alguna prueba falla, reforzando la calidad del código.
- Almacena en caché capas de compilación Docker y dependencias npm para acelerar las ejecuciones de CI.
- Se autentica de forma segura con Docker Hub usando secretos del repositorio de GitHub.
- Compila una imagen lista para producción usando la etapa `prod` en `Dockerfile`.
- Etiqueta y envía la imagen final a Docker Hub con las etiquetas `latest` y SHA corto para trazabilidad.

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

---

### Paso 3: Ejecutar el flujo de trabajo

Tras añadir el archivo de flujo de trabajo, toca activar y observar el proceso de CI/CD en acción.

1. Haz commit y push del archivo de flujo de trabajo
   - Selecciona "Commit changes…" en el editor de GitHub.
   - Este push activará automáticamente el pipeline de GitHub Actions.

2. Supervisa la ejecución del flujo de trabajo
   - Ve a la pestaña Actions de tu repositorio de GitHub.
   - Entra en la ejecución del flujo para seguir cada paso: **build**, **test** y (si todo va bien) **push**.

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

> [!TIP] Protege tu rama main
> Para mantener la calidad del código y evitar pushes directos accidentales, activa reglas de protección de ramas:
>
> - Ve a **tu repo de GitHub → Settings → Branches**.
> - En Branch protection rules, selecciona **Add rule**.
> - Especifica `main` como nombre de rama.
> - Activa opciones como:
>   - _Require a pull request before merging_.
>   - _Require status checks to pass before merging_.
>
> Así solo se fusiona en la rama `main` código probado y revisado.

---

## Resumen

En esta sección configuraste un pipeline de CI/CD completo para tu aplicación Angular containerizada con GitHub Actions.

Esto es lo que lograste:

- Crear un repositorio de GitHub específico para tu proyecto.
- Generar un token de acceso seguro de Docker Hub y añadirlo a GitHub como secreto.
- Definir un flujo de GitHub Actions que:
  - Compila tu aplicación dentro de un contenedor Docker.
  - Ejecuta pruebas en un entorno containerizado consistente.
  - Envía una imagen lista para producción a Docker Hub si las pruebas pasan.
- Activar y verificar la ejecución del flujo mediante GitHub Actions.
- Confirmar que tu imagen se publicó correctamente en Docker Hub.

Con esta configuración, tu aplicación Angular está lista para pruebas y despliegue automatizados en distintos entornos, con más confianza, consistencia y productividad del equipo.

---

## Recursos relacionados

Profundiza en automatización y buenas prácticas para aplicaciones containerizadas:

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

---

## Próximos pasos

A continuación aprenderás a probar y depurar en local tus cargas de trabajo Angular en Kubernetes antes de desplegar. Así te aseguras de que la aplicación se comporta como se espera en un entorno similar a producción y reduces sorpresas durante el despliegue.

