Acciones de GitHub como CI/CD para el sitio del generador estático y las páginas de GitHub

Acciones de GitHub como CI/CD para el sitio del generador estático y las páginas de GitHub

Después de explorar un poco Habr, me sorprendió que se hayan publicado muy pocos artículos sobre el tema de la función (beta) de GitHub: Acciones.

Parece que esta subestimación se explica por el hecho de que la funcionalidad aún está en fase de pruebas, aunque sea “beta”. Pero es una característica útil de la versión beta que permite utilizar esta herramienta en repositorios privados. Se trata de trabajar con esta tecnología de la que hablaré en este artículo.

Prehistoria

Si comenzamos en orden, probablemente valga la pena mencionar que en el proceso de búsqueda de una opción rápida, conveniente, fácil y gratuita para almacenar un sitio web personal "Acerca de mí", tuve que pasar varias noches y revisar muchos artículos.

Algunas personas eligen hosting, otras un servidor en la nube, y a quienes no quieren entender el trabajo, la interacción y el pago de todo esto les gusta cargar sitios estáticos en un repositorio, ya que ahora esto se puede hacer tanto en GitHub como en GitLab.

Por supuesto, esta es la elección personal de cada uno.

Mi elección final fueron las páginas de GitHub.

Acerca de las páginas

Quien no sabe gh-pages - esta es una opción para almacenar documentación en forma de sitio web y se proporciona de forma gratuita, y además de la documentación, también se propone almacenar sitios web personales. GitHub proporciona esta funcionalidad a todos los usuarios y está disponible en la configuración del repositorio.

El repositorio del proyecto utiliza una rama. gh-pages, para un sitio de usuario: un repositorio separado con el nombre username.github.io con fuentes del sitio en master rama

Se pueden ver más detalles en la documentación, pero permítanme señalar que GitHub es sorprendentemente generoso al permitir que cualquiera vincule su propio dominio a dicho sitio simplemente agregando un archivo. CNAME con el nombre de dominio y configurando el DNS de su proveedor de dominio en los servidores de GitHub.

Estoy seguro de que hay muchos artículos aquí sobre cómo desarrollar un sitio de este tipo, así que no voy a hablar más de eso.

Ocurrencia de un problema

El problema era que cuando se utiliza un generador estático, es necesario escribir scripts adicionales y utilizar bibliotecas para simplificar el proceso de generación de páginas y cargarlas en el repositorio. Simplemente, si almacena las fuentes en un repositorio privado separado, cada vez que haya algún cambio en el sitio, será necesario implementar el entorno local para la generación posterior de páginas estáticas y su publicación en el repositorio principal del sitio.

hay una abundancia generadores estáticos y todos tienen el mismo problema. Estas acciones requieren demasiado tiempo y esfuerzo y, en última instancia, ralentizan el trabajo en el sitio, especialmente después de varias migraciones de un sistema operativo a otro o incidentes con pérdida de datos en los discos duros. (este fue el caso en mi caso).

Recientemente, ya sea en una notificación emergente en el sitio web o en un boletín de GitHub, se notó un CI/CD recientemente creado, que permitió llevar a cabo estas acciones con un mínimo esfuerzo.

Acerca de los generadores de páginas estáticas

No centraré especial atención en este subtema, pero compartiré un par de tesis a las que llegué durante la selección y uso de lo siguiente:

1) elige un generador que se adapte a tu lenguaje de programación, o uno que sea lo más claro posible. Se me ocurrió esta idea en un momento en el que yo mismo tenía que agregar alguna funcionalidad para que el sitio funcionara, agregar muletas para su mayor estabilidad y automatización. Además, esta es una buena razón para escribir usted mismo funciones adicionales en forma de complementos;

2) qué generador elegir es una elección personal, pero vale la pena considerar que para la inmersión inicial en el funcionamiento de la funcionalidad de GitHub Pages, primero debe instalar Jekyll. Afortunadamente, te permite generar un sitio web a partir de fuentes directamente en el repositorio. (Repetiré esto con mi elección).

Mi elección de generador se basa en el primer punto. Pelícano que está escrito en Python reemplazó fácilmente a Jekyll, lo cual es extraño para mí (lo usé durante casi un año). Como resultado, incluso crear y editar artículos y trabajar en un sitio web me brinda experiencia adicional en un idioma que me interesa.

__

Formulación del problema

La tarea principal será escribir un script (en realidad, un archivo de configuración) que generará automáticamente páginas estáticas desde un repositorio privado. La solución implicará la funcionalidad de un entorno virtual. El script en sí agregará páginas ya preparadas al repositorio público.

Herramientas para la solución

Herramientas que utilizaremos para solucionar el problema:

  • Acciones de GitHub;
  • Pitón 3.7;
  • Pelícano;
  • Git;
  • Páginas de GitHub.

La solución

Entonces, después de familiarizarse un poco con la documentación y comprender cómo se escriben los scripts de Acciones, quedó claro que este mecanismo resolverá por completo el problema que ha surgido. Al momento de escribir este artículo, debe suscribirse para utilizar esta función. para pruebas beta!

Acciones de GitHub como CI/CD para el sitio del generador estático y las páginas de GitHub
Descripción de la nueva funcionalidad por parte del propio Github

La escritura de un script de Acciones comienza con la creación de un archivo con nombre en una carpeta .github y su subcarpeta workflows. Esto se puede hacer manualmente o desde el editor en la pestaña Acciones en la página del repositorio.

Acciones de GitHub como CI/CD para el sitio del generador estático y las páginas de GitHub
Ejemplo de un formulario de guión en blanco

Comentaré brevemente el formulario.

name: CI    # название скрипта: будет отображаться во вкладке Actions

on: [push]  # действие, по которому запускается данный скрипт

jobs:       # роботы, которые будут выполняться
  build:    # сборка, которая..

    runs-on: ubuntu-latest      # ..будет запущена на основе этого образа

    steps:              # шаги которые будут проделаны после запуска образа
    - uses: actions/checkout@v1     # переход в самую актуальную ветку
    - name: Run a one-line script   # имя работы номер 1
      run: echo Hello, world!       # суть работы номер 1 (bash-команда записана в одну строку)
    - name: Run a multi-line script   # имя работы номер 2
      run: |                    # суть работы номер 2 (многострочная)
        echo Add other actions to build,
        echo test, and deploy your project.

Escribamos el nuestro según la plantilla:

0) También puedes dejar el nombre “CI”. Es una cuestión de gustos.

1) A continuación, debe seleccionar la acción/activador que iniciará el script; en nuestro caso, este es el envío habitual de una nueva confirmación al repositorio.

on:
  push

2) También dejaremos como ejemplo la imagen a partir de la cual se ejecutará el script, ya que Ubuntu está bastante satisfecho con la funcionalidad necesaria. Mirando a herramientas disponibles queda claro que puede ser cualquier imagen necesaria o simplemente conveniente (o un contenedor Docker basado en ella).

  build:
    runs-on: ubuntu-latest

3) En los pasos, primero configuraremos el entorno para prepararnos para el trabajo principal.

3.1) ir a la sucursal que necesitamos (paso estándar checkout):

- uses: actions/checkout@v1

3.2) instalar Python:

    - name: Set up Python
      uses: actions/setup-python@v1
      with:
        python-version: 3.7

3.3) instalar las dependencias de nuestro generador:

    - name: Install dependencies
      run: |
          python -m pip install --upgrade pip
          pip install -r requirements.txt

3.4) crear un directorio en el que se generarán las páginas del sitio:

   - name: Make output folder
      run: mkdir output

4) Para que el trabajo en el sitio sea consistente, es decir, no eliminar cambios anteriores y poder agregar cambios al repositorio del sitio sin conflictos, el siguiente paso será clonar el repositorio del sitio cada vez:

   - name: Clone master branch
      run: git clone "https://${{ secrets.ACCESS_TOKEN }}@github.com/${GITHUB_ACTOR}/${GITHUB_ACTOR}.github.io.git" --branch master --single-branch ./output

Este paso llama a las variables del sistema:

  • variable GITHUB_ACTOR GitHub se instala solo y este es el nombre de usuario por cuya culpa se inició este script;
  • variable secrets.ACCESS_TOKEN esto se genera token para administrar Github, podemos pasarlo como una variable de entorno configurándolo en la pestaña Secrets la configuración de nuestro repositorio. Tenga en cuenta que durante la generación el token se nos proporcionará una vez y no habrá más acceso a él. Así como los valores de los ítems de Secretos.

5) Pasemos a generar nuestras páginas:

   - name: Generate static pages
      run: pelican content -o output -s publishconf.py

Los parámetros pasados ​​al generador son responsables del directorio donde se enviarán los archivos generados (-o output) y el archivo de configuración que utilizamos para generar (-s publishconf.py; Puede leer sobre el enfoque para separar la configuración local y la configuración para publicación en la documentación de Pelican.).

Déjame recordarte lo que hay en nuestra carpeta. output El repositorio del sitio ya ha sido clonado.

6) Configuremos git e indexemos nuestros archivos modificados:

    - name: Set git config and add changes
      run: |
          git config --global user.email "${GITHUB_ACTOR}@https://users.noreply.github.com/"
          git config --global user.name "${GITHUB_ACTOR}"
          git add --all
      working-directory: ./output

En este punto se utiliza una variable ya conocida y se indica el directorio de trabajo en el que se ejecutarán los comandos de este paso. De lo contrario, el comando para ir al directorio de trabajo se vería así: cd output.

7) Generemos un mensaje de confirmación, confirmemos los cambios y los enviemos al repositorio. Para que el commit no sea en vano y por tanto no produzca un error en bash (el resultado de salida no es 0) — primero, verifiquemos si es necesario comprometerse e impulsar algo. Para ello utilizamos el comando git diff-index --quiet --cached HEAD -- que saldrá al terminal 0 si no hay cambios con respecto a la versión anterior del sitio, y 1 hay tales cambios. Luego procesamos el resultado de este comando. Por lo tanto, en la información sobre la ejecución del script, registraremos información útil sobre el estado del sitio en esta etapa, en lugar de fallar automáticamente y enviarnos un informe sobre el fallo del script.

También realizamos estas acciones en nuestro directorio con páginas ya preparadas.

   - name: Push and send notification
      run: |
          COMMIT_MESSAGE="Update pages on $(date +'%Y-%m-%d %H:%M:%S')"
          git diff-index --quiet --cached HEAD -- && echo "No changes!" && exit 0 || echo $COMMIT_MESSAGE
          # Only if repo have changes
          git commit -m "${COMMIT_MESSAGE}"
          git push https://${{ secrets.ACCESS_TOKEN }}@github.com/${GITHUB_ACTOR}/${GITHUB_ACTOR}.github.io.git master
      working-directory: ./output

resultado

Como resultado, dicho script le permite no pensar en crear páginas estáticas. Al agregar cambios directamente a un repositorio privado, ya sea trabajando con git desde cualquier sistema o creando un archivo a través de la interfaz web de GitHub, Actions hará todo por sí mismo. Si el script falla inesperadamente, se enviará una notificación a su correo electrónico.

código completo

Dejaré mi versión de trabajo, en la que el último paso agrega el envío de una notificación de que se ha enviado una confirmación al repositorio principal.

Se utilizan los secretos descritos anteriormente, donde se agregan el token del bot y el ID de usuario al que se debe enviar el mensaje.

name: Push content to the user's GitHub pages repository

on:
  push

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v1
    - name: Set up Python
      uses: actions/setup-python@v1
      with:
        python-version: 3.7
    - name: Install dependencies
      run: |
          python -m pip install --upgrade pip
          pip install -r requirements.txt
    - name: Make output folder
      run: mkdir output
    - name: Clone master branch
      run: git clone "https://${{ secrets.ACCESS_TOKEN }}@github.com/${GITHUB_ACTOR}/${GITHUB_ACTOR}.github.io.git" --branch master --single-branch ./output
    - name: Generate static pages
      run: pelican content -o output -s publishconf.py
    - name: Set git config and add changes
      run: |
          git config --global user.email "${GITHUB_ACTOR}@https://users.noreply.github.com/"
          git config --global user.name "${GITHUB_ACTOR}"
          git add --all
      working-directory: ./output
    - name: Push and send notification
      run: |
          COMMIT_MESSAGE="Update pages on $(date +'%Y-%m-%d %H:%M:%S')"
          git diff-index --quiet --cached HEAD -- && echo "No changes!" && exit 0 || echo $COMMIT_MESSAGE
          git commit -m "${COMMIT_MESSAGE}"
          git push https://${{ secrets.ACCESS_TOKEN }}@github.com/${GITHUB_ACTOR}/${GITHUB_ACTOR}.github.io.git master
          curl "https://api.telegram.org/bot${{ secrets.BOT_TOKEN }}/sendMessage?text=$COMMIT_MESSAGE %0ALook at ${GITHUB_ACTOR}.github.io %0ARepository%3A github.com/${GITHUB_ACTOR}/${GITHUB_ACTOR}.github.io&chat_id=${{ secrets.ADMIN_ID }}"
      working-directory: ./output

Imágenes

Acciones de GitHub como CI/CD para el sitio del generador estático y las páginas de GitHub
El resultado de una de las ejecuciones que se muestra en la pestaña Acciones del repositorio de origen

Acciones de GitHub como CI/CD para el sitio del generador estático y las páginas de GitHub
Mensaje del bot sobre la finalización del script.

Enlaces de interés

Comprender las acciones
Sintaxis de acciones
Lista de desencadenantes
Opciones para entornos virtuales
Páginas de Github
Lista de generadores estáticos

Fuente: habr.com

Añadir un comentario