Un día me propuse un desafío: hacer un commit diario en GitHub durante todo un año. Ahora que ya tengo la disciplina de escribir código de manera constante. Se me ocurrió que quiero automatizar este proceso, y así mismo aprender a hacerlo. Pero ¿cómo podría automatizar un commit diario en GitHub? ¿Será que existe alguna herramienta o script que pueda usar para hacer commits automáticos? Estas eran las preguntas claves que debía resolver.

Después de investigar un poco, encontré que puedo automatizar este proceso utilizando GitHub Actions, que es una herramienta de CI/CD integrada en GitHub. Sin más preámbulos, en este artículo te mostraré un ejemplo de cómo podrías configurar un flujo de trabajo para hacer un commit diario a tu repositorio de manera automática.

Primero, necesitarás un script que realice el commit. Aquí hay un ejemplo simple de un script de Shell que podría hacer esto (.github/scripts/auto_commit.sh):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#.github/scripts/auto_commit.sh

#!/bin/sh

# Crea un nuevo archivo con la fecha y hora actual como contenido. Si ya existe un archivo, reemplaza el contenido con la fecha y hora actual.

echo $(date) > commit.txt

# Agrega el nuevo archivo al staging area
git add commit.txt

# Hace un commit con un mensaje
git commit -m "Commit automatizado"

# Empuja los cambios a GitHub
git push origin main

Luego, necesitarás crear un archivo del flujo de trabajo (“workflow”) de GitHub Actions para ejecutar este script una vez al día. Este archivo define una serie de pasos que se ejecutan automáticamente en respuesta a eventos específicos de GitHub, como un push o un pull request. Aquí hay un ejemplo de cómo podría ser ese archivo del flujo de trabajo (.github/workflows/daily-commit.yml):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
name: Daily Commit

on:
  schedule:
    - cron: "0 0 * * *" # Esto se ejecutará todos los días a medianoche

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v2

      - name: Run script
        run: bash /path/to/your/auto_commit_script.sh

Este flujo de trabajo se ejecutará todos los días a medianoche y ejecutará tu script, que hará un commit y lo empujará a tu repositorio.

Nota: Asegúrate de reemplazar /path/to/your/repo y /path/to/your/script.sh con las rutas reales a tu repositorio y a tu script, respectivamente. Además, este script asume que estás trabajando en la rama main. Si estás trabajando en una rama diferente, reemplaza main con el nombre de tu rama.

Además, necesitarás configurar las credenciales de Git en el flujo de trabajo de GitHub Actions para que puedas empujar a tu repositorio. Puedes hacer esto utilizando un token de acceso personal de GitHub y configurándolo como una variable de entorno en tu flujo de trabajo.

Es importante tener en cuenta que no es una buena práctica almacenar las credenciales de Git en texto plano. Sin embargo, en este caso, no hay forma de evitarlo, ya que el flujo de trabajo de GitHub Actions se ejecuta en un entorno aislado y no tienes acceso a las credenciales de Git almacenadas en tu máquina local. Por lo tanto, necesitarás crear un token de acceso personal de GitHub y configurarlo como una variable de entorno en tu flujo de trabajo.

¿Cómo configurar las credenciales de Git?

Para configurar las credenciales de Git en el flujo de trabajo de GitHub Actions, necesitarás un token de acceso personal de GitHub. Aquí te explico cómo hacerlo:

1. Genera un token de acceso personal en GitHub:

  • Ve a la configuración de tu cuenta de GitHub (haz clic en tu foto de perfil en la esquina superior derecha y selecciona "Settings" (Configuración) ).
  • En el menú de la izquierda, selecciona "Developer settings" (Configuración de desarrollador).
  • Luego, selecciona "Personal access tokens" (Tokens de acceso personal).
  • Haz clic en "Generate new token" (Generar nuevo token).
  • Dale un nombre descriptivo a tu token.
  • Selecciona los permisos que necesitas para tu flujo de trabajo, en este caso, necesitarás el permiso repo y haz clic en "Generate token" (Generar token).

2. Configura el token de acceso personal como una variable de entorno en tu flujo de trabajo:

En tu archivo del flujo de trabajo (.github/workflows/daily-commit.yml), debes agregar una nueva etapa antes de la etapa Run script para configurar las credenciales de Git. Aquí te muestro cómo:

  • Opción 1:
1
2
3
4
5
6
7
8
- name: Set up Git credentials
  run: |
    git config --global user.name "your-username"
    git config --global user.email "your-email@example.com"
    git config --global credential.helper store
    echo "https://$TOKEN:x-oauth-basic@github.com" > ~/.git-credentials
  env:
    TOKEN: $

Nota:

  • Reemplaza “your-username” y “your-email@example.com” con tu nombre de usuario de GitHub y tu correo electrónico.
  • En la última línea, TOKEN es una variable de entorno que contiene tu token de acceso personal. Necesitarás agregar este token a las “Secrets” de tu repositorio en GitHub (más sobre esto más adelante).
  • Opción 2:
1
2
3
4
5
- name: Set up Git credentials
  run: |
    git config --global user.name ""your-username"
    git config --global user.email "your-email@example.com"
    git remote set-url origin https://$@github.com/username/repo.git

Nota:

  • Al igual que en opción 1, reemplaza “your-username” y “your-email@example.com” con tu nombre de usuario de GitHub y tu correo electrónico.
Así debería estar quedando el archivo de workflow de GitHub Actions ```yaml # .github/workflows/daily-commit.yml name: Daily Commit on: schedule: - cron: "0 0 * * *" jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Set up Git credentials run: | git config --global user.name ""your-username" git config --global user.email "your-email@example.com" git remote set-url origin https://$@github.com/username/repo.git ```

¿Cuáles son las diferencias entre las opciones 1 y 2?

La principal diferencia entre estos dos fragmentos de código es cómo se manejan las credenciales de Git:

  • En la Opción 1, se utiliza git config --global credential.helper store para almacenar las credenciales de usuario en un archivo en su directorio local. Luego, se crea un archivo .git-credentials en el directorio home del usuario con la URL que incluye el token de autenticación. Este método almacena las credenciales en un archivo en texto plano en su sistema.

  • En la Opción 2, se utiliza git remote set-url origin para cambiar la URL del repositorio remoto ‘origin’ a una que incluya el token de autenticación. Este método no almacena las credenciales en su sistema, sino que las incluye en la URL del repositorio remoto.

Ambos métodos tienen sus ventajas y desventajas. El almacenamiento de credenciales es más seguro, ya que no expone el token en la línea de comandos, pero puede ser menos seguro si otras personas tienen acceso a su sistema. El uso de la URL del repositorio remoto es menos seguro, ya que expone el token en la línea de comandos, pero puede ser más seguro si tu sistema es seguro y sólo tu tiene acceso a él.

3. Agrega tu token de acceso personal a las "Secrets" de tu repositorio:

  • Ve a la página principal de tu repositorio en GitHub y selecciona "Settings" (Configuración).
  • Luego, selecciona "Secrets" en el menú de la izquierda.
  • Haz clic en "New repository secret" (Nuevo secreto del repositorio).
  • Ingresa YOUR_GITHUB_TOKEN como el nombre del secreto y pega tu token de acceso personal en el campo Value (Valor).
  • Haz clic en "Add secret" (Agregar secreto).

Ahora, tu flujo de trabajo de GitHub Actions debería ser capaz de empujar a tu repositorio utilizando tu token de acceso personal.

4. Ejecuta tu flujo de trabajo de GitHub Actions manualmente:

En el archivo del flujo de trabajo de GitHub Actions, debes agregar un evento que permita ejecutar el flujo de trabajo manualmente. Aquí te muestro cómo:

1
2
on:
  workflow_dispatch: # This allows you to manually trigger the workflow

Ahora, puedes ejecutar tu flujo de trabajo de GitHub Actions manualmente haciendo clic en el botón "Run workflow" (Ejecutar flujo de trabajo) en la página principal de tu repositorio en GitHub.

Así debería estar quedando el archivo de workflow de GitHub Actions ```yaml # .github/workflows/daily-commit.yml name: Daily Commit on: schedule: - cron: "0 0 * * *" workflow_dispatch: # This allows you to manually trigger the workflow jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Set up Git credentials run: | git config --global user.name ""your-username" git config --global user.email "your-email@example.com" git remote set-url origin https://$@github.com/username/repo.git ```

Error al ejecutar el script de Shell.

Si llegaste hasta acá y aún no puedes ejecutar el script de Shell, asegúrate de que el script de Shell tenga permisos de ejecución. Puedes hacer esto agregando el siguiente comando a tu flujo de trabajo de GitHub Actions:

1
2
3
4
- name: Run script
  run: |
    chmod +x ./.github/scripts/auto_commit.sh
    bash ./.github/scripts/auto_commit.sh
Así debería estar quedando el archivo de workflow de GitHub Actions ```yaml # .github/workflows/daily-commit.yml name: Daily Commit on: schedule: - cron: "0 0 * * *" workflow_dispatch: # This allows you to manually trigger the workflow jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Set up Git credentials run: | git config --global user.name ""your-username" git config --global user.email "your-email@example.com" git remote set-url origin https://$@github.com/username/repo.git - name: Run script run: | chmod +x ./.github/scripts/auto_commit.sh bash ./.github/scripts/auto_commit.sh ```

Error después de correr GitHub Actions

En este punto, el script de Shell ya corre, pero genera un error al intentar hacer el commit y empujar los cambios a tu repositorio. Aquí hay un ejemplo de lo que podría verse en la pestaña "Actions" (Acciones) de tu repositorio en GitHub:

1
2
3
4
5
6
7
Run chmod +x ./.github/scripts/auto_commit.sh
[main 8a928cc] Commit automatizado
 1 file changed, 1 insertion(+)
 create mode 100644 commit.txt
remote: Write access to repository not granted.
fatal: unable to access 'https://github.com/username/repoName.git/': The requested URL returned error: 403
Error: Process completed with exit code 128.

Este error significa que el flujo de trabajo de GitHub Actions NO tiene los permisos necesarios para escribir/empujar a tu repositorio. Esto puede suceder por varias razones:

  • Puede ser que el token de acceso personal que configuraste NO tenga los permisos correctos. Asegúrate de que el token de acceso personal tenga el permiso repo.
  • Asegúrate que el token de acceso personal esté bien escrito en el archivo del flujo de trabajo y en las “Secrets” de tu repositorio.
  • Asegúrate que los permisos a los trabajos estén bien asignados en el archivo del flujo de trabajo.

Asignar permisos a los trabajos

Necesitarás asignar los permisos a los trabajos en un flujo de trabajo utilizando la palabra clave "permissions". En este caso, debería asignar el permiso "contents" al trabajo que estás ejecutando en el script. Aquí te muestro cómo:

1
2
3
4
permissions: # Permisos para el flujo de trabajo - Esto es necesario para crear un commit
  issues: write
  pull-requests: write
  contents: write

Conoce más sobre los permisos de los trabajos en Asignar permisos a los trabajos.


En resumen, para automatizar tus commits diarios en GitHub con GitHub Actions, necesitarás un script que realice el commit y un flujo de trabajo de GitHub Actions que ejecute ese script una vez al día. Además, necesitarás configurar las credenciales de Git en el flujo de trabajo para que puedas empujar a tu repositorio. Esto se puede hacer utilizando un token de acceso personal de GitHub y configurándolo como una variable de entorno en tu flujo de trabajo. Finalmente, necesitarás asignar los permisos correctos a tu flujo de trabajo para que pueda crear un commit y empujar a tu repositorio. Aquí te dejo los archivos que necesitarás para hacer esto:

Flujo de Trabajo de GitHub Actions

Aquí está el archivo del flujo de trabajo (workflow) completo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# .github/workflows/daily-commit.yml
name: Daily Commit

on:
  schedule:
    - cron: "0 0 * * *" # Esto se ejecutará todos los días a medianoche
  workflow_dispatch: # esto permite ejecutar el flujo de trabajo manualmente

jobs:
  build:
    runs-on: ubuntu-latest

    permissions: # Otorga los permisos para el flujo de trabajo - Esto es necesario para crear un commit
      issues: write
      pull-requests: write
      contents: write

    steps:
      - uses: actions/checkout@v2

      - name: Set up Git credentials # Configura las credenciales de Git
        run: |
          git config --global user.name ""your-username"
          git config --global user.email "your-email@example.com"
          git remote set-url origin https://$@github.com/username/repo.git

      - name: Run script # Ejecuta el script
        run: |
          chmod +x ./.github/scripts/auto_commit.sh
          bash ./.github/scripts/auto_commit.sh

Script de Shell

Aquí está el archivo del script de Shell completo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# .github/scripts/auto_commit.sh
#!/bin/sh

# Check if the file exists, if not, create it
if [ ! -f ./days/auto-commit.md ]; then
    echo "- $(date)  " > ./days/auto-commit.md
	# it create a new file with the current date and time as a list item. the space after the date creates a line break
	# the > operator creates a new file
else
    # Append (add) the current date and time to the existing content of the file as a new list item
    echo "- $(date)  " >> ./days/auto-commit.md
	# the >> operator appends the output to the end of the file
fi

# Add the new file to the staging area
git add ./days/auto-commit.md

# Make a commit with a message
git commit -m "Commit automatizado $(date)"

# Push the changes to GitHub
git push origin main

git commit -m "Happy coding! 🚀"

Acknowledgments 📚

Resources list that I find helpful and would like to give credit to.