APLICAWEB 4to/Propuesta Intensiva 8 Semanas/Unidad 4/Semana 8
4 hrs guiadas · cierre del curso
semana
08/08

Deployment final y defensa oral en vivo

Última semana del curso: no se agrega código nuevo, se congela lo que ya construiste en las 7 semanas anteriores. Se hace una auditoría final, se etiqueta la versión definitiva en GitHub, y cada alumno sustenta su proyecto completo frente al docente en una defensa oral de 3-5 minutos.

Entregable: el repositorio u4s8-apellidopaterno-apellidomaterno-nombres con su Release v1.0 y su Web Service en https://u4s8-apellidopaterno-apellidomaterno-nombres.onrender.com — sistema completo, público, con login, CRUD y datos reales, defendido en vivo ante el docente.
01

Auditoría final: variables de entorno, backup del .sql, README actualizado

⏱ 0:00–0:30práctica guiada

Antes de "cerrar" el proyecto, tres verificaciones rápidas para no perder nada y dejar todo documentado.

01

Repasar el checklist de seguridad de la Semana 6

El mismo checklist de la Semana 6, ahora como cierre. En el dashboard de Render abre tu servicio u4s7-… → pestaña Environment y confirma los 5 puntos: DEBUG=False; SECRET_KEY propia de producción (distinta a la de tu .env); ALLOWED_HOSTS con tu dominio exacto (sin https://); CSRF_TRUSTED_ORIGINS con tu dirección completa (con https://); y el candado de HTTPS en el navegador. Deben estar las 9 variables (las 5 DB_ más esas 4); si dudas qué lleva cada una, revisa la tabla de la Semana 6, paso 05.6. Las mismas 9 las cargarás en el servicio nuevo u4s8-… del paso 02.

02

Backup de la base de datos

El respaldo se hace desde tu computadora, que está conectada a la misma base de Aiven que usa Render. Opción A (recomendada, no instala nada): Django exporta todos tus usuarios y servicios a un archivo backup_final.json. En la terminal de VS Code, con (venv) activo y en la carpeta que tiene manage.py:

TERMINAL DE VS CODE — PowerShell · con (venv) activo — Opción A: dumpdata
# dumpdata: exporta los datos de tu base (la de Aiven, la misma que usa Render) a un archivo JSON
# -X utf8: obliga a Python a escribir en UTF-8; sin esto, en Windows los acentos y la ñ dañan el archivo y no se puede restaurar
# --natural-foreign / --natural-primary: guarda a los usuarios por su nombre, para que el respaldo funcione en cualquier base
# --exclude ...: deja fuera tablas internas que Django vuelve a crear solo (tipos de contenido, permisos, bitácora del admin y sesiones)
# --output ..\backup_final.json: guarda el archivo en la carpeta de ARRIBA, fuera del repositorio, para que nunca se suba a GitHub
python -X utf8 manage.py dumpdata --natural-foreign --natural-primary --exclude contenttypes --exclude auth.permission --exclude admin.logentry --exclude sessions --indent 2 --output ..\backup_final.json
# Muestra el archivo creado: revisa que la columna Length (tamaño) no sea 0
Get-Item ..\backup_final.json
# Confirma que el respaldo NO quedó dentro del proyecto: backup_final.json no debe aparecer en la lista
git status

El archivo queda en la carpeta que está arriba de tu proyecto (por eso ..\), así git add . nunca lo toma. Cópialo también a una memoria USB o a tu Drive personal. Si algún día necesitas restaurarlo en una base vacía:

TERMINAL DE VS CODE — PowerShell · con (venv) activo — restaurar (solo si hace falta)
# SOLO si algún día se pierden los datos: primero crea las tablas vacías en la base nueva
python manage.py migrate
# loaddata: vuelve a cargar usuarios y servicios desde el respaldo (-X utf8 para leer bien los acentos)
python -X utf8 manage.py loaddata ..\backup_final.json

Opción B (archivo .sql con mysqldump): mysqldump no viene con Python ni con Windows. Descarga de https://dev.mysql.com/downloads/mysql/ el paquete «Windows (x86, 64-bit), ZIP Archive», descomprímelo en C:\mysql (no hace falta instalar ni encender un servidor MySQL) y usa la herramienta que está en C:\mysql\bin. Si al correrla no imprime nada o dice que falta un archivo .dll, instala el «Microsoft Visual C++ Redistributable» (x64) y vuelve a intentar.

TERMINAL DE VS CODE — PowerShell — Opción B: mysqldump (cambia host, puerto y usuario por los de tu .env)
# Confirma que mysqldump funciona: debe imprimir su versión (si descomprimiste en otra carpeta, cambia C:\mysql)
C:\mysql\bin\mysqldump.exe --version
# --single-transaction: copia los datos como estaban en un solo instante, sin bloquear la base (lo recomienda Aiven)
# --set-gtid-purged=OFF: no incluye datos internos de replicación de Aiven (lo recomienda Aiven)
# -h / -P / -u: host, puerto y usuario, los mismos de tu .env · -p: al dar Enter pide la contraseña sin que se vea
# --result-file: escribe el archivo directo; con ">" en PowerShell el archivo sale en otra codificación y no se puede restaurar
# defaultdb: el nombre de tu base (DB_NAME); el archivo queda en la carpeta de arriba, fuera del repositorio
C:\mysql\bin\mysqldump.exe --single-transaction --set-gtid-purged=OFF -h tu-host.aivencloud.com -P 12345 -u avnadmin -p --result-file=..\backup_final.sql defaultdb

Al dar Enter te pide la contraseña: pega la de Aiven (DB_PASSWORD) y da Enter; no se ve mientras la escribes. Si sale Access denied … PROCESS privilege, agrega --no-tablespaces antes de --result-file.

03

Completar el README definitivo

Abre README.md (en la carpeta que tiene manage.py), selecciona todo con Ctrl + A, bórralo, pega esto y completa lo que está entre corchetes. Se sube a GitHub en el paso 02.

README.md — archivo COMPLETO (reemplaza todo)
<!-- título del repo: cambia por tus nombres reales -->
# U4S8 — [Apellido Paterno] [Apellido Materno] [Nombre(s)]

<!-- sección con la URL pública de Render -->
## Demo en vivo (producción)
<!-- tu dirección real de Render de esta práctica -->
https://u4s8-hernandez-nunez-maria-jose.onrender.com

<!-- sección que explica el proyecto a quien lo visite -->
## Qué hace este proyecto
<!-- reemplaza el texto entre corchetes por tu descripción -->
[1-2 párrafos describiendo tu vitrina de servicios]

<!-- sección con las tecnologías usadas -->
## Stack técnico
<!-- las 4 herramientas del curso -->
Django + MySQL (Aiven) + Tailwind CSS + Render

<!-- sección con la prueba de seguridad de la Semana 6 -->
## Cómo se prueba el aislamiento por usuario
<!-- pega aquí la explicación que escribiste en el README de la Semana 6 -->
[Copiar la explicación que ya escribiste en la Semana 6]

<!-- sección con el recorrido del curso -->
## Historial de unidades
<!-- Unidad 1 -->
- Unidad 1: portafolio estático con HTML5 + Tailwind
<!-- Unidad 2 -->
- Unidad 2: modelo Servicio migrado a MySQL, deploy dinámico en Render
<!-- Unidad 3 -->
- Unidad 3: CRUD completo con ModelForms + autenticación y sesiones
<!-- Unidad 4 -->
- Unidad 4: paginación, búsqueda, UI review y defensa final
OJO

Nunca subas backup_final.json ni backup_final.sql a un repositorio público: suele contener datos reales de usuarios (aunque sean de prueba) y credenciales indirectas.

02

Última migración en producción y congelamiento de versión

⏱ 0:30–1:00práctica guiada

Un tag de Git marca un punto exacto del historial como "la versión que se entrega" — así siempre puedes volver a ver (o restaurar) exactamente el código que se defendió hoy.

01

Confirmar que no queda ninguna migración pendiente

TERMINAL DE VS CODE — PowerShell · con (venv) activo
# Lista las migraciones de core en la base de Aiven: todas deben tener [X] (aplicadas)
python manage.py showmigrations core
# migrate sin cambios pendientes no rompe nada; debe responder "No migrations to apply"
python manage.py migrate

En el plan Free de Render no hay pestaña Shell: en producción migrate corre solo, al final del Build Command. Para confirmarlo, abre tu servicio en Render → Logs del último deploy y busca No migrations to apply. Tu compu y Render usan la misma base de Aiven, así que lo que ves aquí es lo mismo que hay en producción.

02

Crear el repositorio u4s8-… y subir los cambios

Cada práctica va en su propio repositorio y en su propio Web Service de Render, con el nombre u4s8-apellidopaterno-apellidomaterno-nombres (minúsculas, sin acentos, ñ → n, espacios → guion). Ej.: u4s8-hernandez-nunez-maria-jose. El repo de la Semana 7 (u4s7-…) se queda intacto como evidencia.

La regla del nombre · siempre igual (repo de GitHub y servicio de Render)

prefijou4s8- apellido paternohernandez- apellido maternonunez- nombre(s)maria-jose
  • Prefijo de la práctica: u + número de unidad + s + número de semana. Esta práctica es u4s8.
  • Todo en minúsculas, sin acentos (á → a), la ñ se escribe n y los espacios se cambian por guion -.
  • Orden fijo: prefijo → apellido paterno → apellido materno → nombre(s). Si tienes dos nombres, van los dos.
  • El mismo nombre se usa en dos lugares: como Repository name en GitHub y como Name del servicio en Render (paso 02.3). Así tu URL queda https://u4s8-….onrender.com.
  • GitHub solo acepta letras sin acento, números, -, _ y . (máximo 100 caracteres). Por eso la regla quita acentos y espacios.
AlumnoNombre del repositorio y del servicio de Render
María José Hernández Núñezu4s8-hernandez-nunez-maria-jose
José Ángel De la Cruz Peñau4s8-de-la-cruz-pena-jose-angel
Ana López (un solo apellido)u4s8-lopez-ana
PrefijoPráctica del curso
u1s1Unidad 1 · Semana 1 — Sitio estático en Render
u1s2Unidad 1 · Semana 2 — Tailwind CSS
u2s3Unidad 2 · Semana 3 — Django + MySQL en Aiven
u2s4Unidad 2 · Semana 4 — Modelos y deploy en Render
u3s5Unidad 3 · Semana 5 — CRUD con ModelForms
u3s6Unidad 3 · Semana 6 — Autenticación y sesiones
u4s7Unidad 4 · Semana 7 — Pulido y defensa
u4s8Unidad 4 · Semana 8 — Deploy final (esta guía)

Genera tu nombre sin errores

Repositorio y servicio de Renderu4s8-hernandez-nunez-maria-jose

Tu repo quedará en https://github.com/TU_USUARIO/u4s8-hernandez-nunez-maria-jose y, con el mismo nombre en Render (paso 02.3), tu sitio en https://u4s8-hernandez-nunez-maria-jose.onrender.com. Los datos de ejemplo están precargados: escribe los tuyos y usa «Copiar nombre».

  1. Entra a https://github.com y confirma arriba a la derecha que es tu cuenta.
  2. Clic en + → New repository. En Repository name pega el nombre que copiaste del generador de arriba (u4s8-…).
  3. Déjalo en Public y no marques «Add a README», «.gitignore» ni «license» (el repo debe nacer vacío). Clic en Create repository y copia la URL que termina en .git.
TERMINAL DE VS CODE — PowerShell · en la carpeta que tiene manage.py
# Muestra a qué repo apunta hoy tu proyecto (debe salir el u4s7-… de la Semana 7)
git remote -v
# Cambia "origin" al repo nuevo de esta práctica; pega TU URL (set-url porque origin ya existe)
git remote set-url origin https://github.com/TU_USUARIO/u4s8-hernandez-nunez-maria-jose.git
# Confirma que ahora apunta al u4s8-… (sale dos veces: fetch y push)
git remote -v
# Lista lo que cambió: NO deben aparecer .env, venv/ ni staticfiles/
git status
# Agrega todos los archivos nuevos y modificados (incluye core/migrations/ si hubo migración)
git add .
# Crea el commit con un mensaje que describe el cambio
git commit -m "U4S8: version final del curso (README definitivo)"
# Sube la rama main al repo nuevo; -u la deja vinculada para que después baste con "git push"
git push -u origin main

Recarga la página del repo en GitHub: deben verse manage.py, requirements.txt, manage.py, core/views.py y tus plantillas. Si ves .env, avisa al profesor antes de seguir (hay que cambiar la contraseña de Aiven).

03

Crear el Web Service en Render, campo por campo

  1. Abre https://dashboard.render.com e inicia sesión con GitHub.
  2. Arriba a la derecha: + New → Web Service. No elijas «Static Site».
  3. En «Source Code» elige Git Provider, busca tu repo u4s8-… (no el u4s7-…) y clic en Connect.
  4. Si el repo no aparece: clic en Configure GitHub, en «Repository access» agrega u4s8-…, guarda y regresa a Render.

Llena solo estos campos; el resto déjalo como viene:

CampoQué escribirPor qué
NameEl mismo nombre del repo, el que copiaste del generador (ej. u4s8-hernandez-nunez-maria-jose)Se vuelve tu dirección: https://u4s8-hernandez-nunez-maria-jose.onrender.com. Anótala; la usas en 02.4.
LanguagePython 3Render lo detecta por requirements.txt; si no, elígelo.
BranchmainCada git push a esta rama redespliega solo.
RegionLa que venga (ej. Oregon (US West))Dónde está el servidor. Cualquiera sirve.
Root DirectoryVacíoSolo se llena si manage.py está en una subcarpeta (ej. backend).
Build CommandEl del bloque de abajoSe corre una vez en cada deploy: instala, junta estáticos y migra.
Start CommandEl del bloque de abajoSe queda corriendo siempre para atender visitas.
Instance TypeFreeGratis; alcanza para el curso.
RENDER — campo «Build Command» (en una sola línea)
# 1) instala requirements.txt  2) junta los estáticos para whitenoise  3) aplica migraciones en Aiven; "&&" = "si el anterior salió bien, sigue"
pip install -r requirements.txt && python manage.py collectstatic --noinput && python manage.py migrate
RENDER — campo «Start Command»
# arranca gunicorn con miproyecto/wsgi.py; cambia "miproyecto" por la carpeta que tiene settings.py
gunicorn miproyecto.wsgi

¿Qué va en lugar de miproyecto? En VS Code abre settings.py, busca con Ctrl + F WSGI_APPLICATION y copia lo que está antes de .application. Ej.: WSGI_APPLICATION = 'miproyecto.wsgi.application' → gunicorn miproyecto.wsgi. Es el mismo Start Command que usaste desde la Semana 4.

04

Las 9 variables de entorno: nombre, valor y de dónde sale

Render no tiene tu .env (no se sube a GitHub). En el mismo formulario baja a «Environment Variables». Los nombres (Key) deben escribirse exactamente así, en mayúsculas, porque settings.py los busca con config('NOMBRE'):

Key (nombre exacto)Value (qué debe tener)De dónde lo sacas
DB_NAMENombre de la base, normalmente defaultdbAiven → tu servicio MySQL → Overview → «Database name». Igual que en tu .env.
DB_USERUsuario de MySQL, normalmente avnadminAiven → Overview → «User». Igual que en tu .env.
DB_PASSWORDLa contraseña real de AivenAiven → Overview → «Password» (icono del ojo). Igual que en tu .env.
DB_HOSTEl host, termina en .aivencloud.com, sin https://Aiven → Overview → «Host». Igual que en tu .env.
DB_PORTUn número de 5 dígitos (ej. 12345), no 3306Aiven → Overview → «Port». Igual que en tu .env.
SECRET_KEYUna clave larga nueva, distinta de la localSe genera en la terminal de VS Code (bloque de abajo). No la reutilices.
DEBUGFalse (con F mayúscula)En producción siempre False. En tu .env local va True.
ALLOWED_HOSTSu4s8-hernandez-nunez-maria-jose.onrender.comTu dominio de Render: sin https:// y sin / al final.
CSRF_TRUSTED_ORIGINShttps://u4s8-hernandez-nunez-maria-jose.onrender.comLa dirección completa: con https:// y sin / al final. Sin ella, el registro, el login y los formularios del CRUD dan «403 CSRF».
TERMINAL DE VS CODE — generar la SECRET_KEY de producción
# Imprime una clave aleatoria de ~67 caracteres; cópiala completa y pégala como valor de SECRET_KEY en Render
python -c "import secrets; print(secrets.token_urlsafe(50))"

Para cargarlas tienes dos formas: rápida, clic en Add from .env, pega el bloque de abajo con tus valores y clic en Add variables; o manual, clic 9 veces en + Add Environment Variable escribiendo Key y Value.

RENDER — «Add from .env» (cambia TODOS los valores por los tuyos)
# nombre de la base de Aiven (cópialo de tu .env local)
DB_NAME=defaultdb
# usuario de Aiven (cópialo de tu .env local)
DB_USER=avnadmin
# contraseña real de Aiven (cópiala de tu .env local)
DB_PASSWORD=tu-password-real-de-aiven
# host real de Aiven, sin https:// (cópialo de tu .env local)
DB_HOST=tu-host-real.aivencloud.com
# puerto real de Aiven (cópialo de tu .env local)
DB_PORT=12345
# clave NUEVA generada con el comando de arriba, solo para Render
SECRET_KEY=pega-aqui-la-clave-nueva
# en producción SIEMPRE False
DEBUG=False
# tu dominio de esta práctica: SIN https:// y SIN / al final
ALLOWED_HOSTS=u4s8-hernandez-nunez-maria-jose.onrender.com
# tu dirección completa: CON https:// y SIN / al final
CSRF_TRUSTED_ORIGINS=https://u4s8-hernandez-nunez-maria-jose.onrender.com
OJO

En «Add from .env» Render puede tomar las líneas que empiezan con # como comentarios, pero para no arriesgarte pega solo las 9 líneas NOMBRE=valor, sin los comentarios. Sin espacios antes ni después del =, y sin comillas.

TIP

Si el nombre ya estaba ocupado, Render le agrega letras (ej. u4s8-...-a1b2.onrender.com). Al terminar, copia la dirección real que aparece debajo del nombre del servicio y corrige ALLOWED_HOSTS y CSRF_TRUSTED_ORIGINS en la pestaña Environment → Edit → Save, rebuild, and deploy.

05

Desplegar y leer el log

Clic en Deploy Web Service. Tarda de 2 a 5 minutos. En el log debes ver, en este orden:

LOG DE RENDER — lo que significa cada línea
# 1. Render descarga tu repo u4s8-… de GitHub
==> Cloning from https://github.com/tu-usuario/u4s8-hernandez-nunez-maria-jose
# 2. empieza tu Build Command
==> Running build command 'pip install -r requirements.txt && ...'
# 3. pip instaló Django, PyMySQL, gunicorn, whitenoise, python-decouple...
Successfully installed Django-5.1.4 PyMySQL-1.1.1 gunicorn-23.0.0 ...
# 4. collectstatic juntó tus CSS/JS e imágenes
127 static files copied to '/opt/render/project/src/staticfiles', 381 post-processed.
# 5. migrate se conectó a Aiven; si no cambiaste modelos, no hay nada pendiente (correcto)
No migrations to apply.
# 6. el build terminó bien
==> Build successful 🎉
# 7. arranca tu Start Command
==> Running 'gunicorn miproyecto.wsgi'
# 8. el estado cambia a "Live" en verde: tu sitio ya responde
==> Your service is live 🎉
Error en el log o en el navegadorCausaSolución
SECRET_KEY not found (u otra variable)Falta una variable o el nombre tiene un error de dedoPestaña Environment: revisa las 9 y sus nombres exactos.
ModuleNotFoundError: No module named 'miproyecto'Start Command con otro nombre de carpetaSettings → «Start Command»: corrígelo (ver 02.3).
Can't connect to MySQL server / Access deniedAlgún DB_ mal copiado o Aiven apagadoCompara con tu .env y revisa que Aiven diga «Running».
Bad Request (400) al abrir la páginaALLOWED_HOSTS no coincide con tu dominioCorrígelo sin https:// y sin /.
Prohibido (403) · CSRF verification failed al guardar un formularioFalta o está mal CSRF_TRUSTED_ORIGINSDebe ser https://tu-dominio.onrender.com, sin / final.
TemplateDoesNotExist: core/login.htmlEl template no se subió o tiene otro nombreRevisa en GitHub la carpeta core/templates/core/.
Table '...core_servicio' doesn't exist / Unknown columnCambiaste el modelo y no se subió la migraciónRepite 02.1 y sube core/migrations/ con git push.
Al entrar a /servicios/ sin sesión manda a /accounts/login/ (404)Falta LOGIN_URL en settings.pyAgrega LOGIN_URL = 'login' (Semana 6, paso 03) y haz git push.

Después de corregir algo en Environment, Render redespliega solo. Si corregiste código, haz git push; o usa Manual Deploy → Deploy latest commit.

06

Probar la versión final en producción

  1. Abre https://u4s8-tus-apellidos-nombres.onrender.com/servicios/: debe pedirte iniciar sesión y, al entrar, mostrar tus servicios con paginación y búsqueda (Semana 7).
  2. Prueba una vez el ciclo completo: crear, editar y eliminar un servicio; cerrar sesión; registrarte con una cuenta nueva y confirmar que no ve tus datos.
  3. Confirma el candado de HTTPS y que /no-existe/ muestra un «Not Found» simple, sin la página amarilla de Django.
  4. Esta es la URL que vas a mostrar en la defensa (paso 03). Ábrela un par de minutos antes: en el plan Free, Render «duerme» el sitio tras 15 minutos sin visitas.
07

Crear un tag anotado con la versión final

Hazlo después de que el push del README esté en GitHub y el deploy diga «Live»: el tag marca exactamente ese último commit.

TERMINAL DE VS CODE — PowerShell · en la carpeta que tiene manage.py
# Confirma que origin apunta al repo u4s8-… (el de esta práctica): el tag se sube ahí
git remote -v
# -a: crea un tag "anotado" (con mensaje y fecha) · v1.0: nombre estándar de una versión final · -m: mensaje descriptivo
git tag -a v1.0 -m "Version final entregada - Unidad 4, Semana 8"
# Muestra los tags que existen en tu proyecto; debe aparecer v1.0
git tag
# push del tag: por defecto git push NO sube los tags, hay que pedirlo explícitamente
git push origin v1.0
08

Publicar un Release en GitHub

En tu repositorio u4s8-… de GitHub: en la columna derecha, sección "Releases" → "Draft a new release" → elige el tag v1.0 → completa un título (ej. "Entrega final del curso") y una breve descripción → "Publish release".

TIP

Un Release con tag es la forma profesional de decir "esta es la versión oficial 1.0" — es exactamente lo que verías en cualquier proyecto de software real antes de entregarlo a un cliente.

03

Defensa oral express por alumno (3-5 min): estructura y timing

⏱ 1:00–3:30defensa oral

Cada alumno pasa por turno. Es el mismo guion de 4 bloques que preparaste y ensayaste en la Semana 7 — hoy se presenta ante el docente, con posible live coding y preguntas conceptuales de cualquiera de las 4 Unidades.

0:00

Mostrar la URL de producción (u4s8-…)

Abre la vitrina publicada, muestra el candado de HTTPS y recorre el listado (con paginación y búsqueda de la Semana 7).

1:00

Recitar el guion de 2 minutos de la Semana 7

Qué hace el sistema, qué decisiones técnicas tomaste y por qué, un desafío real que resolviste.

3:00

Live coding o pregunta conceptual (a criterio del docente)

Puede ser cualquiera de los retos ya practicados en el simulacro de la Semana 7, sobre cualquiera de las 4 Unidades.

4:30

Cierre

Muestra el Release v1.0 en GitHub como evidencia final de la entrega.

OJO

La calificación final aplica la Matriz de Evaluación Anti-IA completa: Live Coding 40%, examen conceptual 25%, commits 20%, entregable publicado 15% — repasa la lista de cotejo de las 3 Unidades técnicas si te queda alguna duda puntual.

04

Retroalimentación grupal y cierre del curso

⏱ 3:30–4:00cierre

Los últimos 30 minutos son para el grupo completo, no para un alumno individual.

01

Ronda de retroalimentación

El docente comparte patrones observados en las 8 semanas (errores comunes, buenas prácticas destacadas) sin señalar proyectos individuales.

02

Repaso del camino completo

De un portafolio HTML estático (Semana 1) a una aplicación Django con MySQL, CRUD y autenticación en producción (Semana 8) — el mismo proyecto, creciendo unidad por unidad.

03

Portafolio final para compartir

Con la plantilla de portafolio (Anexo D), arma una página con los 8 enlaces del curso — lista para compartir en LinkedIn o con reclutadores.

05

Entregar el portafolio final

Marca cada punto a medida que lo completas — queda guardado en este navegador.

0/7

Entrega final del curso

01

Último push

TERMINAL DE VS CODE — PowerShell
# Revisa que no haya cambios sin subir (debe decir "nothing to commit, working tree clean")
git status
# Solo si cambiaste algo después del tag: prepara el README modificado
git add README.md
# Guarda el cambio con su mensaje
git commit -m "README final: cierre del curso"
# Sube el commit al repo u4s8-…; Render redespliega solo
git push
02

Entregar

Pega en la tarea final del curso: el enlace del Release v1.0 (ej. https://github.com/tu-usuario/u4s8-hernandez-nunez-maria-jose/releases/tag/v1.0), la URL pública de Render (ej. https://u4s8-hernandez-nunez-maria-jose.onrender.com) y el enlace de tu portafolio final.

de dónde sale esto GitHub Docs: Managing releases
06

Tabla de referencias — de dónde sale toda la información

Todo lo de esta guía viene de documentación oficial de cada herramienta, no de blogs de terceros.

HerramientaPara quéDónde
MySQL — mysqldump Exportar un respaldo completo de la base de datos dev.mysql.com — mysqldump
Aiven — Backup y restore Respaldos automáticos ya incluidos en el servicio gestionado aiven.io — Backup/restore
Django — Deployment checklist Repaso final de configuración segura de producción docs.djangoproject.com — Deployment checklist
Git — Tagging Marcar un punto exacto del historial como versión final git-scm.com — Tagging
GitHub — Releases Publicar una versión oficial del proyecto docs.github.com — Releases