Akcje GitHub jako CI/CD dla witryny w generatorze statycznym i na stronach GitHub

Akcje GitHub jako CI/CD dla witryny w generatorze statycznym i na stronach GitHub

Po krótkim przejrzeniu Habra byłem zaskoczony, że opublikowano bardzo niewiele artykułów na temat funkcji GitHub (beta) – Akcje.

Wydawałoby się, że takie niedopowiedzenie można wytłumaczyć faktem, że funkcjonalność jest wciąż w fazie testów, choć „beta”. Ale jest to przydatna funkcja wersji beta, która pozwala na użycie tego narzędzia w prywatnych repozytoriach. O pracy z tą technologią będę mówił w tym artykule.

Prehistoria

Jeśli zaczniemy po kolei, to chyba warto wspomnieć, że szukając szybkiej, wygodnej, łatwej i bezpłatnej opcji przechowywania osobistej witryny „O mnie” musiałem spędzić kilka nocy i przeczesać wiele artykułów.

Niektórzy wybierają hosting, inni serwer w chmurze, a ci, którzy nie chcą rozumieć pracy, interakcji i płatności za to wszystko, jak przesyłanie statycznych stron do repozytorium, ponieważ teraz można to zrobić zarówno na GitHubie, jak i GitLabie.

Oczywiście jest to osobisty wybór każdego.

Moim ostatecznym wyborem były strony GitHub.

O stronach

Kto nie jest świadomy gh-pages - jest to opcja przechowywania dokumentacji w formie strony internetowej i jest ona świadczona bezpłatnie, przy czym oprócz dokumentacji proponuje się także przechowywanie osobistych stron internetowych. Funkcjonalność ta udostępniana jest przez GitHub wszystkim użytkownikom i dostępna jest w ustawieniach repozytorium.

Repozytorium projektu korzysta z gałęzi gh-pages, dla witryny użytkownika - osobne repozytorium z nazwą username.github.io ze źródłami witryny w master oddział.

Możesz zobaczyć więcej w dokumentacji, ale zauważę tylko, że GitHub jest zaskakująco hojny, umożliwiając każdemu połączenie własnej domeny z taką witryną poprzez proste dodanie pliku CNAME z nazwą domeny i konfiguracją DNS Twojego dostawcy domeny na serwerach GitHub.

Jestem pewien, że jest tu wiele artykułów na temat tego, jak stworzyć taką witrynę, więc nie o tym będę dalej mówił.

Wystąpienie problemu

Problem polegał na tym, że w przypadku korzystania z generatora statycznego istniała konieczność napisania dodatkowych skryptów i wykorzystania bibliotek, aby uprościć proces generowania stron i ładowania ich do repozytorium. Po prostu, jeśli przechowujesz źródła w osobnym prywatnym repozytorium, to za każdym razem, gdy w serwisie następuje jakakolwiek zmiana, konieczne jest wdrożenie lokalnego środowiska w celu późniejszej generacji stron statycznych i publikacji w głównym repozytorium serwisu.

Jest obfitość generatory statyczne i wszyscy mają ten sam problem. Działania te zajmują zbyt dużo czasu i wysiłku, a ostatecznie spowalniają pracę na stronie, szczególnie po kilku migracjach z OS na OS lub incydentach z utratą danych na dyskach twardych (tak było w moim przypadku).

Całkiem niedawno, czy to w wyskakującym powiadomieniu na stronie, czy w newsletterze z GitHuba, zauważono nowo zbudowany CI/CD, który pozwalał na wykonanie tych działań przy minimalnym wysiłku.

Informacje o generatorach stron statycznych

Nie będę skupiał szczególnej uwagi na tym podpunkcie, ale podzielę się kilkoma tezami, do których doszedłem podczas wyboru i stosowania:

1) wybierz generator pasujący do Twojego języka programowania lub taki, który jest możliwie najbardziej przejrzysty. Wpadłem na ten pomysł w momencie, gdy sam musiałem dodać trochę funkcjonalności, aby strona działała, dodać kule dla jej większej stabilności i automatyzacji. Ponadto jest to dobry powód, aby samodzielnie napisać dodatkową funkcjonalność w postaci wtyczek;

2) który generator wybrać, jest wyborem osobistym, warto jednak wziąć pod uwagę, że aby po raz pierwszy zanurzyć się w pracy funkcjonalności GitHub Pages, należy najpierw zainstalować Jekyll. Na szczęście pozwala wygenerować stronę internetową ze źródeł bezpośrednio w repozytorium (Powtarzam to z moim wyborem).

Mój wybór generatora opiera się na pierwszym punkcie. Pelikan który jest napisany w Pythonie, z łatwością zastępuje Jekylla, który jest mi obcy (używałem go prawie rok). W rezultacie nawet tworzenie i redagowanie artykułów oraz praca na stronie internetowej daje dodatkowe doświadczenie w interesującym mnie języku.

__

Stwierdzenie problemu

Głównym zadaniem będzie napisanie skryptu (właściwie pliku konfiguracyjnego), który automatycznie generowałby strony statyczne z prywatnego repozytorium. Rozwiązanie będzie uwzględniało funkcjonalność środowiska wirtualnego. Sam skrypt doda gotowe strony do publicznego repozytorium.

Narzędzia do rozwiązania

Narzędzia, których użyjemy do rozwiązania problemu:

  • Akcje GitHuba;
  • Pythona 3.7;
  • Pelikan;
  • Gita;
  • Strony GitHuba.

Roztwór

Tak więc, po krótkim zapoznaniu się z dokumentacją i zrozumieniu, w jaki sposób pisane są skrypty dla Akcji, stało się jasne, że ten mechanizm całkowicie rozwiąże powstały problem. Aby móc korzystać z tej funkcji, w momencie pisania tego tekstu musisz wykupić subskrypcję. do testów beta!

Akcje GitHub jako CI/CD dla witryny w generatorze statycznym i na stronach GitHub
Opis nowej funkcjonalności autorstwa samego Githuba

Pisanie skryptu Actions rozpoczyna się od utworzenia nazwanego pliku w folderze .github i jego podfolder workflows. Można to zrobić ręcznie lub z poziomu edytora w zakładce Akcje na stronie repozytorium.

Akcje GitHub jako CI/CD dla witryny w generatorze statycznym i na stronach GitHub
Przykład pustego formularza skryptu

Krótko skomentuję formę

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.

Napiszmy własne na podstawie szablonu:

0) Możesz także pozostawić nazwę „CI”. To kwestia gustu.

1) Następnie musisz wybrać akcję/wyzwalacz, który uruchomi skrypt, w naszym przypadku jest to zwykłe wypchnięcie nowego zatwierdzenia do repozytorium.

on:
  push

2) Jako przykład pozostawimy również obraz, na podstawie którego zostanie uruchomiony skrypt, ponieważ Ubuntu jest całkiem zadowolony z niezbędnej funkcjonalności. Patrzeć na instrukcje obsługi staje się jasne, że może to być dowolny niezbędny lub po prostu wygodny obraz (lub oparty na nim kontener Docker).

  build:
    runs-on: ubuntu-latest

3) W kolejnych krokach najpierw skonfigurujemy środowisko, aby przygotować się do głównej pracy.

3.1) przejdź do potrzebnej nam gałęzi (krok standardowy checkout):

- uses: actions/checkout@v1

3.2) zainstaluj Pythona:

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

3.3) zainstaluj zależności naszego generatora:

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

3.4) utwórz katalog, w którym będą generowane strony serwisu:

   - name: Make output folder
      run: mkdir output

4) Aby praca nad stroną była spójna, czyli nie usuwała poprzednich zmian i aby móc bez konfliktów dodawać zmiany do repozytorium serwisu kolejnym krokiem będzie każdorazowe klonowanie repozytorium serwisu:

   - 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

Ten krok wywołuje zmienne systemowe:

  • zmienny GITHUB_ACTOR GitHub instaluje się sam i jest to nazwa użytkownika, z powodu którego uruchomiono ten skrypt;
  • zmienna secrets.ACCESS_TOKEN to jest generowane token do zarządzania Githubem, możemy przekazać ją jako zmienną środowiskową, ustawiając ją w zakładce Secrets ustawienia naszego repozytorium. Należy pamiętać, że w trakcie generowania token zostanie nam przekazany jednorazowo, nie będzie już do niego dostępu. Jak również wartości przedmiotów Sekretów.

5) Przejdźmy do generowania naszych stron:

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

Parametry przekazywane do generatora odpowiadają za katalog, do którego zostaną przesłane wygenerowane pliki (-o output) i plik konfiguracyjny, którego używamy do generowania (-s publishconf.py; O podejściu do oddzielania konfiguracji lokalnej od konfiguracji do publikacji możesz przeczytać w dokumentacji Pelican).

Przypomnę, co jest w naszym folderze output Repozytorium witryny zostało już sklonowane.

6) Skonfigurujmy gita i zindeksujmy zmienione pliki:

    - 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

W tym momencie wykorzystywana jest znana już zmienna i wskazywany jest katalog roboczy, w którym zostaną uruchomione polecenia z tego kroku. W przeciwnym razie polecenie przejścia do katalogu roboczego wyglądałoby tak: cd output.

7) Wygenerujmy komunikat zatwierdzenia, zatwierdź zmiany i wypchnijmy je do repozytorium. Aby zatwierdzenie nie poszło na marne i dlatego nie spowodowało błędu w bashu (wynik wyjściowy nie jest 0) — najpierw sprawdźmy, czy w ogóle trzeba coś zatwierdzać i wciskać. W tym celu używamy polecenia git diff-index --quiet --cached HEAD -- który wyśle ​​do terminala 0 jeśli nie ma żadnych zmian w stosunku do poprzedniej wersji witryny, oraz 1 są takie zmiany. Następnie przetwarzamy wynik tego polecenia. Dzięki temu w informacji o wykonaniu skryptu zapiszemy przydatne informacje o stanie strony na tym etapie, zamiast automatycznie zawieszać się i przesyłać nam raport o awarii skryptu.

Czynności te wykonujemy również w naszym katalogu z gotowymi stronami.

   - 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

Doświadcz mocnych i skutecznych rezultatów

Dzięki temu taki skrypt pozwala nie myśleć o tworzeniu stron statycznych. Dodając zmiany bezpośrednio do prywatnego repozytorium, czy to pracując z git z poziomu dowolnego systemu, czy tworząc plik poprzez interfejs sieciowy GitHub, Actions zrobi wszystko samodzielnie. Jeśli skrypt nieoczekiwanie ulegnie awarii, na Twój adres e-mail zostanie wysłane powiadomienie.

Pełny kod

Pozostawię moją wersję roboczą, w której ostatnim krokiem jest wysłanie powiadomienia o wypchnięciu zatwierdzenia do głównego repozytorium.

Stosowane są opisane powyżej Sekrety, gdzie dodawany jest token bota oraz identyfikator użytkownika, do którego ma zostać wysłana wiadomość.

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

Zrzuty ekranu

Akcje GitHub jako CI/CD dla witryny w generatorze statycznym i na stronach GitHub
Wynik jednego z przebiegów wyświetlony na karcie Akcje repozytorium źródłowego

Akcje GitHub jako CI/CD dla witryny w generatorze statycznym i na stronach GitHub
Wiadomość od bota o ukończeniu skryptu

Przydatne linki

Zrozumienie działań
Składnia akcji
Lista wyzwalaczy
Opcje dla środowisk wirtualnych
Strony Githuba
Lista generatorów statycznych

Źródło: www.habr.com

Dodaj komentarz