clase:daw:daw:tema07
Diferencias
Muestra las diferencias entre dos versiones de la página.
| Ambos lados, revisión anteriorRevisión previaPróxima revisión | Revisión previa | ||
| clase:daw:daw:tema07 [2026/10/28 09:57] – borrado - editor externo (Fecha desconocida) 127.0.0.1 | clase:daw:daw:tema07 [2026/10/28 10:18] (actual) – Quitar la sección «Contenedor con Jenkins»: el concepto ya está en la introducción claude | ||
|---|---|---|---|
| Línea 1: | Línea 1: | ||
| + | ====== 7. GitHub: Actions y gh ====== | ||
| + | |||
| + | |||
| + | ===== Introducción ===== | ||
| + | |||
| + | * [[https:// | ||
| + | * [[https:// | ||
| + | * [[https:// | ||
| + | |||
| + | El despliegue continuo es desplegar las aplicaciones web lo más pronto posible: cada cambio que se sube al repositorio acaba en el servidor sin que nadie tenga que hacerlo a mano. | ||
| + | |||
| + | Para eso se usa un **servidor de automatización**: | ||
| + | |||
| + | - Descargar el código del repositorio. | ||
| + | - Compilarlo y pasar los tests. | ||
| + | - Construir la imagen Docker. | ||
| + | - Conectarse al servidor y arrancar la nueva versión. | ||
| + | |||
| + | Si un paso falla, se para ahí y avisa: lo que no compila o no pasa los tests no llega al servidor. | ||
| + | |||
| + | Los dos que vamos a ver son: | ||
| + | * [[https:// | ||
| + | * [[https:// | ||
| + | |||
| + | ^ ^ Jenkins ^ GitHub Actions ^ | ||
| + | | Dónde se ejecuta | En un servidor nuestro | En máquinas de GitHub | | ||
| + | | Hay que instalarlo y mantenerlo | ✓ | | | ||
| + | | Dónde se escriben los pasos | En Jenkins | En el repositorio, | ||
| + | | Sirve para repositorios fuera de GitHub | ✓ | | | ||
| + | |||
| + | Si el proyecto está en GitHub, usa GitHub Actions. | ||
| + | |||
| + | |||
| + | ===== GitHub Actions ===== | ||
| + | Un **workflow** es un fichero YAML dentro de la carpeta '' | ||
| + | |||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | |||
| + | Lo que no debe estar en el repositorio (contraseñas, | ||
| + | |||
| + | <note important> | ||
| + | |||
| + | <note important> | ||
| + | |||
| + | Para desplegar el proyecto Java, hay que añadir al repositorio el fichero '' | ||
| + | |||
| + | <sxh yml> | ||
| + | name: Desplegar | ||
| + | |||
| + | on: | ||
| + | workflow_dispatch: | ||
| + | push: | ||
| + | branches: | ||
| + | - master | ||
| + | |||
| + | jobs: | ||
| + | vpn_job: | ||
| + | runs-on: ubuntu-latest | ||
| + | steps: | ||
| + | - name: Checkout repo | ||
| + | uses: actions/ | ||
| + | |||
| + | |||
| + | - name: Configurar la VPN | ||
| + | working-directory: | ||
| + | run: | | ||
| + | sudo apt-get update && sudo apt-get install -y openvpn openvpn-systemd-resolved | ||
| + | echo "${{ secrets.VPN_CA }}" | base64 --decode > ca.crt | ||
| + | echo "${{ secrets.VPN_USERNAME }}" > credenciales.txt | ||
| + | echo "${{ secrets.VPN_PASSWORD }}" >> credenciales.txt | ||
| + | sed -i " | ||
| + | sed -i " | ||
| + | |||
| + | - name: Connect to VPN | ||
| + | working-directory: | ||
| + | run: sudo openvpn --config vpn-pve.conf --daemon --log openvpn.log | ||
| + | |||
| + | - name: Wait for VPN to establish | ||
| + | run: sleep 10 | ||
| + | |||
| + | - name: Test Connection | ||
| + | working-directory: | ||
| + | run: sudo cat openvpn.log | ||
| + | |||
| + | - name: Test Connection | ||
| + | run: ping -c 2 192.168.59.104 | ||
| + | |||
| + | - name: Run remote script | ||
| + | working-directory: | ||
| + | env: | ||
| + | SSH_PRIVATE_KEY: | ||
| + | run: | | ||
| + | echo " | ||
| + | chmod 600 ./id_rsa | ||
| + | ssh -i ./id_rsa -o StrictHostKeyChecking=no -t ${{ secrets.SERVER_USERNAME }}@192.168.59.104 'sudo rm -rf DesplegarFacturasDocker' | ||
| + | ssh -i ./id_rsa -o StrictHostKeyChecking=no -t ${{ secrets.SERVER_USERNAME }}@192.168.59.104 'sudo git clone https:// | ||
| + | ssh -i ./id_rsa -o StrictHostKeyChecking=no -t ${{ secrets.SERVER_USERNAME }}@192.168.59.104 'sudo chmod 777 -R ./ | ||
| + | ssh -i ./id_rsa -o StrictHostKeyChecking=no -t ${{ secrets.SERVER_USERNAME }}@192.168.59.104 'cd DesplegarFacturasDocker && sudo ./deploy.sh 2>& | ||
| + | </ | ||
| + | |||
| + | Ahora al hacer cualquier cambio en la rama '' | ||
| + | |||
| + | Cada ejecución sale en la pestaña //Actions// del repositorio, | ||
| + | |||
| + | Puedes ver un ejemplo en [[https:// | ||
| + | |||
| + | ===== GitHub CLI ===== | ||
| + | '' | ||
| + | |||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | |||
| + | Se instala con: | ||
| + | |||
| + | * **Windows**: | ||
| + | * **Linux**: '' | ||
| + | * **Mac**: '' | ||
| + | |||
| + | <sxh bash> | ||
| + | gh auth login # GitHub.com, HTTPS, navegador. Guarda también la credencial de git | ||
| + | gh auth status | ||
| + | gh auth refresh -s project | ||
| + | </ | ||
| + | |||
| + | Las órdenes de '' | ||
| + | |||
| + | Más información: | ||
| + | * [[https:// | ||
| + | |||
| + | ==== Issues ==== | ||
| + | GitHub ya trae la etiqueta '' | ||
| + | |||
| + | <sxh bash> | ||
| + | gh label create feature | ||
| + | </ | ||
| + | |||
| + | * Crear un issue. Responde con su URL, que acaba en su número: | ||
| + | <sxh bash> | ||
| + | gh issue create --title "Alta de clientes" | ||
| + | </ | ||
| + | * Listar los issues abiertos: | ||
| + | <sxh bash> | ||
| + | gh issue list | ||
| + | </ | ||
| + | * Ver el título, la descripción y el estado del issue 12: | ||
| + | <sxh bash> | ||
| + | gh issue view 12 | ||
| + | </ | ||
| + | * Ponerle una etiqueta: | ||
| + | <sxh bash> | ||
| + | gh issue edit 12 --add-label bug | ||
| + | </ | ||
| + | * Cerrarlo: | ||
| + | <sxh bash> | ||
| + | gh issue close 12 | ||
| + | </ | ||
| + | |||
| + | <note important> | ||
| + | |||
| + | ==== Workflows ==== | ||
| + | * Lanzar a mano un workflow que tiene '' | ||
| + | <sxh bash> | ||
| + | gh workflow run desplegar.yml | ||
| + | </ | ||
| + | * Seguir en directo el workflow que se acaba de lanzar: | ||
| + | <sxh bash> | ||
| + | gh run watch | ||
| + | </ | ||
| + | * Ver las últimas ejecuciones, | ||
| + | <sxh bash> | ||
| + | gh run list --limit 5 | ||
| + | </ | ||
| + | * Ver solo los pasos que han fallado de una ejecución: | ||
| + | <sxh bash> | ||
| + | gh run view 123456 --log-failed | ||
| + | </ | ||
| + | |||
| + | Un workflow rojo tiene un log largo y la causa está en tres líneas: '' | ||
| + | |||
| + | ===== GitHub Projects ===== | ||
| + | Un **Project** es un tablero de GitHub con los issues del repositorio como tarjetas, repartidas en columnas por su estado: //Todo//, //In Progress// y //Done//. Está en GitHub, en el menú // | ||
| + | |||
| + | {{: | ||
| + | |||
| + | ==== Crear el tablero ==== | ||
| + | |||
| + | Uno por proyecto, desde el menú '' | ||
| + | |||
| + | * En //Start from scratch//, la plantilla **Board**. | ||
| + | |||
| + | {{: | ||
| + | |||
| + | * El nombre del proyecto y, marcado, //Import items from repository// | ||
| + | |||
| + | {{: | ||
| + | |||
| + | * Sale con las tres columnas, //Todo//, //In Progress// y //Done//, las que usan los scripts. | ||
| + | |||
| + | {{: | ||
| + | |||
| + | <note important> | ||
| + | |||
| + | ==== Scripts para los issues ==== | ||
| + | |||
| + | Mover una tarjeta con '' | ||
| + | |||
| + | * **Crear un issue**: lo crea, lo añade al Project (en //Todo//) y responde con su número. La etiqueta, si no se da, es '' | ||
| + | |||
| + | <sxh bash; | ||
| + | #!/bin/bash | ||
| + | # Uso: issue_create.sh " | ||
| + | PROJECT=$(gh api graphql -F owner=' | ||
| + | |||
| + | URL=$(gh issue create --title " | ||
| + | gh project item-add $PROJECT --owner @me --url $URL > /dev/null 2>& | ||
| + | echo $URL | grep -o ' | ||
| + | </ | ||
| + | |||
| + | <sxh bash> | ||
| + | scripts/ | ||
| + | scripts/ | ||
| + | </ | ||
| + | |||
| + | \\ | ||
| + | |||
| + | * **Empezar un issue**: pasa su tarjeta a //In Progress//. | ||
| + | |||
| + | <sxh bash; | ||
| + | #!/bin/bash | ||
| + | # Uso: issue_in_progress.sh N | ||
| + | PROJECT=$(gh api graphql -F owner=' | ||
| + | N=$1 | ||
| + | |||
| + | PROJECT_ID=$(gh project view $PROJECT --owner @me --format json --jq .id) | ||
| + | CAMPO=$(gh project field-list $PROJECT --owner @me --format json --jq ' | ||
| + | OPCION=$(gh project field-list $PROJECT --owner @me --format json --jq ' | ||
| + | TARJETA=$(gh project item-list $PROJECT --owner @me --limit 1000 --format json --jq " | ||
| + | |||
| + | if [ -z " | ||
| + | |||
| + | gh project item-edit --project-id $PROJECT_ID --field-id $CAMPO --single-select-option-id $OPCION --id $TARJETA > /dev/null || { echo "No se ha podido mover la tarjeta del issue #$N"; exit 1; } | ||
| + | echo "Issue #$N en In Progress" | ||
| + | </ | ||
| + | |||
| + | <sxh bash> | ||
| + | scripts/ | ||
| + | </ | ||
| + | |||
| + | \\ | ||
| + | |||
| + | * **Cerrar un issue**: lo cierra y pasa su tarjeta a //Done//. | ||
| + | |||
| + | <sxh bash; | ||
| + | #!/bin/bash | ||
| + | # Uso: issue_close.sh N | ||
| + | PROJECT=$(gh api graphql -F owner=' | ||
| + | N=$1 | ||
| + | |||
| + | PROJECT_ID=$(gh project view $PROJECT --owner @me --format json --jq .id) | ||
| + | CAMPO=$(gh project field-list $PROJECT --owner @me --format json --jq ' | ||
| + | OPCION=$(gh project field-list $PROJECT --owner @me --format json --jq ' | ||
| + | TARJETA=$(gh project item-list $PROJECT --owner @me --limit 1000 --format json --jq " | ||
| + | |||
| + | if [ -z " | ||
| + | |||
| + | gh issue close $N > /dev/null 2>&1 | ||
| + | gh project item-edit --project-id $PROJECT_ID --field-id $CAMPO --single-select-option-id $OPCION --id $TARJETA > /dev/null || { echo "No se ha podido mover la tarjeta del issue #$N"; exit 1; } | ||
| + | echo "Issue #$N cerrado y en Done" | ||
| + | </ | ||
| + | |||
| + | <sxh bash> | ||
| + | scripts/ | ||
| + | </ | ||
| + | |||
| + | ===== Ejercicios ===== | ||
| + | |||
| + | ==== Ejercicio 1 ==== | ||
| + | Añade al repositorio de tu código fuente de Java una acción de //GitHhub Actions// que sea para desplegar. | ||
| + | |||
| + | Se ejecutará: | ||
| + | * Manualmente | ||
| + | * Cuando haya un cambio en '' | ||
| + | |||
| + | ==== Ejercicio 2 ==== | ||
| + | * Instala '' | ||
| + | * En tu repositorio de Java, crea la etiqueta '' | ||
| + | * Lanza a mano el workflow del ejercicio 1 con '' | ||
| + | |||
| + | ==== Ejercicio 3 ==== | ||
| + | * Crea el tablero del repositorio como en [[# | ||
| + | * Copia los tres scripts en la carpeta '' | ||
| + | * Crea un issue con '' | ||
