Git & GitHub Course

Dirección Nacional de Planeación y Estadística
(DNPE)

2024-03-10

Version Control with Git

📚 Recursos Recomendados 📖

🔗 Recursos Útiles 📌

Permite simular visualmente operaciones Git en tu propio repositorio con un único comando de terminal. La salida es una imagen (por defecto) o una visualización de vídeo que muestra el comportamiento del comando Git.

Es un juego de código abierto que introduce a los jugadores en el popular sistema de control de versiones Git. Es muy interactivo, y su objetivo es desarrollar la intuición para las operaciones más comunes. Los jugadores son guiados paso a paso a través de las funciones de Git.

Es un visualizador de repositorios Git y una serie de tutoriales/retos educativos. Su objetivo principal es ayudar a los desarrolladores a entender Git a través del poder de la visualización (algo que está ausente cuando se trabaja en la línea de comandos).

DevDocs combina múltiples documentaciones de API en una interfaz rápida, organizada y que permite realizar búsquedas. Además de disponer de hojas de trucos interactivas como la que se pone de ejemplo.

💾 Version Control Systems 📑

Se trata de la gestión de múltiples versiones de un proyecto. Para gestionar una versión, cada cambio (adición, edición o eliminación) en los archivos debe ser rastreado.

Lo anterior parece ser el sistema perfecto hasta que te das cuenta de que, aunque se realiza un seguimiento de las versiones, no hay forma de saber cuáles son los contenidos y descripciones de cada versión. La “solución” es colocar el resumen de cambios de cada versión en un archivo separado. Pero todavía necesitarías una forma de comparar cada versión y cada cambio de archivo. No hay forma de hacer esto en ese sistema; tienes que memorizar todo lo que hiciste.

🔎 ¿Cómo funciona Git

La característica principal de Git es su sistema de “Tres Estados”:


  1. El directorio de trabajo (working directory 📷) es simplemente la instantánea actual en la que estás trabajando.
  2. El área de preparación (staging area 📀) es donde se marcan los archivos modificados en su versión actual, listos para ser almacenados en la BD. No todos los archivos que modifique en el Working Directory deben tenerse en cuenta a la hora de “tomar una instantánea” del estado actual del proyecto.
  3. El directorio Git (git directory 💾) es la BD donde se almacena el historial.


       💥 GIT NO RASTREA CAMBIOS; RASTREA VERSIONES ✔️ 💥

Entonces, básicamente, Git funciona de la siguiente manera: modificas los archivos, agregas cada archivo que deseas incluir en la instantánea al área de preparación (git add), luego tomas la instantánea y los agregas a la base de datos (git commit).


👀 Comandos Principales 👂

Code Desc
\(\texttt{git init}\) Inicializa una nueva BD git
\(\texttt{git clone}\) Copia una BD existente
\(\texttt{git status}\) Consultar el estado del proyecto local
\(\texttt{git diff}\) Revisa los cambios realizados en el proyecto
\(\texttt{git add}\) Indica a Git que rastree un archivo modificado
\(\texttt{git commit}\) Guarde el estado actual del proyecto en la BD
\(\texttt{git push}\) Copia la BD local a un servidor remoto
\(\texttt{git pull}\) Copia una BD remota a una máquina local
\(\texttt{git log}\) Consulta la historia del proyecto (*)
\(\texttt{git branch}\) Enumera, crea o elimina ramas
\(\texttt{git merge}\) Fusiona la historia de dos ramas juntas
\(\texttt{git stash}\) Mantenga los cambios actuales guardados para usarlos más adelante

(*) Puede pasar el parámetro \(\texttt{--oneline}\) para reducir la información mostrada.

Installation and Setup

🚨 Instalación 💥

🔧 Configuración ☑️

Los siguientes comandos solo los usará una única vez, pues toda la configuración se almacena en un archivo global externo, lo que significa que todos tus proyectos compartirán la misma configuración. También hay una manera de configurar los proyectos uno por uno (lo veremos más adelante).


git config --global user.name "Pepito Pérez"
git config --global user.email "pepitoperez@example.com"

Para observar que efectivamente ya definimos dichos parámetros:

git config --get user.name
git config --get user.email


Puedes encontrar el archivo que registra tu configuración de Git en tu carpeta de inicio. Para Windows, puede encontrarlo en ▶️ \(\texttt{C:/Users/YourName/.gitconfig}\)

GIT

Estructura Interna del .git 👷‍♂️

Ten en cuenta que nunca tendrás que modificar nada en esta carpeta, pero en este caso revisaremos lo que contiene 👇


hooks: Almacena Shell scripts que puedes configurar para que se ejecuten posterior a un evento
index: Es el área de preparación (Staging Area)
HEAD: Contiene información del commit actual
refs: Referencias a ramas y commits
objects: Guarda los commits y la información a asociada a ellos
config: Datos del repositorio local y el remoto (si lo hay)
logs: Logs resultantes de la ejecución de comandos

Tags 🏷️


Tal como el nombre lo indica usamos etiquetas cuando queremos hacer referencia a algún evento, puntos importantes y que deseamos guardar dicho momento en el tiempo (versiones)

# Annotated tags (almacena metadatos valiosos):
git tag -a <Nombre del Tag> -m "Descripción del Tag"
# Lightweight tag:
git tag <Nombre del Tag>
# Para ver el listado de tags creados:
git tag
# Para observar el cambio realizado:
git log

Su utilidad, aparte de identificar momentos específicos en la historia de Git, es facilitar la búsqueda, pues ahora ya no necesitamos anotar o buscar el ID del commit (SHA hash) sino simplemente nombrarlo:

git checkout tags/<Nombre del Tag>
git tree


⚠️ Si intentas crear una etiqueta con el mismo identificador de una existente, Git arrojará un error como:

fatal: tag 'v0.4' already exists


🚨 La eliminación de un tag es una operación sencilla. Basta con anteponer la opción -d a una etiqueta:

git tag -d v1.0

Alias 🔠

Los alias (atajos) se utilizan para crear comandos más cortos que se asocian a comandos más largos. Los alias permiten flujos de trabajo más eficientes al requerir menos pulsaciones para ejecutar un comando.

Tenga en cuenta que:

  • No existe un comando git alias directo. No es más que una configuración de Git, por lo tanto, pueden crearse en un ámbito local o global.
  • La creación de los alias no modificará los comandos fuente.
  • El uso de alias te convertirá en un desarrollador más rápido y eficiente.
# Basic Command: git config --global alias.{Nombre} [Código]
git config --global alias.co checkout
git config --global alias.st status
git config --global alias.unstage 'reset HEAD --'


# Uno de los más usados en el día a día, personalmente, es:
git config --global alias.tree log --graph --decorate --all --oneline

Diff 🆚

Si no especificamos parámetros adicionales se observarán los cambios desde la última confirmación, ya que por defecto le mostrará cualquier cambio no comprometido desde el último commit.

git diff <File Name>

@@ -1 +1 @@
-this is a git diff test example
+this is a diff example

Los trozos tienen su propia semántica de salida granular. Por ejemplo, el siguiente fragmento se leería:

@@ -34,6 +34,8 @@
  • Se han extraído 6 líneas a partir de la línea número 34. Además, se han añadido 8 líneas a partir de la línea número 34.

También si lo desea puede resaltar los cambios de una manera más detallada, se tiene un modo especial para resaltar los cambios con una granularidad mucho mejor.

  1. Este modo tokeniza las líneas añadidas y eliminadas por espacios en blanco y luego las difiere.
  2. Si ha clonado el subdirectorio llamado contrib de Git, recuerde que éste contiene un montón de herramientas relacionadas con Git y otras piezas. Una de ellas es un script Perl que le ayudará a resaltar los fragmentos de subpalabras que han cambiado.
# (1).
git diff --color-words
# (2).
git diff-highlight


Por otro lado, puede comparar 2 commits diferentes conociendo sus IDs, mediante:

# Para ver el log y observar los IDs de los últimos commits:
git log --pretty --oneline
# Seleccione el ID de dos commits a comparar:
git diff <123abcd> <789abcd>

Commits

Las confirmaciones son las unidades de bloques de creación principales de la línea de tiempo de un proyecto de Git.

# Comandos por terminal preliminares
mkdir MyProject
cd MyProject/
git init
touch README.md
git add README.md
# Elimina un archivo ya en el Staging Area
git rm --cached README.md
git commit -m "commit message"

Para traer el estado anterior del proyecto al directorio de trabajo:

git checkout <ID del Commit>
git checkout <Nombre del Fichero>
  • 👀 Tenga cuidado de no cambiar nada cuando revise commits anteriores. Como en las películas, ¡cambiar el pasado es una muy mala idea! 🔮

Para regresar al directorio de trabajo:

git checkout <master ó main ó HEAD>

Deshacer 🗑️


¿Por qué no borrar el commit? Por la regla del viaje en el tiempo, nunca cambies el pasado. Cualquier cambio commited debe permanecer así.

git revert <ID del Commit>


  • Tenga en cuenta que con revert, se creará una nueva confirmación que contiene cambios opuestos (eso significa que puedes ¡revertir un revert!). Sugiero que conserve siempre la descripción por defecto del commit, ya que la hace fácil de identificar.

“Modificar”/Reemplazar 🧱

CAMBIO SENCILLO. Cómo solventar un error en el mensaje de confirmación (para el último commit realizado):

git commit --amend
# git log | Para que evidencie el cambio efectivo

🔴 Tenga presente que no está modificando un commit; estás creando un nuevo commit y reemplazando el actual.


CAMBIO COMPLEJO. Como un error en la selección de un archivo, o que nos faltó incluir algo en el archivo:

git reset --soft HEAD~1
git reset HEAD <Nombre del Fichero>
  • --soft: Para que los cambios que hicimos permanezcan en el directorio de trabajo. Es decir, no van a deshacerse los cambios en los archivos, sino que se eliminará el registro del commit. En conclusión, los cambios no están registrados, pero sí permanecen en el working directory.
  • --hard: Si no desea que se mantengan los cambios
  • HEAD~1: Significa que retrocedemos al commit inmediatamente anterior, y situamos nuestro HEAD a la referencia/rama actual.

Ojo, así como podemos ir hacia atrás también podemos ir hacia delante.

git reset --hard <ID del Commit>
# Nada se borra, ¡¡ NADA !!
git reflog
git reset --hard <Mismo ID del commit>

Buenas Prácticas 💚

  1. Si un commit necesita de otros commits para tener sentido, no debería existir.
  2. El mensaje del commit debe ser conciso y directo.
  3. No se deben escribir mensajes de más de 50 caracteres.
  4. Lo único que debes explicar es POR QUÉ se hicieron los cambios, no QUÉ.
  5. La forma correcta de cambiar algo es hacer un nuevo commit. El pasado es el pasado. The past is the past. Let it go

Ignoring Files 🙈

No todo el directorio de trabajo debe ser rastreado por Git. Hay ciertos archivos (configuraciones, contraseñas, código malicioso) que suelen dejarse sin rastrear.

Recuerde que el archivo global \(\texttt{.gitignore}\) debe colocarse en la raíz de su repositorio, no es de buena práctica tener múltiples archivos \(\texttt{.gitignore}\) en múltiples directorios.

Los archivos ignorados suelen ser artefactos de compilación y archivos generados por máquina que se pueden derivar del origen del repositorio. Algunos ejemplos comunes son:

  • Cachés de dependencias, como el contenido de /packages
  • Código compilado, como archivos .pyc y .class
  • Compilar directorios de salida, como /bin, /out o /target
  • Archivos generados en tiempo de ejecución, como .log o .tmp
  • Archivos ocultos del sistema, como .DS_Store o Thumbs.db
  • Archivos de configuración de IDE personales, como .idea/workspace.xml

.gitignore utiliza patrones globbing para comparar nombres de archivos. Puede construir sus patrones utilizando varios símbolos:

Tenga en cuenta que .gitignore no admite expresiones regulares, por ejemplo,

# El equivalente a:  modules.\(py\|r)
modules.py
modules.r
# El equivalente a: (Hellow|Hola)(World|Mundo)-[0-9]*\.csv
HellowWorld-[0-9]*.csv
HolaWorld-[0-9]*.csv
HellowMundo-[0-9]*.csv
HolaMundo-[0-9]*.csv


Además de estos caracteres, puede utilizar \(\texttt{#}\) para incluir comentarios en su archivo .gitignore,

# ¡¡ ESTO NO FUNCIONA !!
output/
!output/BD.xlsx
  • La excepción viene DESPUÉS de la regla.
  • El marcado de excepción sólo funciona para las líneas que describen nombres de archivos. No puede con líneas que ignoran directorios.

Puede utilizar \(\texttt{\\}\) para escapar caracteres de patrón .gitignore si tiene archivos o directorios que los contengan,

# Ignora el archivo literalmente llamado main[01].txt
main\[01\].txt

Además, puedes definir patrones globales para todos los repositorios de tu sistema local estableciendo la propiedad:

git config --global core.excludesFile ~/.gitignore


En algunas ocasiones puede que requiera hacer una depuración de archivos .gitignore, por lo cual si tiene patrones complicados, o patrones repartidos en varios archivos, y resulta difícil averiguar por qué un archivo en particular está siendo ignorado. Para ello puede apoyarse del comando:

git check-ignore -v <Nombre del Fichero>
# git check-ignore -v debug.log


La salida (en este caso de ejemplo) se interpreta con la sintaxis:

.gitignore:3:*.log    debug.log

<fichero que contiene el patrón> : <número de línea del patrón> : <patrón> <nombre del fichero>

Ramas 🌲

Las ramas de Git son un puntero eficaz para las instantáneas de tus cambios. Cuándo quieres añadir una nueva función o solucionar un error, independientemente de su tamaño, generas una nueva rama para alojar estos cambios.

En conclusión, una rama representa una línea independiente de desarrollo. Las ramas sirven como una abstracción de los procesos de cambio, preparación y confirmación.

# Enumera todas las ramas de tu repositorio:
git branch
# Enumera todas las ramas remotas:
git branch -a


# Crear una rama:
git branch <Nombre de la Rama>
# Crea la rama y se mueve a ella:
git checkout -b <Nombre de la Rama>


# Cambiar el nombre de una rama:
git branch -m <Nuevo Nombre de la Rama>
# ó
git branch -m <Actual Nombre de la Rama> <Nuevo Nombre de la Rama>

↪️ Switch & Checkout

Si bien puedo moverme con el checkout, no está pensado para eso. Si no tuviésemos descargada la rama el switch muere pues no nos podríamos mover. El checkout descarga los cambios (no es para moverse entre ramas) y se desplaza a ese punto (cambia entre versiones de código que ya se encuentran en el sistema local).

# Moverse a una rama:
git switch <Nombre de la Rama>
git checkout <Nombre de la Rama>

Si bien tanto git switch como git checkout se pueden usar para navegar entre ramas en Git, tienen algunas diferencias sutiles. git switch se ocupa principalmente de cambiar ramas y tiene algunas opciones útiles que pueden ayudarlo a crear, fusionar o separar ramas fácilmente. git checkout puede hacer muchas cosas además de cambiar ramas, como restaurar archivos de confirmaciones anteriores, crear nuevas ramas o actualizar submódulos.

¿Qué ocurre cuando el nombre del archivo y el nombre de la rama son los mismos?, e intento correr: git checkout <FileName == BranchName>

🪢 Merge

En pocas palabras toma dos punteros de confirmación, normalmente los extremos de la rama, y encuentra una confirmación base común entre ellos. Una vez que Git encuentra una confirmación base en común, crea una “confirmación de fusión” nueva que combina los cambios de cada secuencia de confirmación de fusión puesta en cola.

# Estando parado en main:
git diff <Nombre de otra Rama>
git merge <Nombre de otra Rama>

👀: Observe que lo anterior me genera un nuevo commit de lo nuevo que ha traído. Además, lo anterior solo aplica para ramas locales, no las publicadas en GitHub.

╔ [🐆] Fast-Forward (--ff)

Una fusión rápida puede ocurrir cuando la rama actual no tiene confirmaciones extra comparada con la rama que estamos fusionando. Este tipo de fusión no crea una nueva confirmación, sino que fusiona las confirmaciones de la rama que estamos fusionando en la rama actual.

╠ [🐢] No-Fast-Foward (--no-ff)

Es genial si tu rama actual no tiene ningún commit extra en comparación con la rama que quieres fusionar, ¡pero desafortunadamente raramente es el caso! Si hemos confirmado cambios en la rama actual que la rama que queremos fusionar no tiene, git realizará una fusión no-fast-forward.

Con una fusión no-fast-forward, Git crea una nueva confirmación de fusión en la rama activa. Los commits padre de la confirmación apuntan tanto a la rama activa como a la rama que queremos fusionar.

╚ [] Conflicts

Al hacer un merge Git tratará de fusionar automáticamente los historiales independientes. Sin embargo, si encuentra datos que se han cambiado en ambos historiales (la misma parte del mismo archivo), no podrá combinarlos. Arrojará un conflicto de control de versiones y Git solicitará la intervención del usuario (para que puedas resolver los conflictos manualmente) para poder continuar.

👉 El problema no es que se haya tocado el mismo archivo, sino que tocó las mismas líneas 🧠.

Git le ayudará con indicadores visuales, en los archivos afectados, que marcan ambas caras 🎭 del contenido conflictivo.

# here is some content not affected by the conflict
# <<<<<<< main
# this is conflicted text from main
# =======
# this is conflicted text from feature branch
# >>>>>>> feature branch;

😤 Aunque los conflictos de fusión suelen ser bastante molestos, tiene todo el sentido: 🤔 Git no debería suponer qué cambio queremos mantener.

Una vez identificadas las secciones conflictivas, puedes entrar y arreglar la fusión a tu gusto (eliminar manualmente los cambios que no queremos mantener). Cuando estés listo para terminar la fusión, lo único que tienes que hacer es guardar los cambios, añadir el archivo cambiado de nuevo en los archivos conflictivos (git add) y confirmar los cambios (git commit).

⚙️ Eliminando una rama

Como por definición cada rama debe tener un propósito y debe unirse a la principal en algún momento,

git branch -d <Nombre de la Rama>
# Observe que la rama desapareció efectivamente (ver listado de ramas disponibles)
git branch
git reflog
# Sin embargo podemos regresar al estado antes de "eliminarla"
git checkout <ID del Commit del Delete de la Rama>
git tree
git switch <Nombre de la Rama>
# Observe que oficialmente no existe, pero las referencias sí

🪨 Lo anterior confirma la idea que he tratado de dar, y es que los commit están escritos en piedra 😬.

Con el parámetro -d Git evita que elimines la rama si tiene cambios que aún no se han fusionado.

Stash 📋


Recuerde que nuestro mantra es no hacer commit de código que no funciona. Por lo tanto, necesitamos una forma de hacer un commit temporal local (solamente sabrá de su existencia usted) que no afecte lo que estoy desarrollando.


git stash
# Si desea ponerle una descripción:
git stash save "Mensaje"
# Si desea ver la lista de los ya creados:
git stash list
# Si desea ver lo que contiene antes de recuperarlo:
git stash show
# Para recuperar todo lo que dejó guardado:
git stash pop
# Si tiene varios y desea elegir cuál recuperar puede usar su identificador/enumeración:
git stash pop stash@{No. Secuencia}
# Si desea eliminar los no utilizados:
git stash drop

GITHUB

Git Flow 🧩

Es un modelo alternativo de creación de ramas en Git en el que se utilizan ramas de función y varias ramas principales. Este flujo de trabajo no añade ningún concepto o comando nuevo, aparte de los que se necesitan para el flujo de trabajo de ramas de función. Lo que hace es asignar funciones muy específicas a las distintas ramas y definir cómo y cuándo deben interactuar ♟️.

Además de las ramas de función, utiliza ramas individuales para preparar, mantener y registrar publicaciones 🌿. La idea principal detrás de la estrategia de bifurcación de flujo de Git es aislar tu trabajo en diferentes tipos de ramas. Hay cinco tipos de ramas diferentes en total: Main | Develop | Feature | Release | Hotfix

Ventajas 🟢

  • Los distintos tipos de ramas permiten organizar el trabajo de forma fácil e intuitiva.
  • El proceso de desarrollo sistemático permite realizar pruebas eficientes.
  • El uso de ramas de publicación permite dar soporte de forma sencilla y continua a varias versiones del código de producción.

Retos 🚩

  • Dependiendo de la complejidad del producto, el modelo de flujo de Git podría complicar en exceso y ralentizar el proceso de desarrollo y el ciclo de publicación.
  • Debido al largo ciclo de desarrollo, el flujo Git históricamente no es capaz de soportar la Entrega Continua o la Integración Continua.

Fork 👋

Las bifurcaciones te permiten realizar cambios en un proyecto sin afectar al repositorio original (crea una copia completamente independiente). Después de bifurcar un repositorio, puedes obtener actualizaciones del repositorio para mantenerte al día y puedes proponer cambios con solicitudes de incorporación de cambios.


A diferencia de una fork, un clon crea una copia vinculada que seguirá sincronizándose con el repositorio de destino.


ℹ️💢 Si bifurcas un repositorio público, tu bifurcación seguirá existiendo incluso si se elimina el repositorio de origen 😮💨. Sin embargo, cuando eliminas un repositorio privado, también se eliminan todas sus bifurcaciones privadas 😶.

Está acción le indicará al propietario del repositorio que yo he hecho cambios (sin tener permisos para ello), recuerde primero sincronizar tu versión (estar al día).

Lo anterior creará una copia de ese repositorio que no nos pertenece a nuestra cuenta personal. Usualmente se trabaja o se envía desde otra rama diferente a main, pues si dañamos algo debes borrar la copia bifurcada y crear un fork de nuevo.

Pull Request 📨

Un pull request (flujo propio de GitHub diferente a un Pull) es una petición que el propietario de un fork hace al propietario del repositorio original para que este último incorpore los commits que están en el fork.

🆕 Una vez que se abre una solicitud de incorporación de cambios, puedes debatir y revisar los posibles cambios con los colaboradores y agregar confirmaciones de seguimiento antes de que los cambios se fusionen en la rama base.

En conclusión, es una forma de contribuir a un proyecto grupal o de código abierto (propuesta para combinar un conjunto de cambios de una rama con otra).

Ej: Hay un commit que tú has creado por delante de lo que lleva el proyecto original. El dueño ha seguido avanzando y tú enviaste un pull request. Si se hubiese atendido en el seg 1 no habría ningún conflicto 🙄.

👁️ El mensaje/comentario es con el que se quedará el commit del merge. Al ser aprobada y merge, saldrá como colaborador. Además, no basta marcarlo como resuelto debe también realizar el commit.

Issues 👥

A continuación, se expondrá cómo crear una plantilla YAML (BugTemplate.yml), recuerde que la ruta en donde debe poner dicho archivo es:


[Nombre del Repositorio]/.github/ISSUE_TEMPLATE


name: 🐛🐞 PLANTILLA PARA BUGS (nombre de la plantilla) 🐜🦗
description: Informe de un error de software que le está impidiendo la ejecución correcta (descripción antes de ingresar a la plantilla)
title: "[Bug]: <title>"
labels: ["bug", "fault", "Status: Waiting Triage"]
projects: ["Proj-ABC/1"]
assignees:
  - "JeisonAlarcon"
body:
  - type: markdown
    attributes:
      value: |
        # ¿CÓMO _REDACTAR_ CORRECTAMENTE UN ERROR?
        - Describe de forma clara y precisa cómo reproducir el error, incluyendo los datos relevantes que introdujiste.
        - Asegúrate de que el problema que estás reportando no haya sido reportado previamente. Si ya existe un reporte, puedes agregar un comentario con información adicional.
        - Proporciona información detallada sobre tu entorno de desarrollo, como el sistema operativo, la versión del navegador y cualquier otra información relevante.

        ## Best Practices
        - Incluye cualquier código relevante que pueda ayudar a los demás a entender el problema.
        - Sé muy específico centrándose en el problema y no mezcles en la misma incidencia distintos bugs.
        - Crea para cada error una nueva tarea para resolver.
        - Sé amable y respetuoso en tus interacciones con otros usuarios.

        ### _Otras Sintaxis Markdown:_

        [![N|Solid](https://cldup.com/dTxpPi9lDf.thumb.png)](https://github.com/JeisonAlarcon)
        ```
        127.0.0.1:8080
        ```

        > El éxito no consiste en no cometer errores,
        > sino en no cometer el mismo error dos veces.

        | Software |                              Documentation                             |
        |:--------:|:----------------------------------------------------------------------:|
        |     R    |              [link](https://hachyderm.io/@R_Contributors)              |
        |  Python  |                   [link](https://discuss.python.org)                   |
        |  Tableau |         [link](https://community.tableau.com/s/explore-forums)         |
        |   Excel  | [link](https://techcommunity.microsoft.com/t5/excel/bd-p/ExcelGeneral) |

        > Note: `Los errores son la prueba de que estás intentando`.
  - type: input
    id: Adrress
    attributes:
      label: Dirección de Residencia (Título de mi Input)
      description: No olvides especificar barrio, localidad y ciudad (Descripción de mi Input).
      placeholder: "Cll 20 #108A 15, Belén, Teusaquillo, Bogotá D.C."
    validations:
      required: true
  - type: input
    id: Email
    attributes:
      label: Correo Electrónico Secundario
      description: "No olvides escribir un correo personal no el institucional"
      placeholder: soporte@gmail.com (Marcador Transparente de ejemplo de mi Input)
    validations:
      required: false
  - type: textarea
    id: Environment
    attributes:
      label: ¿En qué ambiente se encontraba cuando sucedió el error?
      description: Cuéntanos detalladamente (_de forma cute con la sintaxis de Markdown_) tu entorno de trabajo.
      placeholder: ¡Este texto SÍ se verá debido a que NO ingresó nada en value!
    validations:
      required: true
  - type: textarea
    id: Logs
    attributes:
      label: ¿Cuál fue la salida del log por consola obtenida?
      description: |
        Por favor, copie y pegue cualquier salida de registro relevante. Esto se formateará automáticamente en código.
        Recuerde que en la descripción puede seguir usando sintaxis Markdown:
          - **OS**: Ubuntu 20.04
          - **Node**: 13.14.0
          - **npm**: 7.6.3
      value: |
          - OS  : 
          - Node: 
          - npm : 
      placeholder: ¡Este texto NO se verá debido a que ingresó algún valor en value!
      render: shell
    validations:
      required: false
  - type: dropdown
    id: Version-R
    attributes:
      label: Este es un menú desplegable con la versión que uso de R
      description: Recuerde que puede saber su versión de R, usando el comando -> version
      options:
        - R 4.0.5 "Shake and Throw" (Default)
        - R 4.0.4 "Lost Library Book"
        - R 4.0.3 "Bunny-Wunnies Freak Out"
      default: 0
    validations:
      required: true
  - type: dropdown
    id: Programming-Language
    attributes:
      label: ¿Qué lenguaje de programación maneja y fue útil para el hallazgo del bug?
      description: Este es otro dropdown pero con la opción de múltiple igual a TRUE
      multiple: true
      options:
        - R
        - Python
        - Java
        - SQL
        - TypeScript
  - type: checkboxes
    id: TyC
    attributes:
      label: Esta es una casilla de verificación
      description: Aceptas las condiciones expuestas en nuestra [página](https://example.com)
      options:
        - label: I agree
          required: true

Adicionalmente, también puede crear su plantilla con un Markdown (eso sí mucho más limitado en opciones), en este caso crearemos el archivo BugTemplate.md

---
name: 👀❌ PLANTILLA PARA BUGS (desde Markdown) 😖👁‍🗨
about: Informe de un error de software que le está impidiendo la ejecución correcta
title: '[Bug]: <title>'
labels: bug, fault, Waiting Triage
assignees: 'JeisonAlarcon'
---

<!--
Nota: Por favor, busca si ya existe una incidencia para el fallo que has encontrado.
-->

### Comportamiento Actual:
<!-- Una descripción concisa de lo que está experimentando. -->

### Comportamiento Esperado:
<!-- Una descripción concisa de lo que espera que ocurra. -->

### Pasos a Reproducir:
<!--
Ejemplo: pasos para reproducir el comportamiento:
1. En este entorno...
1. Con esta configuración...
1. Ejecuta '...'
1. Ver error...
-->

### Entorno:
<!--
Ejemplo:
- SO: Ubuntu 20.04
- Nodo: 13.14.0
- npm: 7.6.3
-->

### Cualquier Otra Cosa:
<!--
¿Vínculos? ¿Referencias? ¡Cualquier cosa que nos dé más contexto sobre el problema que está encontrando!
-->

Adicionalmente puede especificar un archivo de configuración global que afecte todas sus plantillas y podrá poner links si el Issue desea que sea comentado en otro lado. Ojo, el nombre de este archivo debe ser sí o sí config.yml.


blank_issues_enabled: false
contact_links:
  - name: RStudio Community Support
    url: https://community.rstudio.com
    about: Please ask and answer questions here.
  - name: Getting Shiny Help
    url: https://community.rstudio.com/c/shiny/8
    about: The first place to look for help with Shiny is Posit.
  - name: Posit Support Community
    url: https://stackoverflow.com/questions/tagged/shiny
    about: Questions posted on Stack Overflow are not closely monitored by our developers.

Finalmente, luego de todo lo desarrollado debería obtener algo como esto:

Actions 🚀

A continuación, se expondrá cómo crear dos acciones, una que consiste en refrescar una base de datos local cada vez que se realice un commit y otra en la cual se actualizará de manera automática una página web cuando. Tenga presente habilitar el usuario de GitHub Actions para poder escribir commits de manera automática.

Recuerde que la ruta en donde debe poner dicho archivo es:

[Nombre del Repositorio]/.github/workflows

🕥 Local


on:
  push:
    branches: main

jobs:
  my-first-action:
    runs-on: ubuntu-latest
    steps:
      - name: Set up R
        uses: r-lib/actions/setup-r@v2

      - name: Install packages
        uses: r-lib/actions/setup-r-dependencies@v2
        with:
          packages: |
            any::tidyverse 
            any::googlesheets4

      - name: Consultar el Repositorio
        uses: actions/checkout@v3

      - name: Importar Datos
        run: Rscript -e 'source("UpdateSalaries.R")'

      - name: Commit de los Resultados
        run: |
          git config --local user.email "actions@github.com"
          git config --local user.name "GitHub Actions"
          git add BD_GoogleSheet.rds
          git commit -m 'Data updated' || echo "No changes to commit"
          git push origin || echo "No changes to commit"

🌐 Web


on:
  push:
    branches: main

jobs:
  update-report:
    runs-on: ubuntu-latest
    steps:
      - name: Set up R
        uses: r-lib/actions/setup-r@v2

      - name: Install packages
        uses: r-lib/actions/setup-r-dependencies@v2
        with:
          packages: |
            any::tidyverse 
            any::googlesheets4
            any::gt

      - name: Set up Quarto
        uses: quarto-dev/quarto-actions/setup@v2

      - name: Check out repository
        uses: actions/checkout@v3
        
      - name: Render and Publish to Netlify
        uses: quarto-dev/quarto-actions/publish@v2
        with:
          target: netlify
          NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}

Varios 👁️‍🗨️

# Ojo que crea es una carpeta recordar meterse con cd, hasta que salga (main) en la consola
git clone HTTPS URL
# Ojo que para este paso ya debería existir un correo asociado a GitHub
git commit
# Nombre que se le asignó al repo remoto (origin)
git remote
# Más detalle de origin (2 operaciones diferentes push y fetch)
git remote -v


Recuerde ocultar el correo de GitHub. Para ello vaya a settings/emails y ahí vemos el primary email address (para no compartir o exponer el correo personal de GitHub). Asegurarse de mantener chuleado el Keep my address --private.