GitHub-åtgärder som CI/CD för en webbplats på en statisk generator och GitHub-sidor

GitHub-åtgärder som CI/CD för en webbplats på en statisk generator och GitHub-sidor

Efter att ha letat igenom Habr lite blev jag förvånad över att väldigt få artiklar har publicerats om ämnet GitHubs (beta) funktion - Actions.

Det verkar som att en sådan underdrift kan förklaras av det faktum att funktionaliteten fortfarande testas, om än "beta". Men det är en användbar funktion i betaversionen som gör att det här verktyget kan användas i privata arkiv. Det handlar om att arbeta med denna teknik som jag kommer att prata om i den här artikeln.

förhistoria

Om vi ​​börjar i ordning, så är det förmodligen värt att nämna att jag var tvungen att spendera flera nätter och leta efter ett snabbt, bekvämt, enkelt och gratis alternativ för att lagra en personlig "Om mig"-webbplats.

Vissa människor väljer hosting, andra en molnserver och de som inte vill förstå arbetet, interaktionen och betalningen för allt detta som att ladda upp statiska sajter till ett arkiv, eftersom detta nu kan göras på både GitHub och GitLab.

Naturligtvis är detta allas personliga val.

Mitt sista val var GitHub Pages.

Om sidor

Vem är inte medveten gh-pages - detta är ett alternativ för att lagra dokumentation i form av en webbplats och det tillhandahålls kostnadsfritt, och förutom dokumentation föreslås det även att lagra personliga webbplatser. Den här funktionen tillhandahålls av GitHub till alla användare och är tillgänglig i förvarets inställningar.

Projektförvaret använder en gren gh-pages, för en användarwebbplats - ett separat arkiv med namnet username.github.io med webbplatskällor i master gren.

Du kan se fler detaljer i dokumentation, men låt mig bara notera att GitHub är förvånansvärt generös med att tillåta vem som helst att länka sin egen domän till en sådan webbplats genom att helt enkelt lägga till en fil CNAME med domännamnet och konfigurera DNS för din domänleverantör på GitHub-servrarna.

Jag är säker på att det finns många artiklar här om hur man utvecklar en sådan sida, så det är inte det jag ska prata om vidare.

Uppkomst av ett problem

Problemet var att när man använder en statisk generator, finns det ett behov av att skriva ytterligare skript och använda bibliotek för att förenkla processen att generera sidor och ladda in dem i förvaret. Helt enkelt, om du lagrar källorna i ett separat privat arkiv, så var det varje gång det sker någon förändring på webbplatsen, det var nödvändigt att distribuera den lokala miljön för den efterföljande generationen av statiska sidor och publicering i huvudwebbplatsens arkiv.

Det finns ett överflöd statiska generatorer och alla har samma problem. Dessa åtgärder tar för mycket tid och ansträngning, och i slutändan saktar de ner arbetet på webbplatsen, särskilt efter flera migreringar från OS till OS eller incidenter med dataförlust på hårddiskar (så var fallet i mitt fall).

Alldeles nyligen, antingen i ett popup-meddelande på hemsidan eller i ett nyhetsbrev från GitHub, uppmärksammades en nybyggd CI/CD, som gjorde det möjligt att utföra dessa åtgärder med minimal ansträngning.

Om statiska sidgeneratorer

Jag kommer inte att fokusera särskilt på denna underpunkt, men jag kommer att dela ett par avhandlingar som jag kom fram till under urvalet och användningen av följande:

1) välj en generator som passar ditt programmeringsspråk, eller en som är så tydlig som möjligt. Jag kom på den här idén vid en tidpunkt då jag själv var tvungen att lägga till lite funktionalitet för att sajten skulle fungera, lägga till kryckor för dess större stabilitet och automatisering. Dessutom är detta en bra anledning att själv skriva ytterligare funktionalitet i form av plugins;

2) vilken generator att välja är ett personligt val, men det är värt att överväga att för den första nedsänkningen i arbetet med GitHub Pages-funktionaliteten måste du först installera Jekyll. Lyckligtvis låter det dig skapa en webbplats från källor direkt i förvaret (Jag kommer att upprepa detta med mitt val).

Mitt val av generator är baserat på den första punkten. Pelikan som är skrivet i Python ersatte lätt Jekyll, vilket är främmande för mig (använt den i nästan ett år). Som ett resultat ger även att skapa och redigera artiklar och arbeta på en webbplats ytterligare erfarenhet på ett språk som är intressant för mig.

__

Problem uttalande

Huvuduppgiften kommer att vara att skriva ett skript (faktiskt en konfigurationsfil) som automatiskt skulle generera statiska sidor från ett privat arkiv. Lösningen kommer att involvera funktionaliteten i en virtuell miljö. Skriptet i sig kommer att lägga till färdiga sidor till det offentliga arkivet.

Verktyg för lösning

Verktyg som vi kommer att använda för att lösa problemet:

  • GitHub-åtgärder;
  • Python3.7;
  • Pelikan;
  • Git;
  • GitHub-sidor.

Lösning

Så efter att ha bekantat dig lite med dokumentationen och förstått hur skript för Actions skrivs, blev det klart att denna mekanism helt kommer att lösa problemet som har uppstått. I skrivande stund måste du prenumerera för att använda den här funktionen. för betatestning!

GitHub-åtgärder som CI/CD för en webbplats på en statisk generator och GitHub-sidor
Beskrivning av den nya funktionen av Github själv

Att skriva ett Actions-skript börjar med att skapa en namngiven fil i en mapp .github och dess undermapp workflows. Detta kan göras antingen manuellt eller från redigeraren på fliken Åtgärder på arkivsidan.

GitHub-åtgärder som CI/CD för en webbplats på en statisk generator och GitHub-sidor
Exempel på ett tomt skriptformulär

Jag kommer kort kommentera formuläret

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.

Låt oss skriva vårt eget baserat på mallen:

0) Du kan också lämna namnet "CI". Det är en smaksak.

1) Därefter måste du välja åtgärden/triggern som kommer att starta skriptet, i vårt fall är detta den vanliga pushen av en ny commit till förvaret.

on:
  push

2) Vi kommer också att lämna bilden på grundval av vilken skriptet kommer att lanseras som ett exempel, eftersom Ubuntu är ganska nöjd med den nödvändiga funktionaliteten. Tittar på tillgängliga verktyg det blir tydligt att detta kan vara vilken nödvändig eller helt enkelt bekväm bild som helst (eller en Docker-behållare baserad på den).

  build:
    runs-on: ubuntu-latest

3) I stegen kommer vi först att sätta upp miljön för att förbereda för huvudarbetet.

3.1) gå till grenen vi behöver (standardsteg checkout):

- uses: actions/checkout@v1

3.2) installera Python:

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

3.3) installera beroenden för vår generator:

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

3.4) skapa en katalog där webbplatssidorna kommer att genereras:

   - name: Make output folder
      run: mkdir output

4) För att arbetet på sajten ska vara konsekvent, nämligen att inte ta bort tidigare ändringar och för att kunna lägga till ändringar i platsförrådet utan konflikter, blir nästa steg att klona platsförrådet varje gång:

   - 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

Detta steg anropar systemvariabler:

  • variabel GITHUB_ACTOR GitHub installerar sig själv, och detta är användarnamnet vars fel detta skript lanserades;
  • variabel secrets.ACCESS_TOKEN detta genereras token för att hantera Github, kan vi skicka den som en miljövariabel genom att ställa in den i fliken Secrets våra arkivinställningar. Observera att under genereringen kommer token att tillhandahållas oss en gång, det kommer inte att finnas ytterligare åtkomst till den. Samt värdena på Secrets-objekten.

5) Låt oss gå vidare till att skapa våra sidor:

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

Parametrarna som skickas till generatorn är ansvariga för katalogen dit de genererade filerna kommer att skickas (-o output) och konfigurationsfilen som vi använder för att generera (-s publishconf.py; Du kan läsa om tillvägagångssättet för att separera den lokala konfigurationen och konfigurationen för publicering i Pelican-dokumentationen).

Låt mig påminna dig om vad som finns i vår mapp output Webbplatsförrådet har redan klonats.

6) Låt oss ställa in git och indexera våra ändrade filer:

    - 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

Vid denna tidpunkt används en redan känd variabel och arbetskatalogen indikeras där kommandona från detta steg kommer att startas. Kommandot för att gå till arbetskatalogen skulle annars se ut så här - cd output.

7) Låt oss skapa ett commit-meddelande, begå ändringarna och skjuta in dem i arkivet. Så att commit inte är förgäves och därför inte ger ett fel i bash (utgångsresultatet är det inte 0) — låt oss först kontrollera om det är nödvändigt att begå och driva något alls. För att göra detta använder vi kommandot git diff-index --quiet --cached HEAD -- som kommer att matas ut till terminalen 0 om det inte finns några ändringar i förhållande till den tidigare versionen av webbplatsen, och 1 det finns sådana förändringar. Sedan bearbetar vi resultatet av detta kommando. I informationen om körningen av skriptet kommer vi alltså att registrera användbar information om webbplatsens tillstånd i detta skede, istället för att automatiskt krascha och skicka oss en rapport om skriptkraschen.

Vi utför även dessa åtgärder i vår katalog med färdiga sidor.

   - 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

Resultat

Som ett resultat låter ett sådant skript dig inte tänka på att skapa statiska sidor. Genom att lägga till ändringar direkt i ett privat arkiv, antingen genom att arbeta med git från vilket system som helst eller genom att skapa en fil via GitHubs webbgränssnitt, kommer Actions att göra allt själva. Om skriptet kraschar oväntat kommer ett meddelande att skickas till din e-post.

Fullständig kod

Jag lämnar min fungerande version, där det sista steget lägger till att skicka ett meddelande om att en commit har skickats till huvudförvaret.

De ovan beskrivna hemligheterna används, där bot-token och användar-ID som meddelandet måste skickas till läggs till.

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

Skärmdumpar

GitHub-åtgärder som CI/CD för en webbplats på en statisk generator och GitHub-sidor
Resultatet av en av körningarna som visas på fliken Åtgärder i källförvaret

GitHub-åtgärder som CI/CD för en webbplats på en statisk generator och GitHub-sidor
Meddelande från boten om slutförandet av skriptet

Användbara länkar

Förstå åtgärder
Syntax för åtgärder
Lista över triggers
Alternativ för virtuella miljöer
Github -sidor
Statisk generator lista

Källa: will.com

Lägg en kommentar