diff --git a/cursos/git/01_git/03_practica_guiada.md b/cursos/git/01_git/03_practica_guiada.md
index 0153830f..cfdd4708 100755
--- a/cursos/git/01_git/03_practica_guiada.md
+++ b/cursos/git/01_git/03_practica_guiada.md
@@ -11,7 +11,7 @@ A continuación imos a instalar Git nos diferentes tipos de SO. Temos varios mod
Para instalar Git en Windows temos dous opcións principalmente:
1. **mysisGit**: debemos ir ó seguinte enlace [Git para Windows](https://git-scm.com/download/win), escoller a noso instalador ou tipo de instalador e proceder ca descarga.
-2. **Github para Windows** é outra forma de instalar Git no noso equipo Windows. Este instalador a maiores do CLI inclúe unha interfaz de usuario moi completa e intuitiva, que pode facilitar moito o traballo.
+2. **GitHub para Windows** é outra forma de instalar Git no noso equipo Windows. Este instalador a maiores do CLI inclúe unha interfaz de usuario moi completa e intuitiva, que pode facilitar moito o traballo.
> Para comezar e mellor empezar co CLI de Git para familiarizarnos cos comandos.
@@ -67,7 +67,7 @@ Vamos a ver as formas máis comúns:
$ sudo port install git
```
-4. Instalador de Git en OS X no sitio web de [Github Desktop](https://desktop.github.com/).
+4. Instalador de Git en OS X no sitio web de [GitHub Desktop](https://desktop.github.com/).
### 1.4 Instalaión en VSCode
diff --git a/cursos/git/02_hands_on/03_remote_repo.md b/cursos/git/02_hands_on/03_remote_repo.md
index b53ad602..f5a8d23c 100644
--- a/cursos/git/02_hands_on/03_remote_repo.md
+++ b/cursos/git/02_hands_on/03_remote_repo.md
@@ -16,9 +16,9 @@ Algunhas das forxas de código aberto máis coñecidas son:
- **[Gitea](https://gitea.io/en-us/)**: oferta servizos de aloxamento de repositorios Git, xestión de proxectos e control de versións. Tamén é compatible con outros sistemas de control de versións, coma Mercurial ou Subversion.
-Nós ímonos centrar en Github, xa que é a máis utilizada e a que vamos a usar durante o curso. Faremos un recorrido pola documentación que si ou si tes que ler para o bo uso da plataforma.
+Nós ímonos centrar en GitHub, xa que é a máis utilizada e a que vamos a usar durante o curso. Faremos un recorrido pola documentación que si ou si tes que ler para o bo uso da plataforma.
-## Github
+## GitHub
diff --git a/cursos/git/03_prefapp_methodology/02_merge_strategy.md b/cursos/git/03_prefapp_methodology/02_merge_strategy.md
index 0a2a28dc..efec0146 100644
--- a/cursos/git/03_prefapp_methodology/02_merge_strategy.md
+++ b/cursos/git/03_prefapp_methodology/02_merge_strategy.md
@@ -78,7 +78,7 @@ Para realizar un squash en Prefapp, seguimos estes pasos básicos:
2. **Fusionar a rama**: cando estea todo listo e os cambios confirmados na rama, fusiónase a rama de característica á rama principal usando `git merge --squash`, o que crea un único commit con tódolos cambios.
-En github, pódese realizar un squash merge directamente dende a interface gráfica dunha Pull request ó fusionar unha rama de característica na rama principal.
+En GitHub, pódese realizar un squash merge directamente dende a interface gráfica dunha Pull request ó fusionar unha rama de característica na rama principal.
@@ -88,4 +88,4 @@ En github, pódese realizar un squash merge directamente dende a interface gráf
-Documentación de Github sobre as fusións nas PRs: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/incorporating-changes-from-a-pull-request/about-pull-request-merges
+Documentación de GitHub sobre as fusións nas PRs: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/incorporating-changes-from-a-pull-request/about-pull-request-merges
diff --git a/cursos/git/04_workflow/01_what_is_workflow.md b/cursos/git/04_workflow/01_what_is_workflow.md
new file mode 100644
index 00000000..ae7aeccd
--- /dev/null
+++ b/cursos/git/04_workflow/01_what_is_workflow.md
@@ -0,0 +1,288 @@
+
+# Que é un workflow?
+
+Un workflow é unha secuencia automatizada de tarefas ou procesos que se executan de xeito sistemático para completar unha operación específica. Os workflows son esenciais en DevOps e CI/CD (Integración Continua/Entrega Continua), xa que permiten a automatización de procesos repetitivos e aseguran a consistencia e eficiencia no desenvolvemento e despregamento de software.
+
+O concepto de workflow non é novo e evolucionou de xeito significativo ó longo do tempo. Na súa orixe, os workflows utilizábanse en contextos empresariais e administrativos para describir o fluxo de traballo entre distintos departamentos ou etapas dun proceso de negocio. Coa revolución dixital e a evolución do software, os workflows comezaron a ser utilizados no ámbito da tecnoloxía da información para describir a secuencia de tarefas en sistemas informáticos.
+
+Na década de 1990, coa auxe da metodoloxía de desenvolvemento áxil e a necesidade de entregar software de xeito máis rápido e eficiente, os workflows comezaron a ser adoptados no desenvolvemento de software. Esta adopción incrementouse coa chegada de DevOps e CI/CD, onde a automatización de procesos é crucial para a entrega continua de software de alta calidade.
+
+
+## Conceptos xerais
+
+Para comprender mellor os workflows no contexto de DevOps e CI/CD é importante coñecer os seus elementos, parámetros e características principais.
+
+
+### Elementos dun Workflow
+
+1. **Tarefas (Tasks)**: unidades básicas de traballo nun workflow. Cada tarefa representa unha acción específica que debe ser completada. Por exemplo: compilar código, executar probas ou despregar unha aplicación.
+
+2. **Accións (Actions)**: operacións específicas realizadas dentro dunha tarefa. Por exemplo, nunha tarefa de compilación, unha acción podería ser executar un comando de compilación.
+
+3. **Eventos (Events)**: desencadeantes que inician un workflow. Os eventos poden ser internos (por exemplo, un commit do código) ou externos (por exemplo, unha solicitude de pull noutro repositorio).
+
+4. **Condicións (Conditions)**: regras que determinan se unha tarefa ou acción debe ser executada. Poden basearse no estado de tarefas anteriores ou en parámetros específicos.
+
+5. **Parámetros (Parameters)**: valores que se pasan a tarefas ou accións para personalizar o seu comportamento. Por exemplo, o nome dunha rama de código ou unha configuración específica.
+
+6. **Artefactos (Artifacts)**: resultados xerados por unha tarefa que poden ser utilizados en tarefas posteriores. Por exemplo, arquivos binarios xerados por unha tarefa de compilación.
+
+
+### Características dun Workflow
+
+1. **Automatización**: os workflows automatizan tarefas repetitivas, reducindo o esforzo manual e minimizando erros.
+
+2. **Secuencialidade**: os workflows seguen unha secuencia definida de tarefas, asegurando que os procesos se executen na orde correcta.
+
+3. **Paralelismo**: nalgúns casos, os workflows permiten a execución de tarefas en paralelo para mellorar a eficiencia e reducir o tempo total de execución.
+
+4. **Modularidade**: os workflows poden ser deseñados de xeito modular, permitindo reutilizar tarefas ou seccións dun workflow en distintos contextos.
+
+5. **Vixilancia**: os workflows adoitan incluír mecanismos de vixilancia e rexistro (logging) para rastrear o progreso e detectar problemas.
+
+6. **Escalabilidade**: os workflows deben ser capaces de escalar para manexar un maior volume de tarefas a medida que crecen as necesidades do proxecto.
+
+7. **Integración**: os workflows intégranse con outras ferramentas e servizos no ecosistema DevOps, coma sistemas de control de versións, servidores de integración continua e plataformas de despregamento.
+
+
+### Elementos clave en Workflows de CI/CD
+
+1. **Branches**: as ramas de código nas que se executan os workflows, permitindo a integración e proba de características novas sen afectar ó código principal.
+
+2. **Triggers**: os eventos que inician o workflow, coma commits, pull requests, ou despregamentos programados.
+
+3. **Environment Variables**: variables de entorno que proporcionan configuracións específicas ós workflows, coma credenciais de acceso ou rutas de arquivos.
+
+4. **Stages**: fases do workflow que agrupan tarefas relacionadas, coma 'build', 'test', e 'deploy'.
+
+5. **Dependencies**: as dependencias entre tarefas, asegurando que certas tarefas se completen antes de que outras comecen.
+
+Comprender estes conceptos é crucial para deseñar e xestionar workflows eficaces que melloren a eficiencia e calidade no desenvolvemento de software. A correcta implantación de workflows pode supor a diferenza entre un proceso de desenvolvemento áxil e eficiente e un lento e propenso a erros.
+
+
+## Servidores para a automatización
+
+Existen distintos servidores que permiten a automatización de tarefas. Este curso vaise centrar en GitHub Actions, xa que é o máis usado en Prefapp, pero vexamos unha táboa comparativa con outros servidores que tamén usamos.
+
+
+
+
+
+### Outros
+
+- CircleCI: https://circleci.com/
+- Travis CI: https://travis-ci.org/
+- Heroku CI: https://www.heroku.com/continuous-integration
+- TeamCity: https://www.jetbrains.com/teamcity/
+- Bamboo: https://www.atlassian.com/software/bamboo
+- Buddy: https://buddy.works/
+- Codefresh: https://codefresh.io/
+- Concourse: https://concourse-ci.org/
+- Drone: https://drone.io/
+- GoCD: https://www.gocd.org/
+- Spinnaker: https://www.spinnaker.io/
+- Tekton: https://tekton.dev/
+
+Máis info: https://en.wikipedia.org/wiki/Comparison_of_source-code-hosting_facilities
+
+
+### GitHub Actions
+
+Agora, centrándonos en GitHub Actions, imos ver unha descrición básica. Como comentamos, é un servizo de integración continua e entrega continua (CI/CD) que permite automatizar tarefas nun repositorio de GitHub. Baséase na execución de workflows, que son conxuntos de tarefas que se executan nun servidor de GitHub. Os workflows defínense nun arquivo YAML que se almacena no directorio `.github/workflows` do repositorio.
+
+É un servizo gratuíto para repositorios públicos e privados, cun límite de 2000 minutos de execución ó mes para os repositorios privados. Para os repositorios públicos non hai límite de tempo de execución.
+
+GitHub Actions intégrase con GitHub, o que lle permite executar workflows en resposta a eventos de GitHub, como a creación dun pull request, o push dun commit, a creación dun tag, etc. Tamén se poden executar workflows de xeito manual ou programado.
+
+Proporciona un conxunto de accións predefinidas que se poden utilizar nos workflows, así como a posibilidade de crear accións personalizadas.
+
+Tamén existe a posibilidade de crear runners nun servidor propio. Os runners de GitHub son máquinas virtuais aloxadas por GitHub que executan os workflows, pero a posibilidade de configuralos en servidores propio ou na nube pode aportar vantaxes.
+
+No seguinte capítulo imos ver máis en detalle como funcionan os workflows de GitHub Actions e como pode facilitarnos a vida o CI/CD para o desenvolvemento de software propio ou dos nosos clientes.
+
+Enlaces de interés:
+- [GitHub Pricing](https://github.com/pricing)
+- [GitHub Actions Docs](https://docs.github.com/en/actions)
+- [GitHub Marketplace](https://github.com/marketplace?type=actions)
+- [GitHub Runners](https://docs.github.com/en/actions/using-github-hosted-runners/about-larger-runners/about-larger-runners)
diff --git a/cursos/git/04_workflow/02_advanced_github_actions.md b/cursos/git/04_workflow/02_advanced_github_actions.md
new file mode 100644
index 00000000..7acc780a
--- /dev/null
+++ b/cursos/git/04_workflow/02_advanced_github_actions.md
@@ -0,0 +1,318 @@
+
+# GitHub Actions avanzado
+
+
+
+
+Vimos de ver brevemente que son as GitHub Actions, pero agora imos afondar un pouco máis nelas. Neste capítulo exploraremos como se configuran, como se executan e como se poden personalizar para satisfacer necesidades específicas.
+
+GitHub Actions é unha plataforma de integración continua e entrega continua (CI/CD) que automatiza as pipelines de construción, proba e despregamento. Permíteche crear fluxos de traballo que constrúen e proban tódalas pull requests a un repositorio, ou despregar pull requests fusionadas no teu entorno de produción.
+
+Os workflows defínense no directorio .github/workflow do repositorio. Podes definir múltiples workflows, cada un realizando un conxunto diferente de accións. Por exemplo, un workflow pode especificar como crear e probar unha pull request, mentres que outro workflow pode despregar automaticamente unha aplicación cando se crea unha nova release.
+
+Para unha referencia máis detallada, podes consultar a [documentación oficial de GitHub Actions](https://docs.github.com/en/actions/using-workflows).
+
+
+## Conceptos dos workflows en GitHub Actions
+
+### Workflow Triggers
+
+Un trigger de workflow é un evento que fai que se execute un workflow. Hai catro tipos de triggers:
+
+- Eventos no repositorio de GitHub do workflow.
+- Eventos fóra de GitHub, que activan un evento repository_dispatch en GitHub.
+- Un horario predefinido.
+- Trigger manual.
+
+Despois de que se active un workflow, o seu motor executa un ou máis jobs. Cada job contén unha lista predefinida de pasos; un paso pode executar un script definido ou realizar unha acción específica (dunha biblioteca de accións dispoñibles en GitHub Actions). Isto se ilustra no diagrama a continuación.
+
+
+
+O proceso cando se activa un evento é o seguinte:
+
+1. Prodúcese un evento no repositorio. Cada evento ten un SHA de commit e unha referencia de Git (un alias lexible para humanos do hash do commit).
+2. GitHub busca no directorio `.github/workflow` do repositorio arquivos de workflow relacionados co SHA de commit ou a referencia de Git asociada co evento.
+3. Para os workflows con valores que coinciden co evento disparador, actívase a execución do workflow. Algúns eventos requiren que o arquivo do workflow estea na rama predeterminada do repositorio para executarse.
+4. Cada workflow usa a versión do workflow no SHA de commit ou a referencia de Git asociada co evento. Cando se executa o workflow, GitHub configura as variables de entorno `GITHUB_SHA` e `GITHUB_REF` no entorno do launcher.
+
+
+### Workflow Jobs e Concurrency
+
+A execución dun workflow consta dun ou máis jobs que se executan en paralelo. Este é o comportamento predeterminado, pero podes definir dependencias noutros jobs para facer que os jobs executen tarefas secuencialmente. Isto faise utilizando a palabra clave `jobs..needs`.
+
+Podes executar un número ilimitado de tarefas dentro dos límites de uso do teu workflow. Para evitar que se executen demasiados jobs simultaneamente, podes usar `jobs..concurrency` para asegurar que só un job ou workflow no mesmo grupo de concorrencia se execute ó mesmo tempo. O nome dun grupo de concorrencia pode usar calquera cadea ou expresión, excepto segredos.
+
+Se un job ou workflow concorrente está na cola e outro job ou workflow está en progreso, a tarefa ou workflow na cola ponse en espera e calquera tarefa ou workflow previamente suspendido no grupo de concorrencia se cancela.
+
+
+
+## Exemplos de Workflows de GitHub Actions: sintaxe e comandos
+
+### Sintaxe das GitHub Actions
+
+Os workflows en GitHub Actions escríbense en sintaxe YAML. Polo tanto, os arquivos de workflow teñen unha extensión .yml ou .yaml.
+
+Recorda: os arquivos de workflow deben almacenarse nun directorio dedicado no repositorio chamado `.github/workflows.`
+
+#### name
+
+Utilízase para establecer o nome do workflow, dos jobs ou dos steps. GitHub Actions amosa este nome na pestana de accións do repositorio. Se falta o name, Actions amosará a ruta relativa do arquivo de workflow dende o directorio raíz do repositorio. Pódense usar emojis para agregar un toque identificador e colorido, facéndoos máis visuais.
+
+Por exemplo, o nome dun workfow establécese colocando a seguinte liña ó comezo do arquivo:
+
+```yaml
+name: demo-github-actions-workflow 🧪
+```
+
+O job, coa identificación adecuada, establécese do seguinte xeito:
+
+```yaml
+jobs:
+ build:
+ name: Build 🏗
+ runs-on: ubuntu-latest
+```
+
+E o step, tamén coa identificación axeitada:
+
+```yaml
+steps:
+ - name: Install dependencies 🔌
+ run: npm install
+```
+
+
+#### on
+
+Utilízase para especificar o evento ou os eventos (triggers) que activan automaticamente o workflow. Pode tomar un ou múltiples eventos coma triggers. Ademais, pode restrinxir os triggers a arquivos específicos, cambios de rama ou etiquetas.
+
+Exemplos:
+
+A seguinte liña activa o workflow cada vez que hai un push no repositorio:
+
+```yaml
+on: push
+```
+
+A seguinte liña activa o workflow cando hai un push ou o repositorio é bifurcado:
+
+```yaml
+on: [fork, push]
+```
+
+Se se producen múltiples eventos simultaneamente, o workflow se activa múltiples veces.
+
+O seguinte exemplo amosa como especificar a actividade do evento e o tipo de actividade para activar un workflow:
+
+```yaml
+on:
+ branch_protection_rule:
+ types:
+ - edited
+```
+
+Aquí, o workflow execútase cada vez que se cambia a regra de protección da rama do repositorio. O trigger pode ser múltiples tipos de actividade do seguinte xeito:
+
+```yaml
+on:
+ branch_protection_rule:
+ types:
+ - edited
+ - created
+```
+
+Isto executa os workflows dúas veces cando un usuario crea unha nova regra de protección de rama e a agrega.
+
+O seguinte exemplo amosa como usar os filtros de eventos e activar o workflow só cando o evento ten certos aspectos específicos:
+
+```yaml
+on:
+ pull_request:
+ types:
+ - assigned
+ branches:
+ - 'demo-branch/**'
+```
+
+O seguinte exemplo amosa como o workflow pode executarse só para certos tipos de arquivos usando o filtro paths:
+
+```yaml
+on:
+ push:
+ paths:
+ - '**.py'
+```
+
+O workflow se activará cada vez que se suba un arquivo Python ó repositorio.
+
+
+#### defaults
+
+Utilízase para especificar a configuración predeterminada do workflow. Se se especifica baixo un job concreto, só se aplica ó job. En caso contrario, especifica configuracións para tódolos jobs.
+
+A shell predeterminada para os comandos no workflow e o directorio que contén os scripts que se deben executar especifícanse do seguinte xeito:
+
+```yaml
+defaults:
+ run:
+ shell: bash
+ working-directory: demo-workflow-scripts
+```
+
+#### jobs
+
+Utilízase para especificar as accións que realiza o workflow. Pode ter múltiples jobs baixo el, e cada job pode ter o seu propio alcance, conxunto de accións e jobs dependentes.
+
+Exemplos de comandos:
+
+Cada job dentro do bloque de jobs precisa un identificador único que debe ser unha cadea única e conter só -, _, e caracteres alfanuméricos:
+
+```yaml
+jobs:
+ first_demo_job:
+ name: The first demo job
+ second_demo_job:
+ name: The second demo job
+```
+
+As accións dun job se especifican coa sintaxe steps. Cada step pode ter un nome, as súas propias variables de entorno e comandos a executar:
+
+```yaml
+jobs:
+ first_demo_job:
+ name: The first demo job
+ steps:
+ - name: Show the demo running
+ env:
+ VAR1: This is
+ VAR2: A Demo of
+ VAR3: GitHub Actions
+ VAR4: Workflow jobs
+ run: |
+ echo $VAR1 $VAR2 $VAR3 $VAR4.
+```
+
+
+### Comandos do Workflow
+
+#### Establecer outputs
+
+O comando set-output establece o valor para a saída dunha acción. Unha vez establecido, outros comandos poden usar a saída facendo referencia ó id do job:
+
+```yaml
+- name: Set output parameter
+ run: echo '::set-output name=OUTPUT_PARAM::parameter_set'
+ id: output-parameter-setter
+- name: Get output
+ run: echo "The output parameter is set to ${{ steps.output-parameter-setter.outputs.OUTPUT_PARAM }}"
+```
+
+#### Amosar erros
+
+O comando error escribe mensaxes de erro no rexistro. Toma o nome do arquivo, a posición e a mensaxe coma entradas:
+
+```shell
+echo "::error file=demo-file.js,line=1,col=7,endColumn=9::Missing semicolon"
+```
+
+#### Amosar outputs completos
+
+Os comandos echo::on e echo::off activan e desactivan respectivamente a impresión dos comandos para tódolos comandos seguintes:
+
+```yaml
+jobs:
+ demo-workflow-job:
+ steps:
+ - name: set echoing of commands on and off
+ run: |
+ echo '::set-output name=demo_action_echoing::off'
+ echo '::echo::on'
+ echo '::set-output name=demo_action_echoing::on'
+ echo '::echo::off'
+ echo '::set-output name=action_echo::disabled'
+```
+
+Isto amosará a seguinte saída no rexistro:
+
+```shell
+::set-output name=demo_action_echoing::on
+::echo::off
+```
+
+
+### Titorial rápido: creando workflows de inicio
+
+Os workflows de inicio son modelos de workflows que os usuarios poden personalizar segundo as súas necesidades e pór en uso. GitHub proporciona moitos workflows de inicio para categorías como despregamento continuo, automatización e seguridade para axudar ós usuarios a comezar.
+
+Doc GitHub: https://docs.github.com/en/actions/learn-github-actions/using-starter-workflows
+
+Para crear un novo workflow de inicio:
+
+1. Crea un novo directorio e chámao .github, se aínda non existe.
+2. Crea un directorio dentro do novo directorio e chámao workflow-templates.
+3. Crea un arquivo de workflow e chámao demo-workflow.yml. Pon o seguinte código YAML no arquivo:
+
+ ```yaml
+ Name: Starter Workflow Demo
+
+ on:
+ push:
+ branches: [ $default-branch ]
+ pull_request:
+ branches: [ $default-branch ]
+
+ jobs:
+ build:
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v3
+
+ - name: demo workflow job
+ run: echo This is a demo start workflow
+ ```
+
+4. Crea un arquivo de metadatos dentro de workflow-templates e chámao demo-workflow.properties.json. O nome do arquivo do workflow e o nome do arquivo de metadatos deben ser iguais. Pon o seguinte no arquivo de metadatos:
+
+ ```json
+ {
+ "name": "Starter Workflow Demo",
+ "description": "Demo starter workflow.",
+ "iconName": "demo-icon",
+ "categories": [
+ "Python"
+ ]
+ }
+ ```
+
+Aquí, os metadatos especifican a categoría da linguaxe do workflow de inicio para que un usuario poida atopar este workflow de inicio máis facilmente.
+
+
+## GitOps
+
+GitOps é unha metodoloxía para a xestión da infraestrutura e as aplicacións baseadas en Git. No lugar de depender de ferramentas e procesos manuais, GitOps utiliza repositorios Git coma fonte única para todo o relacionado coa infraestrutura e as aplicacións. Isto inclúe a configuración da infraestrutura, as definicións das aplicacións, os scripts de despregamento e calquera outro artefacto ou recurso que se precise para o ciclo de vida de desenvolvemento e operacións.
+
+
+
+- Lectura recomendada "GitOps: ¿qué es y cuáles son sus ventajas?": https://www.redhat.com/es/topics/devops/what-is-gitops 👀
+- Lista de actions e recursos relacionados: https://github.com/sdras/awesome-actions?tab=readme-ov-file 👀
+
+No seguinte módulo veremos exemplos prácticos GitOps que se utilizan en Prefapp.
diff --git a/cursos/git/04_workflow/03_used_in_prefapp.md b/cursos/git/04_workflow/03_used_in_prefapp.md
new file mode 100644
index 00000000..d2a06b00
--- /dev/null
+++ b/cursos/git/04_workflow/03_used_in_prefapp.md
@@ -0,0 +1,48 @@
+
+# Workflows utilizados en Prefapp
+
+
+
+Xa vimos unha pequena explicación do que é GitOps, agora imos ver graficamente algúns workflows básicos para a automatización do ciclo de vida do software.
+
+1. Créase o código fonte e súbese a un repositorio de código fonte mediante unha Pull Request.
+2. A Pull Request activa un workflow que testea o código fonte.
+3. Ó facer merge da Pull Request se activa un workflow que crea unha imaxe de contedor, a sube a un rexistro de contedores e abre outra Pull Request ó repositorio de Helm.
+4. Cando se crea unha release no repositorio do código, esta dispara un workflow que xerará un documento Changelog e empaqueta a aplicación.
+5. Antes de aplicar a Chart (non ten por que ser xusto antes, podería ser o paso 1), débense aprovisionar os recursos que a aplicación precise mediante Terraform.
+6. Cando se fai o merge da Pull Request aberta no repositorio de Helm (aberta no paso 3) actívase un workflow que desprega a release de Helm.
+
+
+
+
+Xenial! Con isto se automatizou case todo o ciclo de vida do software, dende a creación do código fonte ata o despregamento da aplicación.
+
+
+
+
+
+
+
+
+
+Antes de seguir, é recomendable unha lectura das boas prácticas para crear workflows en GitHub Actions:
+
+- Fortalecer a seguridade en GitHub Actions: https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions 👀
+
+Imos examinar algúns dos workflows máis usados en Prefapp para poder introducirnos no mundo da automatización de GitHub Actions:
+
+- [release-please](./05_release-please.md) (paso 4)
+- [release-pipeline](./07_release-pipeline.md) (paso 4)
+- [build_and_dispatch](./06_build_and_dispatch.md) (paso 3)
+- [PR-verify](./04_pr_verify.md) (paso 2)
+
+---
+
+Repositorio demo para "[Build and dispatch](https://github.com/prefapp/hello-k8s/blob/main/.github/workflows/build_and_dispatch.yaml)" e "[PR verify](https://github.com/prefapp/hello-k8s/blob/main/.github/workflows/pr_verify.yaml)": [hello-k8s](https://github.com/prefapp/hello-k8s/tree/main/.github) 👀
+
diff --git a/cursos/git/04_workflow/08_guided_practice-creating_workflow.md b/cursos/git/04_workflow/08_guided_practice-creating_workflow.md
new file mode 100644
index 00000000..87c90543
--- /dev/null
+++ b/cursos/git/04_workflow/08_guided_practice-creating_workflow.md
@@ -0,0 +1,195 @@
+
+# Práctica guiada - Crear un workflow
+
+Xa vimos distintas opcións avanzadas nos anteriores exemplos de [Workflows utilizados en Prefapp](./04_workflow/03_used_in_prefapp). Agora imos facer unha práctica sinxela que nos servirá para repasar conceptos creando un workflow en GitHub Actions dende 0.
+
+Para comezar, simplemente enviaremos un saúdo á consola que poderemos ver no panel de GitHub Actions. Estará coloreado e se executará en resposta a un evento "pull request". Con esta base, iremos engadindo complexidade.
+
+⚠️ *Recordade que o workflow débese gardar na carpeta* `.github/workflows` *do voso repositorio.*
+
+## Imos aló!
+
+Comezamos co nome, que debe ser descritivo e fácil de identificar:
+
+```yaml
+name: saúdo-cor 🌈
+```
+
+Faremos que o trigger sexa a pull request, pero engadimos tamén a opción manual:
+
+```yaml
+on:
+ pull_request:
+ workflow_dispatch:
+```
+
+Precisamos dunhas variables de entorno para definir cores e unha mensaxe estándar. Estas **variables serán globais** para todo o workflow:
+
+```yaml
+ SAUDO: "Ola "
+ RED: \033[31m
+ GREEN: \033[32m
+ YELLOW: \033[33m
+ BLUE: \033[34m
+ PINK: \033[35m
+ CYAN: \033[36m
+ WHITE: \033[37m
+ NORMAL: \033[0;39m
+```
+
+Agora imos definir algúns aspectos do job que afectarán dentro deste ámbito ós steps que anidemos nel:
+- Nome. [Más info](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#name)
+- Sistema operativo. Asignamos unha Ubuntu latest. [Más info](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idruns-on)
+- Variables de entorno. Imos especificar unha **variable específica para o job**. [Más info](https://docs.github.com/en/actions/learn-github-actions/variables)
+
+```yaml
+jobs:
+ probas:
+ name: Probas 🏗️
+ runs-on: ubuntu-latest
+ env:
+ NOMBRE: "Mundo"
+```
+
+Neste punto xa podemos especificar un step dentro do job. Podemos comezar polo checkout para poder acceder ós arquivos do repositorio:
+
+```yaml
+ steps:
+ - name: Checkout repository 🛎️
+ uses: actions/checkout@v3
+```
+
+E o segundo step será o encargado de enviar o saúdo. Ademais engadimos a data mediante unha **variable que actuará só a nivel de step**:
+
+```yaml
+ steps:
+ - name: Dicir ola 👋
+ run: |
+ echo -e "$RED $SAUDO$NOMBRE. Hoxe é $DIA! red"
+ echo -e "$GREEN $SAUDO$NOMBRE. Hoxe é $DIA! green"
+ echo -e "$YELLOW $SAUDO$NOMBRE. Hoxe é $DIA! yellow"
+ echo -e "$BLUE $SAUDO$NOMBRE. Hoxe é $DIA! blue"
+ echo -e "$PINK $SAUDO$NOMBRE. Hoxe é $DIA! pink"
+ echo -e "$CYAN $SAUDO$NOMBRE. Hoxe é $DIA! cyan"
+ echo -e "$WHITE $SAUDO$NOMBRE. Hoxe é $DIA! white"
+ echo -e "$NORMAL $SAUDO$NOMBRE. Hoxe é $DIA! normal"
+ echo -e "$NORMAL $SAUDO$RED$NOMBRE. $GREEN Hoxe é $YELLOW$DIA! varios $NORMAL"
+
+ env:
+ DIA: "Luns"
+```
+
+Con isto xa vimos cada unha das partes dun workflow básico. Ademais, definimos variables en distintos `scopes` para ver como se comportan.
+
+Se engadimos estes cambios a unha rama e os subimos, poderemos ver que ó crear a pull request dispararase o workflow. Cada cambio que efectuemos na rama, reflectirase na pull request e provocará que se dispare o trigger de novo. Na interface de GitHub Actions vese así:
+
+
+
+Xenial! Imos modificar o workflow para ver algo máis complexo.
+
+## Engadimos complexidade
+
+Imos engadir un step que se execute nun novo runner, en concreto, nun contedor ubuntu 20.04 ([Máis info de standard hosted](https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners/about-github-hosted-runners)). Este runner executarase de xeito paralelo. Simplemente, envía un novo saúdo en cor.
+
+```yaml
+ - name: Executar en paralelo 🐳
+ uses: ubuntu-20.04
+ with:
+ entrypoint: /bin/sh
+ run: echo -e "$GREEN Ola dende un contedor! $NORMAL"
+```
+
+Ademais, imos recoller información do contedor cos comandos `whoami`, `free -h` e `ps aux` para gardalo no ficheiro `info.txt` (gárdase dentro do runner) e o amosaremos.
+
+```yaml
+ - name: Recoller información do contedor 📝
+ with:
+ entrypoint: /bin/sh
+ run: |
+ whoami > info.txt
+ free -h >> info.txt
+ ps aux >> info.txt
+ cat info.txt
+```
+
+
+
+Para poder recuperar o documento info.txt creado debemos engadir un step coa action [upload-artifact@](https://github.com/actions/upload-artifact) que o subirá coma un artefacto que poderemos utilizar dende outros runners.
+
+```yaml
+ - name: Upload info.txt 📤
+ uses: actions/upload-artifact@v4
+ with:
+ name: info
+ path: ./info.txt
+```
+
+Agora imos engadir un novo job que dependa do job `paralelo` para ver como se comporta. Neste caso imos instalar [Bats](https://bats-core.readthedocs.io/en/stable/installation.html), un framework de testing para Bash. Utilizaremos Node.js para instalalo e comprobar a versión.
+
+```yaml
+ check-bats-version:
+ name: Testing Bats 🦇
+ runs-on: ubuntu-latest
+ needs: paralelo
+ steps:
+ - name: Checkout repository 🛎️
+ uses: actions/checkout@v4
+ - name: Setup Node.js 🚀
+ uses: actions/setup-node@v4
+ with:
+ node-version: '20'
+ - name: Install Bats 🦇
+ run: npm install -g bats
+ - name: Check Bats version 🦇
+ run: bats -v
+```
+
+Necesitaremos crear un arquivo `test.bats` na raíz. Para comprobar que temos o ficheiro `info.txt` no novo runner, tan só imos comprobar que existe:
+
+```bash
+@test "Check if the file exists" {
+ run ls info.txt
+ [ "$status" -eq 0 ]
+}
+```
+
+Agora xa podemos incluír no noso workflow outro step para executar o test de Bats.
+
+```yaml
+ - name: Executar test de Bats 🦇
+ run: bats test.bats
+```
+
+E, para finalizar, engadimos un step neste job para descargar o artefacto coa action [download-artifact](https://github.com/actions/download-artifact).
+
+```yaml
+ - name: Download info.txt 📥
+ uses: actions/download-artifact@v4
+ with:
+ name: info
+ path: ./info.txt
+```
+
+
+
+## Visión xeral do workflow
+
+
+
+1. Pódese ver como os jobs `Probas` e `Paralelo` execútanse en paralelo.
+2. Pódese ver a dependencia do job `Check Bats version` do job `Paralelo`.
+3. O artifact que subimos o job `Paralelo` queda no workflow cun ficheiro .zip descargable.
+
+Arquivos:
+- [color-test.yaml](../_media/04_workflow/color-test.yaml)
+- [test.bats](../_media/04_workflow/test.bats)
+
+
+Parabéns! 🎉 Chegaches ó final deste capítulo. Agora podes seguir practicando con outros workflows que che interesen. Algunhas ideas: https://github.com/sdras/awesome-actions/blob/main/ideas.md
+
+## Outros recursos interesantes
+
+- [Actions Runners Controller (ARC)](https://github.com/actions/actions-runner-controller) - operador de Kubernetes que orquestra e escala executores autoaloxados para GitHub Actions.
+- [Dagger](https://dagger.io/) - linguaxe de programación de fluxo de traballo de código aberto que permite ós desarrolladores definir fluxos de traballo de CI/CD coma código. Temos un [curso de Dagger](https://prefapp.github.io/formacion/cursos/dagger/#/) en Prefapp.
+- [GitHub Actions con Docker](https://github.com/marketplace?type=actions&query=docker+) - GitHub Actions ten soporte nativo en Docker, co cal podes probalo en local ou integralo con outras ferramentas como Kubernetes ou Jenkins.
+- [Características avanzadas](https://docs.github.com/en/actions/using-workflows/about-workflows#advanced-workflow-features) - Explora a documentación de Github, que paga moito a pena: almacenamento de segredos, jobs dependentes, matrices de variables, caché, etc
diff --git a/cursos/git/_media/04_workflow/GitHub-Actions-workflow-structure.webp b/cursos/git/_media/04_workflow/GitHub-Actions-workflow-structure.webp
new file mode 100644
index 00000000..9307add2
Binary files /dev/null and b/cursos/git/_media/04_workflow/GitHub-Actions-workflow-structure.webp differ
diff --git a/cursos/git/_media/04_workflow/Workflow.webp b/cursos/git/_media/04_workflow/Workflow.webp
new file mode 100644
index 00000000..ff85562e
Binary files /dev/null and b/cursos/git/_media/04_workflow/Workflow.webp differ
diff --git a/cursos/git/_media/04_workflow/build_dispatch.webp b/cursos/git/_media/04_workflow/build_dispatch.webp
new file mode 100644
index 00000000..1eee4285
Binary files /dev/null and b/cursos/git/_media/04_workflow/build_dispatch.webp differ
diff --git a/cursos/git/_media/04_workflow/cicd.webp b/cursos/git/_media/04_workflow/cicd.webp
new file mode 100644
index 00000000..cf5e0322
Binary files /dev/null and b/cursos/git/_media/04_workflow/cicd.webp differ
diff --git a/cursos/git/_media/04_workflow/color-test.yaml b/cursos/git/_media/04_workflow/color-test.yaml
new file mode 100644
index 00000000..9854e7aa
--- /dev/null
+++ b/cursos/git/_media/04_workflow/color-test.yaml
@@ -0,0 +1,85 @@
+name: saludo-color 🌈
+
+on:
+ pull_request:
+ workflow_dispatch:
+
+env:
+ SALUDO: "Hola "
+ RED: \033[31m
+ GREEN: \033[32m
+ YELLOW: \033[33m
+ BLUE: \033[34m
+ PINK: \033[35m
+ CYAN: \033[36m
+ WHITE: \033[37m
+ NORMAL: \033[0;39m
+
+jobs:
+ pruebas:
+ name: Pruebas 🏗️
+ runs-on: ubuntu-latest
+ env:
+ NOMBRE: Mundo
+
+ steps:
+ - name: Checkout repository 🛎️
+ uses: actions/checkout@v4
+
+ - name: Decir hola 👋
+ run: |
+ echo -e "$RED $SALUDO$NOMBRE. Hoy es $DIA! red"
+ echo -e "$GREEN $SALUDO$NOMBRE. Hoy es $DIA! green"
+ echo -e "$YELLOW $SALUDO$NOMBRE. Hoy es $DIA! yellow"
+ echo -e "$BLUE $SALUDO$NOMBRE. Hoy es $DIA! blue"
+ echo -e "$PINK $SALUDO$NOMBRE. Hoy es $DIA! pink"
+ echo -e "$CYAN $SALUDO$NOMBRE. Hoy es $DIA! cyan"
+ echo -e "$WHITE $SALUDO$NOMBRE. Hoy es $DIA! white"
+ echo -e "$NORMAL $SALUDO$NOMBRE. Hoy es $DIA! normal"
+ echo -e ""$NORMAL $SALUDO$RED$NOMBRE. $GREEN Hoy es $YELLOW$DIA! varios""
+ env:
+ DIA: Lunes
+
+ paralelo:
+ name: Paralelo 🐳
+ runs-on: ubuntu-20.04
+ steps:
+ - name: Checkout repository 🛎️
+ uses: actions/checkout@v4
+
+ - name: Ejecutar en paralelo 🚅
+ run: echo -e "$GREEN Hola desde un contenedor! $NORMAL"
+
+ - name: Recoger información del contenedor 📝
+ run: |
+ whoami > info.txt
+ free -h >> info.txt
+ ps aux >> info.txt
+ cat info.txt
+ - name: Upload info.txt 📤
+ uses: actions/upload-artifact@v4
+ with:
+ name: info
+ path: ./info.txt
+
+ check-bats-version:
+ runs-on: ubuntu-latest
+ needs: paralelo
+ steps:
+ - name: Checkout repository 🛎️
+ uses: actions/checkout@v4
+ - name: Setup Node.js 🚀
+ uses: actions/setup-node@v4
+ with:
+ node-version: '20'
+ - name: Install Bats 🦇
+ run: npm install -g bats
+ - name: Check Bats version 🦇
+ run: bats -v
+ - name: Download info.txt 📥
+ uses: actions/download-artifact@v4
+ with:
+ name: info
+ path: ./info.txt
+ - name: Ejecutar test de Bats 🦇
+ run: bats test.bats
diff --git a/cursos/git/_media/04_workflow/github-actions-workflow-components.webp b/cursos/git/_media/04_workflow/github-actions-workflow-components.webp
new file mode 100644
index 00000000..fe9e3a73
Binary files /dev/null and b/cursos/git/_media/04_workflow/github-actions-workflow-components.webp differ
diff --git a/cursos/git/_media/04_workflow/github_actions.webp b/cursos/git/_media/04_workflow/github_actions.webp
new file mode 100644
index 00000000..8b729263
Binary files /dev/null and b/cursos/git/_media/04_workflow/github_actions.webp differ
diff --git a/cursos/git/_media/04_workflow/gitops-workflow.webp b/cursos/git/_media/04_workflow/gitops-workflow.webp
new file mode 100644
index 00000000..93085e4d
Binary files /dev/null and b/cursos/git/_media/04_workflow/gitops-workflow.webp differ
diff --git a/cursos/git/_media/04_workflow/gitops_prefapp.webp b/cursos/git/_media/04_workflow/gitops_prefapp.webp
new file mode 100644
index 00000000..6a3c87f2
Binary files /dev/null and b/cursos/git/_media/04_workflow/gitops_prefapp.webp differ
diff --git a/cursos/git/_media/04_workflow/jobs_concurrency.webp b/cursos/git/_media/04_workflow/jobs_concurrency.webp
new file mode 100644
index 00000000..7311158b
Binary files /dev/null and b/cursos/git/_media/04_workflow/jobs_concurrency.webp differ
diff --git a/cursos/git/_media/04_workflow/pr-verify.webp b/cursos/git/_media/04_workflow/pr-verify.webp
new file mode 100644
index 00000000..a7ea81df
Binary files /dev/null and b/cursos/git/_media/04_workflow/pr-verify.webp differ
diff --git a/cursos/git/_media/04_workflow/prefapp_wf.webp b/cursos/git/_media/04_workflow/prefapp_wf.webp
new file mode 100644
index 00000000..558097f3
Binary files /dev/null and b/cursos/git/_media/04_workflow/prefapp_wf.webp differ
diff --git a/cursos/git/_media/04_workflow/release-pipeline.webp b/cursos/git/_media/04_workflow/release-pipeline.webp
new file mode 100644
index 00000000..52f27041
Binary files /dev/null and b/cursos/git/_media/04_workflow/release-pipeline.webp differ
diff --git a/cursos/git/_media/04_workflow/test.bats b/cursos/git/_media/04_workflow/test.bats
new file mode 100644
index 00000000..7c464478
--- /dev/null
+++ b/cursos/git/_media/04_workflow/test.bats
@@ -0,0 +1,4 @@
+@test "Check if the file exists" {
+ run ls info.txt
+ [ "$status" -eq 0 ]
+}
diff --git a/cursos/git/_media/04_workflow/workflow-example01.webp b/cursos/git/_media/04_workflow/workflow-example01.webp
new file mode 100644
index 00000000..9111a71a
Binary files /dev/null and b/cursos/git/_media/04_workflow/workflow-example01.webp differ
diff --git a/cursos/git/_media/04_workflow/workflow-example02.webp b/cursos/git/_media/04_workflow/workflow-example02.webp
new file mode 100644
index 00000000..35394b34
Binary files /dev/null and b/cursos/git/_media/04_workflow/workflow-example02.webp differ
diff --git a/cursos/git/_media/04_workflow/workflow-example03.webp b/cursos/git/_media/04_workflow/workflow-example03.webp
new file mode 100644
index 00000000..e1bc4cec
Binary files /dev/null and b/cursos/git/_media/04_workflow/workflow-example03.webp differ
diff --git a/cursos/git/_media/04_workflow/workflow-example04.webp b/cursos/git/_media/04_workflow/workflow-example04.webp
new file mode 100644
index 00000000..ab7809a6
Binary files /dev/null and b/cursos/git/_media/04_workflow/workflow-example04.webp differ
diff --git a/cursos/git/_sidebar.md b/cursos/git/_sidebar.md
index 473143ef..f96d7117 100755
--- a/cursos/git/_sidebar.md
+++ b/cursos/git/_sidebar.md
@@ -13,3 +13,8 @@
- [Estratexia de fusión - Merge vs squash vs rebase vs pull](./03_prefapp_methodology/02_merge_strategy.md)
- [Xestión de proxectos en backlog con GitHub](./03_prefapp_methodology/03_project_management_backlog.md)
- [Práctica guiada: creación de ramas, Pull request e preparación de traballo mediante issues (Projects)](./03_prefapp_methodology/04_Guided_practice-branch-pr-issue.md)
+- Capítulo 4 - Worflows
+ - [Que é un workflow?](./04_workflow/01_what_is_workflow.md)
+ - [GitHub Actions avanzado](./04_workflow/02_advanced_github_actions.md)
+ - [Workflows utilizados en Prefapp](./04_workflow/03_used_in_prefapp.md)
+ - [Práctica guiada - Crear un workflow](./04_workflow/08_guided_practice-creating_workflow.md)
\ No newline at end of file
diff --git a/cursos/git/es/01_git/03_practica_guiada.md b/cursos/git/es/01_git/03_practica_guiada.md
index 079a33d2..5099f9ca 100755
--- a/cursos/git/es/01_git/03_practica_guiada.md
+++ b/cursos/git/es/01_git/03_practica_guiada.md
@@ -11,7 +11,7 @@ A continuación, instalaremos Git en los diferentes tipos de sistemas operativos
Para instalar Git en Windows tenemos dos opciones principales:
1. **mysisGit**: debemos ir al enlace [Git para Windows](https://git-scm.com/download/win), elegir nuestro instalador o tipo de instalador y proceder con la descarga.
-2. **Github para Windows** es otra forma de instalar Git en nuestra computadora con Windows. Este instalador además del CLI incluye una interfaz de usuario muy completa e intuitiva, que puede facilitar mucho el trabajo.
+2. **GitHub para Windows** es otra forma de instalar Git en nuestra computadora con Windows. Este instalador además del CLI incluye una interfaz de usuario muy completa e intuitiva, que puede facilitar mucho el trabajo.
> Lo mejor es comenzar con Git CLI para familiarizarse con los comandos.
@@ -67,7 +67,7 @@ Veamos las formas más comunes:
$ sudo port install git
```
-4. Instalador de Git en OS X en el sitio web [Github Desktop](https://desktop.github.com/).
+4. Instalador de Git en OS X en el sitio web [GitHub Desktop](https://desktop.github.com/).
### 1.4 Instalación en VSCode
diff --git a/cursos/git/es/02_hands_on/03_remote_repo.md b/cursos/git/es/02_hands_on/03_remote_repo.md
index b10a464c..025db2fe 100644
--- a/cursos/git/es/02_hands_on/03_remote_repo.md
+++ b/cursos/git/es/02_hands_on/03_remote_repo.md
@@ -18,7 +18,7 @@ Algunas de las forjas de código abierto más populares son:
Nos vamos a centrar en Github, ya que es la más utilizada y la que vamos a utilizar en el curso. Haremos un recorrido por la documentación que sí o sí tienes que leer para el buen uso de la plataforma.
-## Github
+## GitHub
@@ -44,7 +44,7 @@ Características:
- **[Opción en línea de comandos](https://docs.github.com/es/github-cli)**: GitHub también ofrece una herramienta en línea de comandos (CLI) que permite a los usuarios interactuar con la plataforma de GitHub directamente desde la línea de comandos. La CLI de GitHub admite una amplia gama de comandos y opciones para interactuar con repositorios, problemas, solicitudes de extracción y más.
-Como hemos visto en los anteriores hipervínculos, en la [documentación de Github](https://docs.github.com/es) podrás encontrar multitud de información sobre la plataforma, sus funcionalidades, etc., así como una serie de tutoriales que te pueden ayudar a comenzar con la plataforma y con Git si es tu primera vez. Es interesante revisar la documentación para extraer las buenas prácticas que se recomiendan.
+Como hemos visto en los anteriores hipervínculos, en la [documentación de GitHub](https://docs.github.com/es) podrás encontrar multitud de información sobre la plataforma, sus funcionalidades, etc., así como una serie de tutoriales que te pueden ayudar a comenzar con la plataforma y con Git si es tu primera vez. Es interesante revisar la documentación para extraer las buenas prácticas que se recomiendan.
## Protección de ramas
@@ -60,7 +60,7 @@ Algunas buenas prácticas para proteger las ramas principales son:
- **Limita el acceso a las ramas**: solo los miembros del equipo o los colaboradores que necesiten acceder a una rama deberían tener permiso para hacerlo. Esto se puede lograr a través de la configuración de permisos en GitHub.
-- **Usa herramientas de integración continua**: usa herramientas de integración continua, como Travis CI o CircleCI, para realizar pruebas automáticas en cada commit y pull request. Esto te permitirá detectar y solucionar errores rápidamente. Más adelante veremos las Github Actions.
+- **Usa herramientas de integración continua**: usa herramientas de integración continua, como Travis CI o CircleCI, para realizar pruebas automáticas en cada commit y pull request. Esto te permitirá detectar y solucionar errores rápidamente. Más adelante veremos las GitHub Actions.
- **Limita el acceso a las credenciales**: limita el acceso a las credenciales, como claves SSH o contraseñas de acceso a la cuenta de GitHub. Solo los miembros del equipo que necesiten acceder a estas credenciales deberían tener permiso para hacerlo.
@@ -79,7 +79,7 @@ Repositorio con una colección de plantillas de `.gitignore` para diferentes len
El buen uso de `.gitattributes` implica utilizarlo para establecer los atributos correctos para los archivos del proyecto, de tal manera que se puedan manejar adecuadamente en Git. Por ejemplo, si trabajas en un proyecto que utiliza diferentes sistemas operativos, se puede utilizar `.gitattributes` para establecer el tipo de final de línea que debe ser utilizado, asegurando la compatibilidad entre los diferentes sistemas operativos.
-## Lectura de buenas prácticas en Github
+## Lectura de buenas prácticas en GitHub
diff --git a/cursos/git/es/02_hands_on/05_Guided_practice-Cloning_repo_branch_creation_first_commit_pull_request.md b/cursos/git/es/02_hands_on/05_Guided_practice-Cloning_repo_branch_creation_first_commit_pull_request.md
index 997da830..20dc9fed 100644
--- a/cursos/git/es/02_hands_on/05_Guided_practice-Cloning_repo_branch_creation_first_commit_pull_request.md
+++ b/cursos/git/es/02_hands_on/05_Guided_practice-Cloning_repo_branch_creation_first_commit_pull_request.md
@@ -2,9 +2,9 @@
Hemos pasado por unas largas lecturas teóricas, así que esta práctica será muy corta. En esta práctica guiada vamos a clonar un repositorio, crear una rama, realizar un primer commit y crear un pull request.
-## Crear una cuenta en Github
+## Crear una cuenta en GitHub
-Para poder realizar esta práctica, será necesario tener un usuario en una plataforma para repositorios remotos. Si no lo tienes todavía, puedes crearlo en Github, accediendo a [https://github.com/signup](https://github.com/signup).
+Para poder realizar esta práctica, será necesario tener un usuario en una plataforma para repositorios remotos. Si no lo tienes todavía, puedes crearlo en GitHub, accediendo a [https://github.com/signup](https://github.com/signup).
@@ -16,7 +16,7 @@ Para poder realizar esta práctica, será necesario tener un usuario en una plat
## Crear un nuevo repositorio
-Necesitamos tener un repositorio para poder trabajar sobre él desde nuestra máquina. En Github, los pasos a seguir son:
+Necesitamos tener un repositorio para poder trabajar sobre él desde nuestra máquina. En GitHub, los pasos a seguir son:
- En la esquina superior derecha de cualquier página, seleccionar la opción '+' > New repository.
@@ -91,4 +91,4 @@ Necesitamos tener un repositorio para poder trabajar sobre él desde nuestra má
-Espero que también hayas practicado el resto de los comandos de git que se explican en el [capítulo 2 - Manos a la obra](02_basic_commands.md). La recomendación para este capítulo es que repases una y otra vez la documentación git y de github para poder tener una visión general del trabajo con los repositorios, tanto en local como en remoto.
+Espero que también hayas practicado el resto de los comandos de git que se explican en el [capítulo 2 - Manos a la obra](02_basic_commands.md). La recomendación para este capítulo es que repases una y otra vez la documentación git y de GitHub para poder tener una visión general del trabajo con los repositorios, tanto en local como en remoto.
diff --git a/cursos/git/es/03_prefapp_methodology/02_merge_strategy.md b/cursos/git/es/03_prefapp_methodology/02_merge_strategy.md
index 7c4a993f..10c904e6 100644
--- a/cursos/git/es/03_prefapp_methodology/02_merge_strategy.md
+++ b/cursos/git/es/03_prefapp_methodology/02_merge_strategy.md
@@ -77,7 +77,7 @@ Para realizar un squash en Prefapp, seguimos estos pasos básicos:
2. **Fusionar la rama**: cuando esté todo listo y los cambios confirmados en la rama, se fusiona la rama de características a la rama principal utilizando `git merge --squash`, lo que crea un único commit con todos los cambios.
-En github, se puede realizar un squash merge directamente desde la interfaz gráfica de una Pull Request al fusionar una rama de características en la rama principal.
+En GitHub, se puede realizar un squash merge directamente desde la interfaz gráfica de una Pull Request al fusionar una rama de características en la rama principal.
diff --git a/cursos/git/es/03_prefapp_methodology/03_project_management_backlog.md b/cursos/git/es/03_prefapp_methodology/03_project_management_backlog.md
index cdd63992..9e981876 100644
--- a/cursos/git/es/03_prefapp_methodology/03_project_management_backlog.md
+++ b/cursos/git/es/03_prefapp_methodology/03_project_management_backlog.md
@@ -34,7 +34,7 @@ Las GitHub Issues son una forma de realizar un seguimiento de las tareas, mejora
Si ves alguna necesidad en el código, alguna mejora o, simplemente, un error, puedes abrir una issue en GitHub para que el equipo pueda abordarla. Las issues son una forma efectiva de comunicar y gestionar el trabajo en un proyecto de software. Es importante que refleje **"La motivación"** y los **"Criterios de aceptación"** para que el equipo pueda entender y trabajar en la issue de manera efectiva. También puedes añadir observaciones, dejar la evolución de la tarea, documentación, etc.
-Puedes crear tu propias templates para las issues. Revisa la documentación de Github: https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/configuring-issue-templates-for-your-repository
+Puedes crear tu propias templates para las issues. Revisa la documentación de GitHub: https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/configuring-issue-templates-for-your-repository
## Procedimientos
@@ -73,7 +73,7 @@ En Prefapp, vinculamos nuestras tareas de GitHub Issues con pull requests (PRs)
Al utilizar GitHub Projects de esta manera, podemos mantener un seguimiento claro del trabajo pendiente, colaborar de manera efectiva en el desarrollo de software y garantizar la entrega oportuna de proyectos de alta calidad.
-Además, con las keywords de github, podemos relacionar las issues con las PRs, de manera que se cierre automáticamente la issue al hacer merge de la PR.
+Además, con las keywords de GitHub, podemos relacionar las issues con las PRs, de manera que se cierre automáticamente la issue al hacer merge de la PR.
Doc:
- "Using keywords in issues and pull requests" https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/using-keywords-in-issues-and-pull-requests
diff --git a/cursos/git/es/04_workflow/01_what_is_workflow.md b/cursos/git/es/04_workflow/01_what_is_workflow.md
new file mode 100644
index 00000000..5cca1c70
--- /dev/null
+++ b/cursos/git/es/04_workflow/01_what_is_workflow.md
@@ -0,0 +1,319 @@
+
+# ¿Qué es un workflow?
+
+
+
+Un workflow es una secuencia automatizada de tareas o procesos que se ejecutan de manera sistemática para completar una operación específica. Los workflows son esenciales en DevOps y CI/CD (Integración Continua/Entrega Continua), ya que permiten la automatización de procesos repetitivos y aseguran la consistencia y eficiencia en el desarrollo y despliegue de software.
+
+El concepto de workflow no es nuevo y ha evolucionado significativamente a lo largo del tiempo. Originalmente, los workflows se utilizaban en contextos empresariales y administrativos para describir el flujo de trabajo entre diferentes departamentos o etapas de un proceso de negocio. Con la revolución digital y la evolución del software, los workflows comenzaron a ser utilizados en el ámbito de la tecnología de la información para describir la secuencia de tareas en sistemas informáticos.
+
+En la década de 1990, con el auge de la metodología de desarrollo ágil y la necesidad de entregar software de manera más rápida y eficiente, los workflows comenzaron a ser adoptados en el desarrollo de software. Esta adopción se incrementó con la llegada de DevOps y CI/CD, donde la automatización de procesos es crucial para la entrega continua de software de alta calidad.
+
+
+## Conceptos generales
+
+Para comprender mejor los workflows en el contexto de DevOps y CI/CD, es importante conocer sus elementos, parámetros y características principales.
+
+
+### Elementos de un Workflow
+
+1. **Tareas (Tasks)**: son las unidades básicas de trabajo en un workflow. Cada tarea representa una acción específica que debe ser completada. Por ejemplo, compilar código, ejecutar pruebas, o desplegar una aplicación.
+
+2. **Acciones (Actions)**: son operaciones específicas realizadas dentro de una tarea. Por ejemplo, en una tarea de compilación, una acción podría ser ejecutar un comando de compilación.
+
+3. **Eventos (Events)**: son desencadenantes que inician un workflow. Los eventos pueden ser internos (por ejemplo, un commit de código) o externos (por ejemplo, una solicitud de pull en otro repositorio).
+
+4. **Condiciones (Conditions)**: son reglas que determinan si una tarea o acción debe ser ejecutada. Pueden basarse en el estado de tareas anteriores o en parámetros específicos.
+
+5. **Parámetros (Parameters)**: son valores que se pasan a tareas o acciones para personalizar su comportamiento. Por ejemplo, el nombre de una rama de código o una configuración específica.
+
+6. **Artefactos (Artifacts)**: son los resultados generados por una tarea que pueden ser utilizados en tareas posteriores. Por ejemplo, archivos binarios generados por una tarea de compilación.
+
+
+### Características de un Workflow
+
+1. **Automatización**: los workflows automatizan tareas repetitivas, reduciendo el esfuerzo manual y minimizando errores.
+
+2. **Secuencialidad**: los workflows siguen una secuencia definida de tareas, asegurando que los procesos se ejecuten en el orden correcto.
+
+3. **Paralelismo**: en algunos casos, los workflows permiten la ejecución de tareas en paralelo para mejorar la eficiencia y reducir el tiempo total de ejecución.
+
+4. **Modularidad**: los workflows pueden ser diseñados de manera modular, permitiendo la reutilización de tareas o secciones de un workflow en diferentes contextos.
+
+5. **Monitorización**: los workflows suelen incluir mecanismos de monitorización y registro (logging) para rastrear el progreso y detectar problemas.
+
+6. **Escalabilidad**: los workflows deben ser capaces de escalar para manejar un mayor volumen de tareas a medida que crecen las necesidades del proyecto.
+
+7. **Integración**: los workflows se integran con otras herramientas y servicios en el ecosistema DevOps, como sistemas de control de versiones, servidores de integración continua, y plataformas de despliegue.
+
+
+### Elementos clave en Workflows de CI/CD
+
+1. **Branches**: las ramas de código en las que se ejecutan los workflows, permitiendo la integración y prueba de características nuevas sin afectar el código principal.
+
+2. **Triggers**: los eventos que inician el workflow, como commits, pull requests, o despliegues programados.
+
+3. **Environment Variables**: variables de entorno que proporcionan configuraciones específicas a los workflows, como credenciales de acceso o rutas de archivos.
+
+4. **Stages**: fases del workflow que agrupan tareas relacionadas, como 'build', 'test', y 'deploy'.
+
+5. **Dependencies**: las dependencias entre tareas, asegurando que ciertas tareas se completen antes de que otras comiencen.
+
+Comprender estos conceptos es crucial para diseñar y gestionar workflows eficaces que mejoren la eficiencia y calidad en el desarrollo de software. La correcta implementación de workflows puede significar la diferencia entre un proceso de desarrollo ágil y eficiente y uno lento y propenso a errores.
+
+
+## Servidores para la automatización
+
+Existen diferentes servidores que permiten la automatización de tareas. Este curso se centrará en GitHub Actions, ya que es el más usado en Prefapp, pero veamos en una tabla comparativo con otros servidores que también utilizamos.
+
+
+
+
+
+
+
+
GitHub Actions
+
Gitlab CI/CD
+
Jenkins
+
Apache Airflow
+
Azure DevOps
+
AWS CodePipeline
+
Google Cloud Build
+
Bitbucket Pipelines
+
+
+
+
+
Logo
+
+
+
+
+
+
+
+
+
+
+
Empresa propietaria
+
GitHub (Microsoft)
+
Gitlab Inc.
+
Comunidad Open Source
+
Apache Software Foundation
+
Microsoft
+
Amazon Web Services
+
Google
+
Atlassian
+
+
+
Primera release
+
2018
+
2015
+
2011
+
2014
+
2018
+
2015
+
2018
+
2016
+
+
+
Tipo de software
+
Freemium
+
Freemium
+
Open Source
+
Open Source
+
Freemium
+
Privativo
+
Privativo
+
Freemium
+
+
+
Licencia
+
Copyright
+
Licencia MIT
+
Licencia MIT
+
Apache License 2.0
+
Copyright
+
Copyright
+
Copyright
+
Proprietary
+
+
+
Hosting
+
Cloud
+
Cloud o self-hosted
+
Self-hosted
+
Self-hosted
+
Cloud
+
Cloud
+
Cloud
+
Cloud
+
+
+
Instalación
+
No requiere instalación
+
Opción de instalación self-hosted
+
Requiere instalación
+
Requiere instalación
+
No requiere instalación
+
No requiere instalación
+
No requiere instalación
+
No requiere instalación
+
+
+
Prerrequisitos
+
Cuenta de GitHub
+
Cuenta de Gitlab
+
Servidor propio (1 CPU, 1GB RAM)
+
Servidor propio (4 CPU, 8GB RAM)
+
Cuenta de Azure
+
Cuenta de AWS
+
Cuenta de Google Cloud
+
Cuenta de Bitbucket
+
+
+
Bases de datos
+
No requiere
+
No requiere
+
Opcional
+
Opcional
+
No requiere
+
No requiere
+
No requiere
+
No requiere
+
+
+
Escalabilidad
+
Alta
+
Alta
+
Alta
+
Alta
+
Alta
+
Alta
+
Alta
+
Alta
+
+
+
Control
+
Medio
+
Alto
+
Alto
+
Alto
+
Medio
+
Medio
+
Medio
+
Medio
+
+
+
Dificultad de uso
+
Media
+
Media
+
Alta
+
Media
+
Media
+
Media
+
Media
+
Media
+
+
+
Comunidad
+
Amplia
+
Amplia
+
Muy amplia
+
Amplia
+
Amplia
+
Amplia
+
Amplia
+
Amplia
+
+
+
Integraciones
+
Nativo con GitHub
+
Nativo con Gitlab, múltiples integraciones
+
Amplia gama de integraciones a través de plugins
+
Amplia gama de integraciones a través de operadores
+
+
+### Otros
+
+- CircleCI: https://circleci.com/
+- Travis CI: https://travis-ci.org/
+- Heroku CI: https://www.heroku.com/continuous-integration
+- TeamCity: https://www.jetbrains.com/teamcity/
+- Bamboo: https://www.atlassian.com/software/bamboo
+- Buddy: https://buddy.works/
+- Codefresh: https://codefresh.io/
+- Concourse: https://concourse-ci.org/
+- Drone: https://drone.io/
+- GoCD: https://www.gocd.org/
+- Spinnaker: https://www.spinnaker.io/
+- Tekton: https://tekton.dev/
+
+Más info: https://en.wikipedia.org/wiki/Comparison_of_source-code-hosting_facilities
+
+
+### GitHub Actions
+
+GitHub Actions es un servicio de integración continua y entrega continua (CI/CD) que automatiza tareas en repositorios de GitHub mediante la ejecución de **workflows**, definidos en archivos YAML en el directorio `.github/workflows`.
+
+Un **workflow** es un **DAG (Directed Acyclic Graph)**, donde los pasos se ejecutan en un orden específico, garantizando que las tareas se completen sin ciclos de dependencia. Para más detalles sobre DAGs, consulta [este artículo](https://www.linkedin.com/pulse/directed-acyclic-graphs-its-application-workflow-management-wrba?utm_source=share&utm_medium=member_ios&utm_campaign=share_via).
+
+GitHub Actions es gratuito para repositorios públicos y tiene un límite de 2000 minutos de ejecución al mes para repositorios privados. Los workflows pueden ejecutarse en respuesta a eventos en GitHub (como pull requests o commits), de forma manual o programada.
+
+Ofrece acciones predefinidas y la opción de crear acciones personalizadas. Además, puedes configurar **runners** en servidores propios o en la nube, además de los runners alojados por GitHub.
+
+En el siguiente capítulo, exploraremos en detalle cómo GitHub Actions y los workflows pueden facilitar el desarrollo de software.
+
+Enlaces de interés:
+- [GitHub Pricing](https://github.com/pricing)
+- [GitHub Actions Docs](https://docs.github.com/en/actions)
+- [GitHub Marketplace](https://github.com/marketplace?type=actions)
+- [GitHub Runners](https://docs.github.com/en/actions/using-github-hosted-runners/about-larger-runners/about-larger-runners)
+
diff --git a/cursos/git/es/04_workflow/02_advanced_github_actions.md b/cursos/git/es/04_workflow/02_advanced_github_actions.md
new file mode 100644
index 00000000..3068b243
--- /dev/null
+++ b/cursos/git/es/04_workflow/02_advanced_github_actions.md
@@ -0,0 +1,327 @@
+
+# GitHub Actions avanzado
+
+
+
+
+Ya hemos visto brevemente qué son las GitHub Actions, pero ahora vamos a profundizar un poco más en ellas. En este capítulo, exploraremos cómo se configuran, cómo se ejecutan y cómo se pueden personalizar para satisfacer necesidades específicas.
+
+GitHub Actions es una plataforma de integración continua y entrega continua (CI/CD) que automatiza los pipelines de construcción, prueba y despliegue. Te permite crear flujos de trabajo que construyen y prueban todas las pull requests a un repositorio, o puedes desplegar pull requests fusionadas en tu entorno de producción.
+
+Los workflows se definen en el directorio .github/workflow del repositorio. Puedes definir múltiples workflows, cada uno realizando un conjunto diferente de acciones. Por ejemplo, un workflow puede especificar cómo crear y probar una pull request, mientras que otro workflow puede desplegar automáticamente una aplicación cuando se crea una nueva release.
+
+Para una referencia más detallada, puedes consultar la [documentación oficial de GitHub Actions](https://docs.github.com/en/actions/using-workflows).
+
+
+## Conceptos de los workflows en GitHub Actions
+
+### Workflow Triggers
+
+Un trigger de workflow es un evento que hace que se ejecute un workflow. Hay cuatro tipos de triggers:
+
+- Eventos que ocurren en el repositorio de GitHub del workflow.
+- Eventos que ocurren fuera de GitHub, que activan un evento repository_dispatch en GitHub.
+- Un horario predefinido.
+- Trigger manual.
+
+Después de que se activa un workflow, el motor del workflow ejecuta uno o más jobs. Cada job contiene una lista predefinida de pasos; un paso puede ejecutar un script definido o realizar una acción específica (de una biblioteca de acciones disponibles en GitHub Actions). Esto se ilustra en el diagrama a continuación.
+
+
+
+El proceso que ocurre cuando se activa un evento es el siguiente:
+
+1. Ocurre un evento en el repositorio. Cada evento tiene un SHA de commit y una referencia de Git (un alias legible para humanos del hash del commit).
+2. GitHub busca en el directorio `.github/workflow` del repositorio archivos de workflow relacionados con el SHA de commit o la referencia de Git asociada con el evento.
+3. Para los workflows con valores que coinciden con el evento desencadenante, se activa la ejecución del workflow. Algunos eventos requieren que el archivo del workflow esté en la rama predeterminada del repositorio para ejecutarse.
+4. Cada workflow usa la versión del workflow en el SHA de commit o la referencia de Git asociada con el evento. Cuando se ejecuta el workflow, GitHub configura las variables de entorno `GITHUB_SHA` y `GITHUB_REF` en el entorno del launcher.
+
+
+### Workflow Jobs y Concurrency
+
+La ejecución de un workflow consta de uno o más jobs que se ejecutan en paralelo. Este es el comportamiento predeterminado, pero puedes definir dependencias en otros jobs para hacer que los jobs ejecuten tareas secuencialmente. Esto se hace utilizando la palabra clave `jobs..needs`.
+
+Puedes ejecutar un número ilimitado de tareas dentro de los límites de uso de tu workflow. Para evitar que se ejecuten demasiados jobs simultáneamente, puedes usar `jobs..concurrency` para asegurar que solo un job o workflow en el mismo grupo de concurrencia se ejecute al mismo tiempo. El nombre de un grupo de concurrencia puede usar cualquier cadena o excepción, excepto secretos.
+
+Si un job o workflow concurrente está en la cola, y otro job o workflow está en progreso, la tarea o workflow en cola se pone en espera, y cualquier tarea o workflow previamente suspendido en el grupo de concurrencia se cancela.
+
+
+
+## Ejemplos de Workflows de GitHub Actions: Sintaxis y Comandos
+
+### Sintaxis de las GitHub Actions
+
+Los workflows en GitHub Actions se escriben en sintaxis YAML. Por lo tanto, los archivos de workflow tienen una extensión .yml o .yaml.
+
+Recuerda: Los archivos de workflow deben almacenarse en un directorio dedicado en el repositorio llamado `.github/workflows.`
+
+
+
+#### name
+
+Se utiliza para establecer el nombre del workflow, del jobs o del step. GitHub Actions muestra este nombre en la pestaña de acciones del repositorio. Si falta name, Actions mostrará la ruta relativa del archivo de workflow desde el directorio raíz del repositorio. Los emojis pueden agregar un toque identificativo y colorido para hacerlos más visuales
+
+Por ejemplo, el nombre de un workflow se establece colocando la siguiente línea al comienzo del archivo:
+
+```yaml
+name: demo-github-actions-workflow 🧪
+```
+
+
+El job, con la identación adecuada, se establece de la siguiente manera:
+
+```yaml
+jobs:
+ build:
+ name: Build 🏗
+ runs-on: ubuntu-latest
+```
+
+Y el step, también con la identación adecuada:
+
+```yaml
+steps:
+ - name: Install dependencies 🔌
+ run: npm install
+```
+
+
+#### on
+
+Se utiliza para especificar el/los evento/s (triggers) que activan automáticamente el workflow. Puede tomar uno o múltiples eventos como triggers. Además, puede restringir los triggers a archivos específicos, cambios de rama o etiquetas.
+
+Ejemplos:
+
+La siguiente línea activa el workflow cada vez que ocurre un push en el repositorio:
+
+```yaml
+on: push
+```
+
+La siguiente línea activa el workflow cuando ocurre un push o el repositorio es bifurcado con la siguiente línea:
+
+```yaml
+on: [fork, push]
+```
+
+Si ocurren múltiples eventos simultáneamente, activa el workflow múltiples veces.
+
+El siguiente ejemplo muestra cómo especificar la actividad del evento y el tipo de actividad para activar un workflow:
+
+```yaml
+on:
+ branch_protection_rule:
+ types:
+ - edited
+```
+
+Aquí, el workflow se ejecuta cada vez que se cambia la regla de protección de la rama del repositorio. El trigger puede ser múltiples tipos de actividad de la siguiente manera:
+
+```yaml
+on:
+ branch_protection_rule:
+ types:
+ - edited
+ - created
+```
+
+Esto ejecuta los workflows dos veces cuando un usuario crea una nueva regla de protección de rama y la agrega.
+
+El siguiente ejemplo muestra cómo usar filtros de eventos y activar el workflow solo cuando el evento tiene ciertos aspectos específicos:
+
+```yaml
+on:
+ pull_request:
+ types:
+ - assigned
+ branches:
+ - 'demo-branch/**'
+```
+
+El siguiente ejemplo muestra cómo el workflow puede ejecutarse solo para ciertos tipos de archivos usando el filtro paths:
+
+```yaml
+on:
+ push:
+ paths:
+ - '**.py'
+```
+
+El workflow se activará cada vez que se suba un archivo Python al repositorio.
+
+
+#### defaults
+
+Se utiliza para especificar la configuración predeterminada del workflow. Si se especifica bajo un job determinado, solo se aplica al job. De lo contrario, especifica configuraciones para todos los jobs.
+
+El shell predeterminado para los comandos en el workflow y el directorio que contiene los scripts que debe ejecutar se especifican de la siguiente manera:
+
+```yaml
+defaults:
+ run:
+ shell: bash
+ working-directory: demo-workflow-scripts
+```
+
+#### jobs
+
+Se utiliza para especificar las acciones que realiza el workflow. Puede tener múltiples jobs bajo él, y cada job puede tener su propio alcance, conjunto de acciones y jobs dependientes.
+
+Ejemplos de comandos:
+
+Cada job bajo jobs necesita un identificador único que debe ser una cadena única y contener solo -, _, y caracteres alfanuméricos:
+
+```yaml
+jobs:
+ first_demo_job:
+ name: The first demo job
+ second_demo_job:
+ name: The second demo job
+```
+
+Las acciones de un job se especifican con la sintaxis steps. Cada paso puede tener un nombre, sus propias variables de entorno y comandos a ejecutar:
+
+```yaml
+jobs:
+ first_demo_job:
+ name: The first demo job
+ steps:
+ - name: Show the demo running
+ env:
+ VAR1: This is
+ VAR2: A Demo of
+ VAR3: GitHub Actions
+ VAR4: Workflow jobs
+ run: |
+ echo $VAR1 $VAR2 $VAR3 $VAR4.
+```
+
+
+### Comandos del Workflow
+
+#### Establecer Outputs
+
+El comando set-output establece el valor para la salida de una acción. Una vez establecido, otros comandos pueden usar la salida haciendo referencia al id del job:
+
+```yaml
+- name: Set output parameter
+ run: echo '::set-output name=OUTPUT_PARAM::parameter_set'
+ id: output-parameter-setter
+- name: Get output
+ run: echo "The output parameter is set to ${{ steps.output-parameter-setter.outputs.OUTPUT_PARAM }}"
+```
+
+#### Mostrar Errores
+
+El comando error escribe mensajes de error en el registro. Toma el nombre del archivo, la posición y el mensaje como entradas:
+
+```shell
+echo "::error file=demo-file.js,line=1,col=7,endColumn=9::Missing semicolon"
+```
+
+#### Mostrar outputs completos
+
+Los comandos echo::on y echo::off activan y desactivan respectivamente la impresión de los comandos, para todos los comandos siguientes:
+
+```yaml
+jobs:
+ demo-workflow-job:
+ steps:
+ - name: set echoing of commands on and off
+ run: |
+ echo '::set-output name=demo_action_echoing::off'
+ echo '::echo::on'
+ echo '::set-output name=demo_action_echoing::on'
+ echo '::echo::off'
+ echo '::set-output name=action_echo::disabled'
+```
+
+Esto mostrará la siguiente salida en el registro:
+
+```shell
+::set-output name=demo_action_echoing::on
+::echo::off
+```
+
+
+### Tutorial Rápido: Creando Workflows de Inicio
+
+Los Workflows de Inicio son plantillas de workflows que los usuarios pueden personalizar según sus necesidades y poner en uso. GitHub proporciona muchos workflows de inicio para categorías como despliegue continuo, automatización y seguridad para ayudar a los usuarios a comenzar.
+
+Doc GitHub: https://docs.github.com/en/actions/learn-github-actions/using-starter-workflows
+
+Para crear un nuevo workflow de inicio:
+
+1. Crea un nuevo directorio y llámalo .github, si aún no existe.
+2. Crea un directorio dentro del nuevo directorio y llámalo workflow-templates.
+3. Crea un archivo de workflow y llámalo demo-workflow.yml. Pon el siguiente código YAML en el archivo:
+
+ ```yaml
+ Name: Starter Workflow Demo
+
+ on:
+ push:
+ branches: [ $default-branch ]
+ pull_request:
+ branches: [ $default-branch ]
+
+ jobs:
+ build:
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v3
+
+ - name: demo workflow job
+ run: echo This is a demo start workflow
+ ```
+
+4. Crea un archivo de metadatos dentro de workflow-templates y llámalo demo-workflow.properties.json. El nombre del archivo del workflow y el nombre del archivo de metadatos deben ser iguales. Pon lo siguiente en el archivo de metadatos:
+
+ ```json
+ {
+ "name": "Starter Workflow Demo",
+ "description": "Demo starter workflow.",
+ "iconName": "demo-icon",
+ "categories": [
+ "Python"
+ ]
+ }
+ ```
+
+Aquí, los metadatos especifican la categoría del lenguaje del workflow de inicio para que un usuario pueda encontrar este workflow de inicio más fácilmente.
+
+
+## GitOps
+
+GitOps es una metodología para la gestión de la infraestructura y las aplicaciones basada en Git. En lugar de depender de herramientas y procesos manuales, GitOps utiliza repositorios Git como fuente única para todo lo relacionado con la infraestructura y las aplicaciones. Esto incluye la configuración de la infraestructura, las definiciones de las aplicaciones, los scripts de despliegue y cualquier otro artefacto o recurso necesario para el ciclo de vida de desarrollo y operaciones.
+
+
+
+- Lectura recomendada "GitOps: ¿qué es y cuáles son sus ventajas?" https://www.redhat.com/es/topics/devops/what-is-gitops 👀
+- Lista de actions y recursos relacionados https://github.com/sdras/awesome-actions?tab=readme-ov-file 👀
+
+En el siguiente módulo veremos ejemplos prácticos GitOps que se utilizan en Prefapp.
diff --git a/cursos/git/es/04_workflow/03_used_in_prefapp.md b/cursos/git/es/04_workflow/03_used_in_prefapp.md
new file mode 100644
index 00000000..4f0a91fe
--- /dev/null
+++ b/cursos/git/es/04_workflow/03_used_in_prefapp.md
@@ -0,0 +1,48 @@
+
+# Workflows utilizados en Prefapp
+
+
+
+Ya hemos visto una pequeña explicación de lo que es GitOps, ahora vamos a ver gráficamente algunos workflows básicos para la automatización del ciclo de vida del software.
+
+1. Se crea el código fuente y se sube a un repositorio de código fuente mediante una Pull Request.
+2. La Pull Request activa un workflow que testea el código fuente.
+3. Al mergear la Pull Request se activa un workflow que crea una imagen de contenedor, la sube a un registro de contenedores y abre otra Pull Request al repositorio de Helm.
+4. Cuando se crea una release en el repositorio del código, esta dispara un workflow que generá un documento Changelog y paquetiza la aplicación.
+5. Antes de aplicar la Chart (No tiene por qué ser justo antes, podría ser el paso 1), se deben aprovisionar los recursos necesarios para la aplicación mediante Terraform.
+6. Cuando se mergea la Pull Request abierta en el repositorio de Helm (abierta en el paso 3), se activa un workflow que despliega la release de Helm.
+
+
+
+
+¡Genial! Con esto se ha automatizado casi todo el ciclo de vida del software, desde la creación del código fuente hasta el despliegue de la aplicación.
+
+
+
+
+
+
+
+
+
+Antes de seguir, es recomendable una lectura de las buenas prácticas para crear workflows en GitHub Actions:
+
+- Fortalecer la seguridad en GitHub Actions: https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions 👀
+
+Vamos a examinar algunos de los workflows más usados en Prefapp para poder introducirnos en el mundo de la automatización de GitHub Actions:
+
+- [release-please](./05_release-please.md) (paso 4)
+- [release-pipeline](./07_release-pipeline.md) (paso 4)
+- [build_and_dispatch](./06_build_and_dispatch.md) (paso 3)
+- [PR-verify](./04_pr_verify.md) (paso 2)
+
+---
+
+Repositorio demo para "[Build and dispatch](https://github.com/prefapp/hello-k8s/blob/main/.github/workflows/build_and_dispatch.yaml)" y "[PR verify](https://github.com/prefapp/hello-k8s/blob/main/.github/workflows/pr_verify.yaml)": [hello-k8s](https://github.com/prefapp/hello-k8s/tree/main/.github) 👀
+
diff --git a/cursos/git/es/04_workflow/04_release-please.md b/cursos/git/es/04_workflow/04_release-please.md
new file mode 100644
index 00000000..d8bf1a45
--- /dev/null
+++ b/cursos/git/es/04_workflow/04_release-please.md
@@ -0,0 +1,68 @@
+
+# Workflows utilizados en Prefapp: release-please
+
+El workflow release-please está diseñado para automatizar la gestión de versiones y lanzamientos en un repositorio de GitHub. Este workflow utiliza la acción [release-please](https://github.com/googleapis/release-please) de Google para gestionar las versiones y lanzamientos del proyecto basado en [semver](https://prefapp.github.io/formacion/cursos/git/es/#/./03_prefapp_methodology/01_forking_strategy?id=versionado-sem%c3%a1ntico).
+
+
+
+
+## Evento que activa el workflow
+
+```yaml
+on:
+ push:
+ branches:
+ - main
+```
+- **on**: Especifica el evento que activa el workflow.
+- **push**: El workflow se activará cuando haya un push.
+- **branches**: Lista de ramas en las que debe ocurrir el push para activar el workflow, aquí `main`.
+
+
+## Nombre del workflow
+
+```yaml
+name: Run Release Please
+```
+- **name**: Este es el nombre del workflow, en este caso `Run Release Please`.
+
+
+## Job: release-please
+
+```yaml
+jobs:
+ release-please:
+ name: Release Please Manifest
+ runs-on: ubuntu-latest
+ steps:
+ - uses: google-github-actions/release-please-action@v3
+ id: release
+ with:
+ command: manifest
+ token: ${{secrets.GITHUB_TOKEN}}
+ default-branch: main
+```
+- **release-please**: Nombre del job.
+- **name**: Nombre descriptivo del job, `Release Please Manifest`.
+- **runs-on**: Especifica el sistema operativo en el que se ejecutará el job, aquí `ubuntu-latest`.
+
+
+### Pasos del job
+
+```yaml
+ steps:
+ - uses: google-github-actions/release-please-action@v3
+ id: release
+ with:
+ command: manifest
+ token: ${{secrets.GITHUB_TOKEN}}
+ default-branch: main
+```
+- **steps**: Lista de pasos a ejecutar en el job.
+ - **uses**: Utiliza una acción externa, en este caso `google-github-actions/release-please-action@v3`.
+ - **id**: Identificador del paso, `release`.
+ - **with**: Parámetros para la acción.
+ - **command**: Comando a ejecutar, aquí `manifest`.
+ - **token**: Token de autenticación de GitHub, obtenido de los secretos del repositorio (`secrets.GITHUB_TOKEN`).
+ - **default-branch**: Rama principal del repositorio, aquí `main`.
+
diff --git a/cursos/git/es/04_workflow/05_release-pipeline.md b/cursos/git/es/04_workflow/05_release-pipeline.md
new file mode 100644
index 00000000..a5674c53
--- /dev/null
+++ b/cursos/git/es/04_workflow/05_release-pipeline.md
@@ -0,0 +1,85 @@
+
+# Workflows utilizados en Prefapp: release-pipeline
+
+El workflow **release-pipeline** está diseñado para facilitar la publicación de nuevos paquetes mediante la automatización de la creación de ramas, la actualización de índices de repositorios Helm, y la generación de Pull Requests (PR) en GitHub.
+
+
+
+
+## Evento Trigger: `workflow_dispatch`
+
+Este workflow se activa manualmente mediante el evento `workflow_dispatch`, lo cual permite a los usuarios iniciar el proceso proporcionando los siguientes inputs:
+
+- `package`: Nombre del paquete que se va a publicar.
+- `version`: Versión del paquete que se va a publicar.
+
+
+## Variables de Entorno Globales
+
+- `proyecto`: Nombre del proyecto, en este caso, `prefapp`.
+- `git_user`: Usuario de Git configurado para las acciones de GitHub (`github-actions`).
+- `git_email`: Correo electrónico configurado para las acciones de GitHub (`github-actions@github.com`).
+
+
+## Definición del Job: `pipeline`
+
+Este único job se encarga de todo el proceso de publicación.
+
+
+### Pasos del Job
+
+1. **Checkout del Código**
+ ```yaml
+ - uses: actions/checkout@v3
+ ```
+ Este paso clona el repositorio en el runner de GitHub Actions.
+
+2. **Calcular el Nombre de la Rama**
+ ```yaml
+ - name: Calculating branch name
+ id: step-branch
+ run: echo "::set-output name=branch::$(echo new-release/${{ inputs.package }}-${{ inputs.version }})"
+ ```
+ Calcula el nombre de la nueva rama basada en el nombre y la versión del paquete proporcionados.
+
+3. **Mensaje del Commit**
+ ```yaml
+ - name: Commit Message
+ id: step-commit_message
+ run: echo "::set-output name=commit_message::$(echo New Chart Release '${{ inputs.package }}-${{ inputs.version }}')"
+ ```
+ Genera el mensaje del commit utilizando los inputs proporcionados.
+
+4. **Crear Rama con Cambios**
+ ```yaml
+ - name: Create branch with changes
+ run: |
+ git config --global user.name ${{ env.git_user }}
+ git config --global user.email ${{ env.git_email }}
+ git checkout -b ${{ steps.step-branch.outputs.branch }}
+ cd charts/${{ inputs.package }} && helm package . -d ../../docs/${{ inputs.package }}
+ cd ../../docs/${{ inputs.package }} && helm repo index .
+ git add .
+ git commit -m "${{steps.step-commit_message.outputs.commit_message}}"
+ git push origin ${{ steps.step-branch.outputs.branch }}
+ ```
+ - Configura el usuario y correo electrónico de Git.
+ - Crea una nueva rama basada en el nombre calculado.
+ - Genera el paquete Helm y actualiza el índice del repositorio.
+ - Añade y commitea los cambios, luego empuja la nueva rama al repositorio remoto.
+
+5. **Crear Pull Request**
+ ```yaml
+ - name: Create Pull Request
+ run: |
+ prName="Bump release ${{ inputs.package }}-${{ inputs.version }}"
+ docker run -v $(pwd):/repo prefapp/prefapp-cicdpy:sleep-test github.pr_auto_merge \
+ token=${{ secrets.GITHUB_TOKEN }} \
+ titulo="${prName}" \
+ rama_origen=${{ steps.step-branch.outputs.branch }} \
+ repo=charts \
+ proyecto=${{ env.proyecto }} \
+ reviewers='${{ github.actor }}'
+ ```
+ - Usa un contenedor Docker para ejecutar un script que crea un Pull Request automáticamente.
+ - Configura el título del PR, la rama de origen, el repositorio, el proyecto, y asigna el revisor basado en el actor de GitHub que inició el workflow.
diff --git a/cursos/git/es/04_workflow/06_build_and_dispatch.md b/cursos/git/es/04_workflow/06_build_and_dispatch.md
new file mode 100644
index 00000000..d18bf3d8
--- /dev/null
+++ b/cursos/git/es/04_workflow/06_build_and_dispatch.md
@@ -0,0 +1,156 @@
+
+# Workflows utilizados en Prefapp: build_and_dispatch
+
+El workflow "[Build and dispatch](https://github.com/prefapp/hello-k8s/blob/main/.github/workflows/build_and_dispatch.yaml)" está diseñado para construir y publicar imágenes de contenedor automáticamente cuando se realiza un push a la rama principal o cuando se crea un release (prereleased o released) en el repositorio. Además, se encarga de despachar cambios para su despliegue en otros sistemas.
+
+
+
+
+## Evento Trigger: `release` y `push`
+
+Este workflow se activa mediante dos eventos:
+- `release`: Cuando se crea o actualiza un prerelease o release.
+- `push`: Cuando se realiza un push a la rama `main`.
+
+
+## Variables de Entorno Globales
+
+- `REGISTRY`: Registro de contenedores (ghcr.io).
+- `IMAGE_NAME`: Nombre de la imagen, basado en el repositorio de GitHub.
+- `repo_state_name`: Nombre del repositorio de estado.
+
+
+## Job 1: `calculate_matrix`
+
+Este job calcula la matriz de imágenes que se construirán.
+
+1. **Checkout del Código**
+ ```yaml
+ - uses: actions/checkout@v4
+ ```
+ Clona el repositorio en el runner.
+
+2. **Calcular la Matriz**
+ ```yaml
+ - name: calculate_matrix
+ id: calculate_matrix
+ uses: prefapp/action-flavour-images-matrix-generator@v3
+ with:
+ repository: ${{ env.REGISTRY }}/${{ github.repository }}
+ ```
+ Usa la acción `action-flavour-images-matrix-generator` para calcular y generar la matriz de imágenes.
+
+
+## Job 2: `build-image`
+
+Este job construye y publica las imágenes de contenedor.
+
+1. **Configuración de Permisos**
+ ```yaml
+ permissions:
+ contents: read
+ packages: write
+ ```
+ Configura los permisos necesarios para leer contenidos y escribir paquetes.
+
+2. **Estrategia de Matriz**
+ ```yaml
+ strategy:
+ matrix: ${{fromJson(needs.calculate_matrix.outputs.matrix)}}
+ ```
+ Define la estrategia para ejecutar las tareas basadas en la matriz calculada.
+
+3. **Pasos del Job**
+
+ - **Datos de la Matriz**
+ ```yaml
+ - name: Matrix data
+ run: |
+ echo ${{ matrix.tags }}
+ echo ${{ matrix.build_args }}
+ echo ${{ matrix.dockerfile }}
+ ```
+ Imprime los datos de la matriz.
+
+ - **Clonar el Repositorio**
+ ```yaml
+ - name: Clone repository
+ uses: actions/checkout@v3
+ ```
+ Clona el repositorio en el runner.
+
+ - **Iniciar Sesión en el Registro de Contenedores**
+ ```yaml
+ - name: Log in to the Container registry
+ uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
+ with:
+ registry: ${{ env.REGISTRY }}
+ username: ${{ github.actor }}
+ password: ${{ secrets.GITHUB_TOKEN }}
+ ```
+ Inicia sesión en el registro de contenedores con las credenciales proporcionadas.
+
+ - **Construir y Publicar la Imagen Completa**
+ ```yaml
+ - name: Build and push full
+ uses: docker/build-push-action@v5
+ if: ${{ matrix.dockerfile == 'Dockerfile.full' }}
+ with:
+ context: .
+ push: true
+ file: ${{ matrix.dockerfile }}
+ build-args: |
+ ${{ matrix.build_args }}
+ tags: |
+ ${{ matrix.tags }}
+ ghcr.io/prefapp/gitops-k8s:latest
+ ```
+ Construye y publica la imagen completa (Dockerfile.full) si corresponde.
+
+ - **Construir y Publicar la Imagen Slim**
+ ```yaml
+ - name: Build and push slim
+ uses: docker/build-push-action@v5
+ if: ${{ matrix.dockerfile == 'Dockerfile.slim' }}
+ with:
+ context: .
+ push: true
+ file: ${{ matrix.dockerfile }}
+ build-args: |
+ ${{ matrix.build_args }}
+ tags: |
+ ${{ matrix.tags }}
+ ghcr.io/prefapp/gitops-k8s:latest-slim
+ ```
+ Construye y publica la imagen slim (Dockerfile.slim) si corresponde.
+
+
+## Job 3: `make-dispatches`
+
+Este job despacha los cambios para su despliegue.
+
+1. **Configurar Variables de Entorno**
+ ```yaml
+ - name: Set env
+ run: echo "state_repo=$GITHUB_REPOSITORY_OWNER/$repo_state_name" >> $GITHUB_ENV
+ ```
+ Configura las variables de entorno necesarias para el despacho.
+
+2. **Clonar el Repositorio**
+ ```yaml
+ - name: Clone Repository
+ uses: actions/checkout@v2
+ ```
+ Clona el repositorio en el runner.
+
+3. **Despachar Cambios**
+ ```yaml
+ - name: Dispatch changes
+ uses: prefapp/action-deployment-dispatch@v2
+ with:
+ state_repo: ${{ env.repo_state_name }}
+ image_repository: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
+ token: ${{ secrets.PAT_DEPLOY }}
+ ```
+ Utiliza la acción `action-deployment-dispatch` para despachar los cambios utilizando el repositorio de estado y el token de despliegue.
+
diff --git a/cursos/git/es/04_workflow/07_pr_verify.md b/cursos/git/es/04_workflow/07_pr_verify.md
new file mode 100644
index 00000000..8b451fd4
--- /dev/null
+++ b/cursos/git/es/04_workflow/07_pr_verify.md
@@ -0,0 +1,287 @@
+
+# Workflows utilizados en Prefapp: PR-verify
+
+El workflow "[PR verify](https://github.com/prefapp/hello-k8s/blob/main/.github/workflows/pr_verify.yaml) se encarga de verificar los cambios introducidos en un Pull Request (PR) en un repositorio de GitHub. Este workflow automatiza una serie de tareas esenciales para asegurar la calidad y la coherencia de los cambios antes de integrarlos en la base de código principal.
+
+
+
+
+## Workflow
+
+```yaml
+name: PR-verify
+```
+- **name**: Este es el nombre del workflow.
+
+
+## Evento que activa el workflow
+
+```yaml
+on:
+ pull_request:
+```
+- **on**: Especifica el evento que activa el workflow. Aquí, se activará cada vez que se cree una pull request.
+
+
+## Variables de entorno globales
+
+```yaml
+env:
+ VERSION: 2.0.0
+```
+- **env**: Define variables de entorno globales para el workflow. La `VERSION` está establecida en `2.0.0`.
+
+
+## Job 1: check-changes
+
+```yaml
+jobs:
+ check-changes:
+ runs-on: ubuntu-latest
+ outputs:
+ changed: ${{ steps.calculate_changes.outputs.changed }}
+ changed_files: ${{ steps.calculate_changes.outputs.changed_files }}
+ steps:
+ - name: Calculate changes
+ id: calculate_changes
+ uses: dorny/paths-filter@4512585405083f25c027a35db413c2b3b9006d50 # v2.11.1
+ with:
+ list-files: json
+ filters: |
+ changed:
+ - '**.yaml'
+ - '**.yml'
+ - '!.github/**'
+```
+- **runs-on**: Especifica el sistema operativo en el que se ejecutará el job, aquí `ubuntu-latest`.
+- **outputs**: Define las salidas del job, que se calcularán en uno de los pasos.
+- **steps**: Lista de pasos a ejecutar en el job.
+ - **Calculate changes**:
+ - **id**: Identificador del paso, `calculate_changes`.
+ - **uses**: Utiliza una acción externa `dorny/paths-filter` para calcular los archivos cambiados.
+ - **with**: Parámetros para la acción, listando los tipos de archivos a verificar (`**.yaml`, `**.yml`, excluyendo `.github/**`).
+
+
+## Job 2: determine-target
+
+```yaml
+ determine-target:
+ runs-on: ubuntu-latest
+ needs: check-changes
+ if: needs.check-changes.outputs.changed == 'true'
+ outputs:
+ TENANT: ${{ env.TENANT }}
+ APP: ${{ env.APP }}
+ ENV: ${{ env.ENV }}
+ env:
+ FILES: ${{ needs.check-changes.outputs.changed_files }}
+ steps:
+ - uses: actions/checkout@v4
+ - name: Eval changes
+ uses: actions/github-script@v6.4.1
+ with:
+ script: |
+ const script = require('./.github/evaluate_changes.js')
+ script({core, context})
+ - name: Check target (tenant, app and env) exist
+ run: |
+ target=${{ env.TENANT }}/${{ env.APP }}/${{ env.ENV }}
+ [ -d "$target" ] || (echo "target $target path doesn't exists" && exit 1)
+```
+
+- **needs**: Este job depende de la finalización del job `check-changes`.
+- **if**: Condicional que determina si el job se ejecuta basado en la salida del job `check-changes`.
+- **outputs**: Define salidas del job, usando variables de entorno.
+- **steps**: Lista de pasos a ejecutar en el job.
+ - **Eval changes**:
+ - **uses**: Utiliza la acción `actions/github-script` para ejecutar un script de Node.js.
+ - **script**: El script está definido en `./.github/evaluate_changes.js`.
+ - **Check target (tenant, app and env) exist**:
+ - **run**: Verifica si la ruta del objetivo existe.
+
+
+## Job 3: linter
+
+```yaml
+ linter:
+ runs-on: ubuntu-latest
+ needs: determine-target
+ if: needs.determine-target.outputs.TENANT != ''
+ env:
+ TENANT: ${{ needs.determine-target.outputs.TENANT }}
+ APP: ${{ needs.determine-target.outputs.APP }}
+ ENV: ${{ needs.determine-target.outputs.ENV }}
+ steps:
+ - uses: actions/checkout@v4
+ - name: Linter yaml principal
+ uses: ibiqlik/action-yamllint@81e214fd484713882ce4237cb7cd264d550856cf # v3.1.0
+ with:
+ file_or_dir: ${{ env.TENANT }}/${{ env.APP }}/${{ env.ENV }}
+ format: github
+ config_data: |
+ extends: default
+ ignore: |
+ secrets.yaml
+ rules:
+ document-start: enable
+ line-length:
+ max: 1000
+ trailing-spaces:
+ level: warning
+```
+- **needs**: Este job depende de la finalización del job `determine-target`.
+- **if**: Condicional que determina si el job se ejecuta basado en la salida del job `determine-target`.
+- **env**: Define variables de entorno para el job.
+- **steps**: Lista de pasos a ejecutar en el job.
+ - **Linter yaml principal**:
+ - **uses**: Utiliza la acción `ibiqlik/action-yamllint` para realizar linting en archivos YAML. Es buena práctica utilizar un SHA específicando el commit cuando la action es de terceros.
+ - **with**: Parámetros para la acción, especificando el archivo o directorio a revisar y la configuración del linter.
+
+
+## Job 4: validate-release
+
+```yaml
+ validate-release:
+ runs-on: ubuntu-latest
+ needs: determine-target
+ if: needs.determine-target.outputs.TENANT != ''
+ env:
+ TENANT: ${{ needs.determine-target.outputs.TENANT }}
+ APP: ${{ needs.determine-target.outputs.APP }}
+ ENV: ${{ needs.determine-target.outputs.ENV }}
+ steps:
+ - uses: actions/checkout@v4
+ - name: Edit cloud_providers.json
+ shell: bash
+ run: |
+ update_json() {
+ local secret_json="$1"
+ local secret_value="$2"
+ local json_path=".github/cloud_providers.json"
+ echo $(jq --arg a "$secret_value" "$secret_json = \$a" "$json_path") > "$json_path"
+ }
+ update_json '.dev.aws_config.aws_access_key_id' "${{ secrets.AWS_ACCESS_KEY_DEV }}"
+ update_json '.dev.aws_config.aws_secret_access_key' "${{ secrets.AWS_SECRET_ACCESS_KEY_DEV }}"
+ update_json '.pre.aws_config.aws_access_key_id' "${{ secrets.AWS_ACCESS_KEY_PRE }}"
+ update_json '.pre.aws_config.aws_secret_access_key' "${{ secrets.AWS_SECRET_ACCESS_KEY_PRE }}"
+ update_json '.pro.aws_config.aws_access_key_id' "${{ secrets.AWS_ACCESS_KEY_PRO }}"
+ update_json '.pro.aws_config.aws_secret_access_key' "${{ secrets.AWS_SECRET_ACCESS_KEY_PRO }}"
+
+ - name: Set provider
+ id: set-cloud-info
+ uses: actions/github-script@v6.4.0
+ with:
+ result-encoding: string
+ script: |
+ const cloud_config = require('.github/cloud_providers.json');
+ const {ENV} = process.env;
+ const provider = cloud_config[ENV].provider;
+ core.exportVariable('CLUSTER_NAME', cloud_config[ENV].cluster_name);
+ core.exportVariable('IMAGE_REPOSITORY_NAME', cloud_config[ENV].image_repository_name);
+ console.log("PROVIDER=" + provider);
+ if (provider == "azure"){
+ core.exportVariable('AKS_RESOURCE_GROUP', cloud_config[ENV].azure_config.aks_resource_group);
+ core.exportVariable('AZURE_CREDENTIALS', cloud_config[ENV].azure_config.az_credentials);
+ } else if (provider == "aws"){
+ core.exportVariable('AWS_KEYS', cloud_config[ENV].aws_config);
+ core.exportVariable('AWS_REGION', cloud_config[ENV].aws_config.aws_region);
+ } else if (provider == "do"){
+ core.exportVariable('DO_TOKEN', cloud_config[ENV].do_config.do_personal_access_token);
+ core.setSecret(cloud_config[ENV].do_config.do_personal_access_token);
+ }
+ return provider
+
+ - name: Setup / Install helm, helmfile y helm-secrets
+ uses: mamezou-tech/setup-helmfile@03233e1cd9b19b2ba320e431f7bcc061
+
+8db4248d # v2.0.0
+ with:
+ helmfile-version: v0.161.0
+ helm-version: v3.13.3
+ additional-helm-plugins: https://github.com/jkroepke/helm-secrets --version v4.5.1
+
+ - name: Install sops
+ run: |
+ wget -O /home/runner/bin/sops https://github.com/mozilla/sops/releases/download/v3.7.1/sops-v3.7.1.linux
+ chmod +x /home/runner/bin/sops
+
+ - id: azure-login
+ if: ${{ steps.set-cloud-info.outputs.result == 'azure' }}
+ uses: prefapp/composite-action-login-azure@v1
+ with:
+ creds: ${{ env.AZURE_CREDENTIALS }}
+ resource-group: ${{ env.AKS_RESOURCE_GROUP }}
+ cluster-name: ${{ env.CLUSTER_NAME }}
+ repository-name: ${{ env.IMAGE_REPOSITORY_NAME }}
+
+ - id: aws-login
+ if: ${{ steps.set-cloud-info.outputs.result == 'aws' }}
+ uses: prefapp/composite-action-login-aws@v1
+ with:
+ awskeys: ${{ env.AWS_KEYS }}
+ cluster-name: ${{ env.CLUSTER_NAME }}
+ aws-region: ${{ env.AWS_REGION }}
+
+ - id: digital-ocean-login
+ if: ${{ steps.set-cloud-info.outputs.result == 'do' }}
+ uses: prefapp/composite-action-login-digitalocean@v1
+ with:
+ cluster-name: ${{ env.CLUSTER_NAME }}
+ auth-token: ${{ env.DO_TOKEN }}
+
+ - name: Set helmfile env var
+ run: |
+ str=${{ env.IMAGE_REPOSITORY_NAME }}
+ upperStr="${str^^}"
+ helmfilevar="${upperStr}_PASSWORD"
+ echo "HELMFILE_VAR_NAME=$helmfilevar" >> "$GITHUB_ENV"
+
+ - name: Validate release coherence
+ run: |
+ echo "Validating chart..."
+ cd ${{ env.TENANT }}/${{ env.APP }}
+ export ${{ env.HELMFILE_VAR_NAME }}=${{ steps.azure-login.outputs.helmfile-creds }}${{ steps.aws-login.outputs.helmfile-creds }}
+ helm version
+ helmfile -v
+ helmfile -e ${{ env.ENV }} template | kubectl create -f - --dry-run
+
+ - name: Download Pluto
+ uses: FairwindsOps/pluto/github-action@d8a976c87f8db0c41048dc5450fabbb2a0603c82 # v5.18.4
+
+ - name: Run pluto
+ run: |
+ echo "Running pluto..."
+ cd ${{ env.TENANT }}/${{ env.APP }}
+ export ${{ env.HELMFILE_VAR_NAME }}=${{ steps.azure-login.outputs.helmfile-creds }}${{ steps.aws-login.outputs.helmfile-creds }}
+ helmfile -e ${{ env.ENV }} template | pluto detect -
+
+ - name: Set up python
+ uses: actions/setup-python@65d7f2d534ac1bc67fcd62888c5f4f3d2cb2b236 # v4.7.1
+ with:
+ python-version: 3.7
+
+ - name: Run Trivy vulnerability scanner in IaC mode
+ uses: aquasecurity/trivy-action@fbd16365eb88e12433951383f5e99bd901fc618f # v0.12.0
+ with:
+ scan-type: 'config'
+ hide-progress: false
+ scan-ref: '.'
+ exit-code: '0'
+ ignore-unfixed: true
+```
+
+- **needs**: Este job depende de la finalización del job `determine-target`.
+- **if**: Condicional que determina si el job se ejecuta basado en la salida del job `determine-target`.
+- **env**: Define variables de entorno para el job.
+- **steps**: Lista de pasos a ejecutar en el job.
+ - **Edit cloud_providers.json**: Actualiza el archivo `cloud_providers.json` con credenciales secretas.
+ - **Set provider**: Establece variables de entorno según el proveedor de nube.
+ - **Setup / Install helm, helmfile y helm-secrets**: Instala herramientas necesarias.
+ - **Install sops**: Instala `sops` para manejar secretos.
+ - **azure-login**, **aws-login**, **digital-ocean-login**: Inicia sesión en el proveedor de nube correspondiente.
+ - **Set helmfile env var**: Establece una variable de entorno para `helmfile`.
+ - **Validate release coherence**: Valida la coherencia del release usando `helmfile` y `kubectl`.
+ - **Download Pluto** y **Run pluto**: Descarga y ejecuta `pluto` para detectar recursos Kubernetes en desuso.
+ - **Set up python**: Configura Python.
+ - **Run Trivy vulnerability scanner in IaC mode**: Ejecuta Trivy para escanear vulnerabilidades en la infraestructura como código.
+
diff --git a/cursos/git/es/04_workflow/08_guided_practice-creating_workflow.md b/cursos/git/es/04_workflow/08_guided_practice-creating_workflow.md
new file mode 100644
index 00000000..bd93113f
--- /dev/null
+++ b/cursos/git/es/04_workflow/08_guided_practice-creating_workflow.md
@@ -0,0 +1,196 @@
+
+# Práctica guiada - Crear un workflow
+
+Ya hemos visto opciones avanzadas en los anteriores ejemplos de [Workflows utilizados en Prefapp](./04_workflow/03_used_in_prefapp). Ahora vamos a hacer una práctica sencilla que nos servirá para repasar conceptos creando un workflow en GitHub Actions desde 0.
+
+Para empezar, simplemente enviaremos un saludo a la consola que podremos ver en el panel de GitHub Action. Estará coloreado y se ejecutará en respuesta a un evento "pull request". Con esta base, iremos añadiendo complejidad.
+
+⚠️ *Recordad que el workflow se debe guardar en la carpeta* `.github/workflows` *de vuestro repositorio.*
+
+## Manos a la obra
+
+Empezamos con el nombre, debe ser descriptivo y fácil de identificar:
+
+```yaml
+name: saludo-color 🌈
+```
+
+El trigger haremos que sea la pull request, pero añadimos también la opción manual:
+
+```yaml
+on:
+ pull_request:
+ workflow_dispatch:
+```
+
+Necesitamos unas variables de entorno para definir colores y un mensaje standard. Estas **variables serán globales** para todo el workflow:
+
+```yaml
+ SALUDO: "Hola "
+ RED: \033[31m
+ GREEN: \033[32m
+ YELLOW: \033[33m
+ BLUE: \033[34m
+ PINK: \033[35m
+ CYAN: \033[36m
+ WHITE: \033[37m
+ NORMAL: \033[0;39m
+```
+
+Ahora, vamos a definir algunos aspectos del job que afectarán dentro de este ámbito a los steps que anidemos en él:
+- Nombre. [Más info](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#name)
+- Sistema operativo. Le asignamos una Ubuntu latest. [Más info](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idruns-on)
+- Variables de entorno. Vamos a especificar una **variable específica para el job**. [Más info](https://docs.github.com/en/actions/learn-github-actions/variables)
+
+```yaml
+jobs:
+ pruebas:
+ name: Pruebas 🏗️
+ runs-on: ubuntu-latest
+ env:
+ NOMBRE: "Mundo"
+```
+
+Ahora ya podemos especificar un step dentro del job. Podemos empezar por el checkout para poder acceder a los archivos del repositorio:
+
+```yaml
+ steps:
+ - name: Checkout repository 🛎️
+ uses: actions/checkout@v3
+```
+
+Y el segundo step será el encargado de enviar el saludo. Además añadimos la fecha mediante una **variable que actuará tan solo a nivel de step**:
+
+```yaml
+ steps:
+ - name: Decir hola 👋
+ run: |
+ echo -e "$RED $SALUDO$NOMBRE. Hoy es $DIA! red"
+ echo -e "$GREEN $SALUDO$NOMBRE. Hoy es $DIA! green"
+ echo -e "$YELLOW $SALUDO$NOMBRE. Hoy es $DIA! yellow"
+ echo -e "$BLUE $SALUDO$NOMBRE. Hoy es $DIA! blue"
+ echo -e "$PINK $SALUDO$NOMBRE. Hoy es $DIA! pink"
+ echo -e "$CYAN $SALUDO$NOMBRE. Hoy es $DIA! cyan"
+ echo -e "$WHITE $SALUDO$NOMBRE. Hoy es $DIA! white"
+ echo -e "$NORMAL $SALUDO$NOMBRE. Hoy es $DIA! normal"
+ echo -e "$NORMAL $SALUDO$RED$NOMBRE. $GREEN Hoy es $YELLOW$DIA! varios $NORMAL"
+
+ env:
+ DIA: "Lunes"
+```
+
+Con este workflow hemos visto cada parte de un workflow básico. Además, hemos definido variables en distintos `scopes` para ver cómo se comportan.
+
+Si añadimos estos cambios a una rama y los subimos, podremos ver que al crear la pull request se dispará el workflow. A cada cambio que efectuemos en la rama, se reflejará en la pull request y provocará que se dispare el trigger de nuevo. En la interfaz de GitHub Actions se ve así:
+
+
+
+¡Genial! Vamos a modificar el workflow para ver algo más complejo.
+
+## Añadimos complejidad
+
+Vamos a añadir un step que se ejecute en un nuevo runner, en concreto, en un contenedor ubuntu 20.04 ([Más info de standard hosted](https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners/about-github-hosted-runners)). Este runner se ejecutará de manera paralela. Simplemente, envía un nuevo saludo en color.
+
+```yaml
+ - name: Ejecutar en paralelo 🐳
+ uses: ubuntu-20.04
+ with:
+ entrypoint: /bin/sh
+ run: echo -e "$GREEN Hola desde un contenedor! $NORMAL"
+```
+
+Además, vamos a recoger información del contenedor con los comandos `whoami`, `free -h` y `ps aux` para guardarlo en el fichero `info.txt` (Se guarda dentro del runner) y lo mostraremos.
+
+```yaml
+ - name: Recoger información del contenedor 📝
+ with:
+ entrypoint: /bin/sh
+ run: |
+ whoami > info.txt
+ free -h >> info.txt
+ ps aux >> info.txt
+ cat info.txt
+```
+
+
+
+
+Para poder recuperar el documento info.txt creado debemos añadir un step con la action [upload-artifact@](https://github.com/actions/upload-artifact) que lo subirá como un artefacto que podremos utilizar desde otros runners.
+
+```yaml
+ - name: Upload info.txt 📤
+ uses: actions/upload-artifact@v4
+ with:
+ name: info
+ path: ./info.txt
+```
+
+Ahora, vamos a añadir un nuevo job que dependa del job `paralelo` para ver como se comporta. En este caso, vamos a instalar [Bats](https://bats-core.readthedocs.io/en/stable/installation.html), un framework de testing para Bash. Utilizaremos Node.js para instalarlo y comprobar la versión.
+
+```yaml
+ check-bats-version:
+ name: Testing Bats 🦇
+ runs-on: ubuntu-latest
+ needs: paralelo
+ steps:
+ - name: Checkout repository 🛎️
+ uses: actions/checkout@v4
+ - name: Setup Node.js 🚀
+ uses: actions/setup-node@v4
+ with:
+ node-version: '20'
+ - name: Install Bats 🦇
+ run: npm install -g bats
+ - name: Check Bats version 🦇
+ run: bats -v
+```
+
+Necesitaremos crear un fichero `test.bats` en la raíz. Para comprobar que tenemos el fichero `info.txt` en el nuevo runner, tan solo vamos a comprobar que existe:
+
+```bash
+@test "Check if the file exists" {
+ run ls info.txt
+ [ "$status" -eq 0 ]
+}
+```
+
+Ahora ya podemos incluir en nuestro workflow otro step para ejecutar el test de Bats.
+
+```yaml
+ - name: Ejecutar test de Bats 🦇
+ run: bats test.bats
+```
+
+Y para finalizar, añadimos un step en este job para descargar el artefacto con la action [download-artifact](https://github.com/actions/download-artifact).
+
+```yaml
+ - name: Download info.txt 📥
+ uses: actions/download-artifact@v4
+ with:
+ name: info
+ path: ./info.txt
+```
+
+
+
+## Visión general del workflow
+
+
+
+1. Se puede ver como los jobs `Pruebas` y `Paralelo` se ejecutan en paralelo.
+2. Se puede ver la dependencia del job `Check Bats version` del job `Paralelo`.
+3. El artifact que hemos subido en el job `Paralelo` queda en el workflow con un fichero .zip descargable.
+
+Ficheros:
+- [color-test.yaml](../../_media/04_workflow/color-test.yaml)
+- [test.bats](../../_media/04_workflow/test.bats)
+
+
+!Enhorabuena! 🎉 Has llegado al final de este capítulo. Ahora puedes seguir prácticando con otros workflows que te interesen. Algunas ideas: https://github.com/sdras/awesome-actions/blob/main/ideas.md
+
+## Otros recursos interesantes
+
+- [Actions Runners Controller (ARC)](https://github.com/actions/actions-runner-controller) - es un operador de Kubernetes que orquesta y escala ejecutores autoalojados para GitHub Actions.
+- [Dagger](https://dagger.io/) - es un lenguaje de programación de flujo de trabajo de código abierto que permite a los desarrolladores definir flujos de trabajo de CI/CD como código. Tenemos un [curso de Dagger](https://prefapp.github.io/formacion/cursos/dagger/#/) en Prefapp.
+- [GitHub Actions con Docker](https://github.com/marketplace?type=actions&query=docker+) - GitHub Actions tiene soporte nativo en Docker, con lo cuál puedes probarlo en local o integrarlo con otras herramientas como Kubernetes o Jenkins.
+- [Características avanzadas](https://docs.github.com/en/actions/using-workflows/about-workflows#advanced-workflow-features) - Explora la documentación de GitHub que merece mucho la pena: Almacenamiento de secretos, jobs dependientes, matrices de variables, caché, etc
diff --git a/cursos/git/es/README.md b/cursos/git/es/README.md
index 94faf94e..a90c97d8 100755
--- a/cursos/git/es/README.md
+++ b/cursos/git/es/README.md
@@ -2,7 +2,7 @@
Git es el SCV (sistema de control de versiones) de código abierto más utilizado más utilizado en el mundo. Diseñado por Linus Torvalds, su propósito es llevar registro de los cambios en archivos de computadora. A diferencia de Subversion, Git es distribuido, con lo que permite la coordinación del trabajo entre varias personas sobre archivos compartidos en un repositorio de código. Las empresas y los programadores suelen utilizar Git para colaborar en el desarrollo de software y aplicaciones.
-Git es un proyecto de código abierto maduro y con un mantenimiento activo, y es la base de grandes plataformas de servicios de alojamiento web para proyectos, también llamados repositorios remotos o forjas, como pueden ser Github, Gitlab, Bitbucket, Gitea, Gogs, etc.
+Git es un proyecto de código abierto maduro y con un mantenimiento activo, y es la base de grandes plataformas de servicios de alojamiento web para proyectos, también llamados repositorios remotos o forjas, como pueden ser GitHub, Gitlab, Bitbucket, Gitea, Gogs, etc.
Un asombroso número de proyectos de software dependen de Git para el control de versiones, incluidos proyectos comerciales y de código abierto. Los desarrolladores que han trabajado con Git cuentan con una buena representación en la base de talentos disponibles para el desarrollo de software, y este sistema funciona a la perfección en una amplia variedad de sistemas operativos e IDE (entornos de desarrollo integrados).
diff --git a/cursos/git/es/_cdn/motor.js b/cursos/git/es/_cdn/motor.js
index 4153578a..cdb82a29 100755
--- a/cursos/git/es/_cdn/motor.js
+++ b/cursos/git/es/_cdn/motor.js
@@ -1 +1 @@
-!function(){function s(n){var r=Object.create(null);return function(e){var t=c(e)?e:JSON.stringify(e);return r[t]||(r[t]=n(e))}}var a=s(function(e){return e.replace(/([A-Z])/g,function(e){return"-"+e.toLowerCase()})}),l=Object.prototype.hasOwnProperty,h=Object.assign||function(e){for(var t=arguments,n=1;n/gm),Ve=F(/^data-[\-\w.\u00B7-\uFFFF]/),Xe=F(/^aria-[\-\w]+$/),Ke=F(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i),Qe=F(/^(?:\w+script|data):/i),Je=F(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205f\u3000]/g),et="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};function tt(e){if(Array.isArray(e)){for(var t=0,n=Array(e.length);t"+e;else{var r=Ce(e,/^[\s]+/);n=r&&r[0]}var i=b?b.createHTML(e):e;if(o)try{t=(new m).parseFromString(i,"text/html")}catch(e){}if(s&&ze(U,["title"]),!t||!t.documentElement){var a=(t=w.createHTMLDocument("")).body;a.parentNode.removeChild(a.parentNode.firstElementChild),a.outerHTML=i}return e&&n&&t.body.insertBefore(l.createTextNode(n),t.body.childNodes[0]||null),A.call(t,X?"html":"body")[0]}var O=Ge,$=Ye,M=Ve,N=Xe,z=Qe,P=Je,j=Ke,D=null,H=ze({},[].concat(tt(je),tt(De),tt(He),tt(qe),tt(Ie))),q=null,I=ze({},[].concat(tt(Ue),tt(Be),tt(Ze),tt(We))),U=null,B=null,Z=!0,W=!0,G=!1,Y=!1,V=!1,X=!1,K=!1,Q=!1,J=!1,ee=!1,te=!1,ne=!1,re=!0,ie=!0,ae=!1,oe={},se=ze({},["annotation-xml","audio","colgroup","desc","foreignobject","head","iframe","math","mi","mn","mo","ms","mtext","noembed","noframes","plaintext","script","style","svg","template","thead","title","video","xmp"]),le=ze({},["audio","video","img","source","image"]),ce=null,ue=ze({},["alt","class","for","id","label","name","pattern","placeholder","summary","title","value","style","xmlns"]),pe=null,de=l.createElement("form");d.isSupported&&(function(){try{F('