Azioni GitHub come CI/CD per un sito su un generatore statico e pagine GitHub

Azioni GitHub come CI/CD per un sito su un generatore statico e pagine GitHub

Dopo aver esplorato un po’ Habr, sono rimasto sorpreso dal fatto che siano stati pubblicati pochissimi articoli sull’argomento della funzionalità (beta) di GitHub – Actions.

Sembrerebbe che tale eufemismo possa essere spiegato dal fatto che la funzionalità è ancora in fase di test, anche se “beta”. Ma è una caratteristica utile della versione beta che consente di utilizzare questo strumento nei repository privati. Si tratta di lavorare con questa tecnologia di cui parlerò in questo articolo.

preistoria

Se iniziamo in ordine, probabilmente vale la pena ricordare che nel processo di ricerca di un'opzione veloce, conveniente, facile e gratuita per archiviare un sito Web personale "Informazioni su di me", ho dovuto trascorrere diverse notti e sfogliare molti articoli.

Alcune persone scelgono l'hosting, altri un server cloud e coloro che non vogliono capire il lavoro, l'interazione e il pagamento per tutto questo preferiscono caricare siti statici in un repository, poiché ora questo può essere fatto sia su GitHub che su GitLab.

Naturalmente, questa è la scelta personale di ognuno.

La mia scelta finale è stata GitHub Pages.

Informazioni sulle pagine

Chi non lo sa gh-pages - questa è un'opzione per archiviare la documentazione sotto forma di sito Web ed è fornita gratuitamente e, oltre alla documentazione, si propone anche di archiviare siti Web personali. Questa funzionalità è fornita da GitHub a tutti gli utenti ed è disponibile nelle impostazioni del repository.

Il repository del progetto utilizza un ramo gh-pages, per un sito utente: un repository separato con il nome username.github.io con le fonti del sito in master ramo.

Puoi vedere di più nella documentazione, ma lasciatemi solo notare che GitHub è sorprendentemente generoso nel consentire a chiunque di collegare il proprio dominio a un sito del genere semplicemente aggiungendo un file CNAME con il nome del dominio e configurando i DNS del tuo provider di dominio sui server GitHub.

Sono sicuro che ci siano molti articoli qui su come sviluppare un sito del genere, quindi non è di questo che parlerò ulteriormente.

Problema sorto

Il problema era che quando si utilizza un generatore statico, è necessario scrivere script aggiuntivi e utilizzare librerie per semplificare il processo di generazione delle pagine e di caricamento nel repository. Semplicemente, se memorizzi i sorgenti in un repository privato separato, ogni volta che viene apportata una modifica al sito, sarà necessario distribuire l'ambiente locale per la successiva generazione di pagine statiche e pubblicazione nel repository del sito principale.

C'è abbondanza generatori statici e hanno tutti lo stesso problema. Queste azioni richiedono troppo tempo e sforzi e alla fine rallentano il lavoro sul sito, soprattutto dopo diverse migrazioni da un sistema operativo all'altro o incidenti con perdita di dati sui dischi rigidi (nel mio caso è stato così).

Proprio di recente, in una notifica pop-up sul sito Web o in una newsletter di GitHub, è stato notato un CI/CD di nuova creazione, che ha consentito di eseguire queste azioni con il minimo sforzo.

Informazioni sui generatori di pagine statiche

Non focalizzerò particolare attenzione su questo sottopunto, ma condividerò un paio di tesi a cui sono giunto durante la selezione e l'utilizzo di quanto segue:

1) scegli un generatore adatto al tuo linguaggio di programmazione, oppure uno che sia il più chiaro possibile. Sono arrivato a questa idea in un momento in cui io stesso dovevo aggiungere alcune funzionalità affinché il sito funzionasse, aggiungere stampelle per una sua maggiore stabilità e automazione. Inoltre, questo è un buon motivo per scrivere tu stesso funzionalità aggiuntive sotto forma di plugin;

2) quale generatore scegliere è una scelta personale, ma vale la pena considerare che per l'immersione iniziale nel lavoro della funzionalità GitHub Pages è necessario prima installarlo Jekyll. Fortunatamente, ti consente di generare un sito Web dalle fonti direttamente nel repository (Lo ripeterò con la mia scelta).

La mia scelta del generatore si basa sul primo punto. Pellicano che è scritto in Python ha facilmente sostituito Jekyll, che mi è estraneo (l'ho usato per quasi un anno). Di conseguenza, anche creare e modificare articoli e lavorare su un sito Web offre ulteriore esperienza in una lingua che mi interessa.

__

Formulazione del problema

Il compito principale sarà scrivere uno script (in realtà un file di configurazione) che generi automaticamente pagine statiche da un repository privato. La soluzione coinvolgerà la funzionalità di un ambiente virtuale. Lo script stesso aggiungerà pagine già pronte al repository pubblico.

Strumenti per la soluzione

Strumenti che utilizzeremo per risolvere il problema:

  • Azioni GitHub;
  • Pitone 3.7;
  • Pellicano;
  • Idiota;
  • Pagine GitHub.

La soluzione

Quindi, dopo aver familiarizzato un po' con la documentazione e aver compreso come sono scritti gli script per le azioni, è diventato chiaro che questo meccanismo risolverà completamente il problema che si è presentato. Al momento in cui scrivo, è necessario abbonarsi per utilizzare questa funzionalità. per il beta testing!

Azioni GitHub come CI/CD per un sito su un generatore statico e pagine GitHub
Descrizione della nuova funzionalità da parte di Github stesso

La scrittura di uno script di azioni inizia con la creazione di un file con nome in una cartella .github e la sua sottocartella workflows. Questa operazione può essere eseguita manualmente o dall'editor nella scheda Azioni nella pagina del repository.

Azioni GitHub come CI/CD per un sito su un generatore statico e pagine GitHub
Esempio di un modulo di script vuoto

Commenterò brevemente il modulo

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.

Scriviamo il nostro in base al modello:

0) Puoi anche lasciare il nome "CI". È una questione di gusti.

1) Successivamente, è necessario selezionare l'azione/trigger che avvierà lo script, nel nostro caso si tratta del solito push di un nuovo commit nel repository.

on:
  push

2) Lasciamo come esempio anche l'immagine sulla base della quale verrà avviato lo script, poiché Ubuntu è abbastanza soddisfatto delle funzionalità necessarie. Guardando strumenti disponibili diventa chiaro che può trattarsi di qualsiasi immagine necessaria o semplicemente conveniente (o di un contenitore Docker basato su di essa).

  build:
    runs-on: ubuntu-latest

3) Nei passaggi, configureremo innanzitutto l'ambiente per prepararci al lavoro principale.

3.1) recarsi al ramo di cui abbiamo bisogno (passo standard checkout):

- uses: actions/checkout@v1

3.2) installa Python:

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

3.3) installa le dipendenze del nostro generatore:

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

3.4) creare una directory nella quale verranno generate le pagine del sito:

   - name: Make output folder
      run: mkdir output

4) Affinché il lavoro sul sito sia coerente, ovvero non elimini le modifiche precedenti e possa aggiungere modifiche al repository del sito senza conflitti, il passo successivo sarà clonare ogni volta il repository del sito:

   - 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

Questo passaggio richiama le variabili di sistema:

  • variabile GITHUB_ACTOR GitHub si installa da solo e questo è il nome utente per colpa del quale è stato avviato questo script;
  • variabile secrets.ACCESS_TOKEN questo viene generato token per la gestione di Github, possiamo passarlo come variabile d'ambiente impostandolo nella scheda Secrets le impostazioni del nostro repository. Tieni presente che durante la generazione il token ci verrà fornito una volta e non sarà possibile accedervi ulteriormente. Così come i valori degli oggetti Segreti.

5) Passiamo alla generazione delle nostre pagine:

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

I parametri passati al generatore sono responsabili della directory in cui verranno inviati i file generati (-o output) e il file di configurazione che utilizziamo per generare (-s publishconf.py; Puoi leggere l'approccio per separare la configurazione locale e la configurazione per la pubblicazione nella documentazione di Pelican).

Lascia che ti ricordi cosa c'è nella nostra cartella output Il repository del sito è già stato clonato.

6) Impostiamo git e indicizziamo i file modificati:

    - 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

A questo punto viene utilizzata una variabile già nota e viene indicata la directory di lavoro in cui verranno lanciati i comandi di questo passo. Altrimenti il ​​comando per andare alla directory di lavoro sarebbe simile a: cd output.

7) Generiamo un messaggio di commit, committiamo le modifiche e inseriamole nel repository. In modo che il commit non sia vano e quindi non produca un errore in bash (il risultato in output non lo è 0) — per prima cosa controlliamo se è necessario impegnarsi e spingere qualcosa. Per fare questo utilizziamo il comando git diff-index --quiet --cached HEAD -- che verrà inviato al terminale 0 se non sono presenti modifiche rispetto alla versione precedente del sito, e 1 ci sono tali cambiamenti. Quindi elaboriamo il risultato di questo comando. Pertanto, nelle informazioni sull'esecuzione dello script, registreremo informazioni utili sullo stato del sito in questa fase, invece di bloccarsi automaticamente e inviarci un rapporto sul crash dello script.

Eseguiamo queste azioni anche nella nostra directory con pagine già pronte.

   - 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

risultato

Di conseguenza, uno script di questo tipo ti consente di non pensare alla creazione di pagine statiche. Aggiungendo modifiche direttamente a un repository privato, sia lavorando con git da qualsiasi sistema o creando un file tramite l'interfaccia web GitHub, Actions farà tutto da solo. Se lo script si blocca in modo imprevisto, verrà inviata una notifica al tuo indirizzo email.

Codice completo

Lascerò la mia versione funzionante, in cui l'ultimo passaggio aggiunge l'invio di una notifica che un commit è stato inviato al repository principale.

Vengono utilizzati i Secret sopra descritti, dove vengono aggiunti il ​​token del bot e l'ID dell'utente a cui inviare il messaggio.

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

Screenshots

Azioni GitHub come CI/CD per un sito su un generatore statico e pagine GitHub
Il risultato di una delle esecuzioni visualizzate nella scheda Azioni del repository di origine

Azioni GitHub come CI/CD per un sito su un generatore statico e pagine GitHub
Messaggio dal bot relativo al completamento dello script

Link utili

Comprendere le azioni
Sintassi delle azioni
Elenco dei trigger
Opzioni per ambienti virtuali
Pagine GitHub
Elenco dei generatori statici

Fonte: habr.com

Aggiungi un commento