learning-front

Nivel 9 · El ciclo completo: del commit al deploy

Proyecto: desplegar el Team Builder

El capstone del nivel: lleva tu Team Builder de React a producción de verdad juntando todo —flujo de PR, CI con GitHub Actions, deploy automático y la capa PWA— y demuéstralo con el examen del Nivel 9.

Llegaste al final del Nivel 9. Llevas seis capítulos montando piezas por separado: el flujo de ramas y PRs, el grafo de módulos y el tree-shaking, el pipeline de CI con GitHub Actions, el deploy a Pages, las meta tags de SEO y la capa PWA. Ahora las juntas todas. No hay concepto nuevo; es integración: tu Team Builder de React sale a producción de verdad.

El ciclo completo, de un vistazo#

Así queda el pipeline cuando el proyecto esté terminado:

texto
trabajas en una rama  →  abres un PR


                  CI: lint + tests + build       ← (cap. 3 GitHub Actions)
                  [merge bloqueado si falla]     ← (branch protection)


                        mergeas a main


                  CD: build + deploy a Pages     ← (cap. 4 deploy)
                  [solo si CI pasó]


            URL pública: Team Builder online     ← (cap. 4 base en vite.config.ts)
            instalable desde el navegador        ← (cap. 6 manifest + SW)
            funciona sin conexión                ← (cap. 6 caché offline)

Cada flecha del diagrama corresponde a algo que ya hiciste en un capítulo del nivel. Aquí los encadenas en un sistema que se ejecuta solo.

Lo que vas a entregar#

La misión es que en tu repositorio de GitHub exista un pipeline de CI/CD que funcione de extremo a extremo: verificación en cada PR y publicación automática en cada push a main. La app debe ser una PWA instalable con soporte offline. Y como el proyecto es iterativo, arrastra la calidad de todos los niveles anteriores: el HTML sigue siendo semántico, el CSS aguanta a 375px en móvil, no hay any en el TypeScript y los tests están en verde. Acumulas una capa más; no descartas nada.

La URL final, https://tu-usuario.github.io/team-builder/, es el resultado visible. Pero el aprendizaje de verdad está en el proceso: en la fricción de conectar las piezas, en depurar el primer 404 por un base mal configurado, en ver el CI fallar por primera vez y bloquear el merge como debe. Eso es lo que diferencia saber los conceptos de haberlos aplicado.

Cómo encajan las piezas#

Cada capítulo del nivel aporta algo concreto al sistema:

Git avanzado (cap. 1) pone el flujo: cada tarea en su propia rama, el PR como punto de revisión, el rebase interactivo para limpiar la historia antes del merge. La calidad de la historia de maincommits en formato convencional, sin mensajes de “wip”— es parte del criterio de excelente.

Bundling a fondo (cap. 2) explica lo que hay en dist/ después del build: los chunks de JS con tree-shaking, el CSS, el manifest, el service worker y los iconos. El pipeline no toca esos ficheros; los arrastra el build. Saber lo que hay ahí te permite depurar cuando algo falta.

CI con GitHub Actions (cap. 3) monta la portería: el job ci ejecuta lint, tests y build en cada PR. La branch protection bloquea el merge si falla. El ejercicio de este capítulo ya tenías un ci.yml; aquí lo integras con el deploy en un solo workflow o en dos ficheros separados.

Deploy a Pages (cap. 4) publica el dist/. Las dos cosas críticas: el base en vite.config.ts con el nombre exacto del repositorio, y GitHub Pages activado en modo “GitHub Actions” en Settings > Pages. El deploy.yml que montaste en ese capítulo es la base del job deploy de aquí.

SEO (cap. 5) ya está hecho: las meta tags del <head><title>, <meta name="description">, las etiquetas Open Graph— viven en el index.html. El build las arrastra a dist/ sin que el pipeline las toque. Los crawlers de redes sociales las leerán del HTML estático sin necesitar ejecutar JavaScript.

PWA (cap. 6) también está hecho: el manifest.json en public/ y el service worker con su caché offline. El build los copia a dist/. Cuando el deploy publique ese dist/, la app será instalable y funcionará sin conexión desde la URL de Pages.

La integración es el trabajo de este capstone. Conecta las piezas, verifica el pipeline de extremo a extremo, y cuando la URL esté viva y el CI funcione como portería, habrás cerrado el Nivel 9: sabes construir, verificar y publicar una aplicación frontend de principio a fin.

Examen del Nivel 9#

18 preguntas que repasan los seis capítulos del nivel: git avanzado, bundling, CI con GitHub Actions, deploy, SEO y PWA. Algunas combinan temas, otras esconden una trampa donde la opción incorrecta parece razonable. Es el examen que cierra el nivel; tómatelo como tal.

Pregunta 1 de 18

¿Cuál es la diferencia clave entre merge y rebase en el resultado de la historia de git?

El proyecto#

Este es un proyecto en local, sobre tu Team Builder de React. No hay playground: un pipeline de CI/CD necesita un repositorio real, ramas, pull requests y un runner de GitHub Actions para ejecutarse. El resultado solo es visible cuando la app está publicada en tu URL de Pages. Lee el README del ejercicio antes de empezar; tiene la lista de comprobación completa y los requisitos previos. Cuando termines (o si te atascas), despliega las soluciones: los tres ci-cd.yml muestran el pipeline integrado de cada tier y los comentarios explican por qué cada nivel supera al anterior.

Ejercicio · hazlo en local

Despliega el Team Builder

Lleva tu Team Builder de React a producción de verdad. La misión: que en tu repositorio de GitHub exista un pipeline de CI/CD que verifique el código en cada PR y publique la app en GitHub Pages en cada push a main. La app debe ser una PWA instalable y funcionar offline. No hay concepto nuevo: es integrar todo lo que has montado capítulo a capítulo —el flujo de PR, el CI con GitHub Actions, el deploy, las meta tags de SEO y el service worker— en un sistema que funcione de extremo a extremo. El proyecto es ITERATIVO: no basta con que la URL exista, también deben seguir bien el HTML semántico, el CSS responsive (aguanta a 375px), los tipos sin any y los tests en verde. Acumulas una capa más; no descartas nada de lo anterior.

Paso 1: La URL existe y el pipeline lleva el código a producción

  • Existe .github/workflows/ci-cd.yml con un job que construye la app con pnpm build y la publica en GitHub Pages. La URL https://tu-usuario.github.io/team-builder/ responde y muestra el Team Builder.
  • vite.config.ts tiene base: '/team-builder/' con el nombre exacto del repositorio. GitHub Pages está activado en modo "GitHub Actions" en Settings > Pages.
  • El deploy es automático: un push a main lo dispara sin intervención manual. El dist/ contiene el manifest.json, el service worker y las meta tags del index.html: el build los arrastra.

Cómo hacerlo en local

Clona el repositorio del curso, entra en la carpeta del ejercicio y abre el index.html en tu navegador. Toda tu solución va en solucion.js.

git clone <repo>
cd exercises/nivel-9/proyecto-desplegar-el-team-builder
# abre index.html en el navegador y edita solucion.js
Ver soluciones
# Tier ok — el mínimo para estar en producción
#
# Un único job hace todo el trabajo: obtiene el código, instala dependencias,
# construye la app y la publica en GitHub Pages.
#
# La app está online y accesible en tu URL de Pages. Eso ya es un logro real.
#
# Límite de este tier: el job no ejecuta lint ni tests antes de construir.
# Si introduces un error de TypeScript, un test roto o una regla de ESLint violada,
# el workflow lo ignora y publica igualmente. Para que el código roto no llegue a
# producción hace falta separar CI y CD en jobs distintos, como hacen los tiers
# siguientes.

name: CI/CD

# Solo se ejecuta en push a main.
# Los pull requests no disparan este workflow: no hay verificación previa al merge.
on:
  push:
    branches:
      - main

# Permisos que GitHub Pages necesita para publicar desde un workflow.
# contents: read permite al job leer el código del repositorio.
# pages: write permite subir el artifact a GitHub Pages.
# id-token: write es necesario para que deploy-pages se autentique con el entorno.
permissions:
  contents: read
  pages: write
  id-token: write

# concurrency evita que dos deploys corran a la vez sobre el mismo entorno de Pages.
# cancel-in-progress: false deja que el deploy en curso termine antes de empezar otro:
# un deploy a medias puede dejar la app en un estado inconsistente.
concurrency:
  group: pages
  cancel-in-progress: false

jobs:
  # Un solo job que construye y despliega sin verificación previa.
  build-and-deploy:
    runs-on: ubuntu-latest

    # environment registra este job como despliegue en el entorno github-pages.
    # GitHub muestra un historial de despliegues y protecciones de entorno aquí.
    environment:
      name: github-pages
      # steps.deployment.outputs.page_url lo devuelve actions/deploy-pages
      # con la URL final donde la app queda publicada
      url: ${{ steps.deployment.outputs.page_url }}

    steps:
      - name: Obtener el código
        uses: actions/checkout@v6

      - name: Instalar pnpm
        uses: pnpm/action-setup@v4
        with:
          version: 9

      - name: Configurar Node.js con caché de pnpm
        uses: actions/setup-node@v6
        with:
          node-version: 24
          cache: 'pnpm'

      - name: Instalar dependencias
        run: pnpm install --frozen-lockfile

      # IMPORTANTE: vite.config.ts debe tener base: '/team-builder/' con el nombre
      # exacto de tu repositorio. Sin esa línea, Vite genera rutas absolutas
      # (/assets/index-xxxx.js) que el navegador resuelve contra la raíz del dominio,
      # no contra el subdirectorio de Pages, y la app carga en blanco con errores 404.
      - name: Construir la app
        run: pnpm build

      # configure-pages prepara el entorno de Pages y calcula la URL base.
      # Debe ejecutarse antes de subir el artifact.
      - name: Configurar GitHub Pages
        uses: actions/configure-pages@v5

      # upload-pages-artifact empaqueta el contenido de dist/ como artifact de Pages.
      # El dist/ ya contiene el manifest.json, el service worker y las meta
      # tags del index.html: el pipeline los arrastra del build, no los toca.
      - name: Subir dist/ como artifact de Pages
        uses: actions/upload-pages-artifact@v4
        with:
          path: dist/

      # deploy-pages publica el artifact en GitHub Pages y devuelve la URL final.
      # id: deployment permite referenciar su output en environment.url más arriba.
      - name: Desplegar en GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v4

Por qué este nivel

  • Un único job hace todo el trabajo: checkout, instalar, construir y publicar. La app está en producción y eso ya es real. Su límite está documentado en el propio fichero: sin lint ni tests antes del build, el código roto llega a producción igual.
  • El límite que separa ok de mejor: el job no ejecuta lint ni tests. Si introduces un error de TypeScript o un test roto, el workflow lo ignora y publica igualmente. Para que el código roto no llegue a producción hace falta separar CI y CD en jobs distintos.