- PVSM.RU - https://www.pvsm.ru -
Немного прошерстив Habr удивился тому, что очень мало опубликовано статей на тему (beta-)фичи GitHub'а — Actions.
Казалось бы, можно объяснить такую недосказанность тем, что функционал еще в тестировании, пусть и "beta". Но именно полезная особенность беты позволяет использовать этот инструмент в приватных репозиториях. Именно про работу с данной технологией я расскажу в этой статье.
Если начинать по порядку, то стоит, наверное, упомянуть тот момент, что в процессе поиска быстрого, удобного, легкого и бесплатного варианта хранения персонального сайта "Обо мне" пришлось потратить несколько ночей и прошерстить множество статей.
Кто-то на выбирает
Конечно, это личный выбор каждого.
Мой окончательный выбор был в пользу GitHub Pages.
Кто не в курсе, gh-pages
— это такой вариант хранения документации в виде сайта и предоставляется он бесплатно, а кроме документации предлагается хранить также персональные сайты. Этот функционал предоставляется GitHub’ом всем пользователям и доступен в настройках репозитория.
Для репозитория проекта используется ветка gh-pages
, для пользовательского сайта — отдельный репозиторий с названием username.github.io
с исходниками сайта в master
ветке.
Подробнее можно посмотреть в документации [2], но отмечу лишь то, что GitHub с удивительной щедростью разрешает каждому привязать собственный домен к такому сайту просто добавив файл CNAME
c названием домена и настроив DNS своего домен-провайдера на сервера GitHub.
Уверен, что статей о том как развернуть такой сайт здесь найдется множество, поэтому дальше не об этом.
Проблема состояла в том, что при использовании статического генератора есть необходимость сочинять дополнительные костыли скрипты и использовать библиотеки для упрощения процесса генерации страниц и их загрузки в репозиторий. Попросту если хранить исходники в отдельном приватном репозитории, то каждый раз при любом изменении на сайте было необходимо разворачивать локальное окружение для последующей генерации статических страниц и публикации в основном репозитории сайта.
Существует обилие статических генератораторов [3] и все они имеют такую же проблему. Эти действия занимают слишком много времени и сил, а по итогу стопорят работу над сайтом, особенно после нескольких миграций с ОС на ОС или инцидентов с потерей данных на жестких дисках (так было в моем случае).
Буквально недавно, то ли в всплывающем уведомлении на сайте, то ли в рассылке от GitHub мною было замечено нововстроенный CI/CD, который позволил проводить эти действия с минимальными усилиями.
Не буду заострять на этом подпункте особое внимание, но поделюсь парой тезисов к которым пришел за время выбора и использования таких:
1) выбирать генератор стоит под свой язык программирования, или такой который был максимально понятен. К этой идее я пришел в тот момент, когда самому пришлось дописывать некоторый функционал для работы сайта, проставлять костыли для его большей устойчивости и автоматизации. Кроме того, это хороший повод самому написать дополнительный функционал в виде плагинов;
2) на каком именно генераторе останавливаться это личный выбор, но стоит учитывать, что для начального погружения в работу функционала GitHub Pages необходимо сначала поставить себе Jekyll [4]. Благо, он позволяет генерировать сайт из исходников прямо в репозитории (это я и повторю со своим выбором).
Мой выбор генератора основывается на первом пункте. Pelican [5] который написан на Python с легкостью заменил чужой для меня Jekyll (пользовался почти год). В итоге даже создание и редактирование статей, робота над сайтом дает дополнительный опыт в интересном для меня языке.
__
Главная задача будет — написать такой скрипт (на самом деле файл конфигурации) который позволил бы автоматически генерировать статические страницы из приватного репозитория. В решении будет задействован функционал виртуального окружения. Скрипт сам будет добавлять готовые страницы в публичный репозиторий.
Инструменты которые будем использовать для решение задачи:
Итого, познакомившись немного с документацией и разобравшись как пишутся скрипты для Actions стало понятно что этот механизм полностью решит возникшую проблему. На момент написания статьи для использования данного функционала необходимо подписаться на бета-тестирование [6]!
Описание нового функционала самим Github
Начинается написание Actions-скрипта с создания именованного файла в папке .github
и ее подпапке workflows
. Сделать это можно как вручную, так и из редактора во вкладке Actions на странице репозитория.
Пример пустого бланка скрипта
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.
Напишем свой на основе шаблона:
0) Имя можно оставить и “CI”. Тут дело вкусовщины.
1) Далее необходимо выбрать то действие/триггер, которое приведет к запуску скрипта, в нашем случае это обычный пуш нового коммита в репозиторий.
on:
push
2) Образ на основе которого будет запускаться скрипт также оставим с примера, так как Ubuntu вполне устраивает по необходимому функционалу. Глядя на доступные инструменты [7] становится понятно, что это может быть любой необходимый или просто удобный образ (или докер контейнер на его основе).
build:
runs-on: ubuntu-latest
3) В шагах сначала настроим среду для подготовки к основной работе.
3.1) переходим в необходимую нам ветку (стандартный шаг checkout
):
- uses: actions/checkout@v1
3.2) устанавливаем Python:
- name: Set up Python
uses: actions/setup-python@v1
with:
python-version: 3.7
3.3) устанавливаем зависимости нашего генератора:
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
3.4) создаем директорию в которую будут генерироваться страницы сайта:
- name: Make output folder
run: mkdir output
4) Для того, чтобы работа над сайтом была последовательна, а именно не удаляла предыдущие изменения и можно было без конфликтов добавлять изменения в репозиторий сайта, следующим шагом будем каждый раз клонировать репозиторий сайта:
- 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
Этот шаг вызывает системные переменные:
GITHUB_ACTOR
GitHub устанавливает сам, и это имя пользователя, по вине которого запустился данный скрипт;secrets.ACCESS_TOKEN
это сгенерированный токен для управления Github’ом [8], его в виде переменной окружения мы можем передать установив во вкладке Secrets
настроек нашего репозитория. Прошу заметить, при генерации токен предоставится нам единожды, больше доступа к нему не будет. Также как и значения пунктов Secrets.5) Переходим к генерации наших страниц:
- name: Generate static pages
run: pelican content -o output -s publishconf.py
Параметры переданные генератору отвечают за директорию куда будет отправлены сгенерированные файлы (-o output
) и конфигурационный файл, который используем для генерации (-s publishconf.py
; об подходе к разделению локального конфига и конфига для публикации можно почитать в документации Pelican).
Напомню, что у нас в папку output
уже склонирован репозиторий сайта.
6) Настроим git и проиндексируем наши измененные файлы:
- 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
В этом пункте используется уже известная переменная, и указывается рабочая директория в которой будет происходить запуск команд из этого шага. Команда перехода в рабочую директорию иначе выглядела бы как — cd output
.
7) Сгенерируем сообщение коммита, закоммитим изменения и запушим их в репозиторий. Чтобы коммит не был впустую, и соответственно не выдал ошибку в bash (результат на выходе не 0
) — сначала проверим необходимо ли вообще что-то коммитить и пушить. Для этого используем команду git diff-index --quiet --cached HEAD --
которая на выходе в терминал выдаст 0
если нет изменений относительно предыдущей версии сайта, и 1
такие изменения есть. После чего обрабатываем результат этой команды. Таким образом мы в информации о выполнении скрипта запишем полезную информацию о состоянии сайта на этом этапе, вместо автоматического падения и отправки нам отчета о падении скрипта.
Эти действия также проводим в нашей директории с готовыми страницами.
- 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
В итоге такой скрипт позволяет не думать о создании статических страниц. Добавляя изменения напрямую в приватный репозиторий, будь то работой с git из под любой системы или созданием файла через web-интерфейс GitHub’а, Actions сделают все сами. В случае неожиданного падения скрипта на почту придет уведомление.
Оставлю свой рабочий вариант, в нем в последний шаг добавлена отправка уведомления о том, что коммит был запушен в основной репозиторий.
Используются вышеописанные Secrets куда добавлен токен бота и идентификатор пользователя которому нужно отправить сообщение.
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
Результат одного из запусков отображенный во вкладке Actions репозитория с исходниками
Сообщение от бота о завершении работы скрипта
Общие сведения об Actions [6]
Синтаксис Actions [9]
Список триггеров [10]
Варианты виртуальных окружений [11]
Github Pages [2]
Static Generator list [3]
Автор: Dmytro Hoi
Источник [12]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/python/335646
Ссылки в тексте:
[1] хостинг: https://www.reg.ru/?rlink=reflink-717
[2] в документации: https://help.github.com/en/github/working-with-github-pages/about-github-pages
[3] статических генератораторов: https://www.staticgen.com/
[4] Jekyll: https://jekyllrb.com/
[5] Pelican: https://blog.getpelican.com/
[6] на бета-тестирование: https://github.com/features/actions
[7] доступные инструменты: https://help.github.com/en/github/automating-your-workflow-with-github-actions/software-in-virtual-environments-for-github-actions
[8] токен для управления Github’ом: https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line
[9] Синтаксис Actions: https://help.github.com/en/github/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions
[10] Список триггеров: https://help.github.com/en/github/automating-your-workflow-with-github-actions/events-that-trigger-workflows
[11] Варианты виртуальных окружений: https://help.github.com/en/github/automating-your-workflow-with-github-actions/virtual-environments-for-github-actions
[12] Источник: https://habr.com/ru/post/474668/?utm_source=habrahabr&utm_medium=rss&utm_campaign=474668
Нажмите здесь для печати.