Как работать с GitHub Actions
Рассказываем, как GitHub Actions упрощает процессы разработки при взаимодействии с репозиторием. Рассматриваем ключевые аспекты: автоматизацию проверки кода и деплой на сервер.
Представьте ситуацию: вы загрузили код на GitHub и все нужно проверять заново. На это уходит много времени и сил. Но мы же все любим автоматизировать — тем более, для этого есть все инструменты.
Доставку специально осуществим немного разными способами, чтобы захватить как можно больше контекста. Приятного чтения!
GitHub Actions — платформа, которая позволяет автоматизировать рабочие процессы прямо в репозитории. Можно создавать, настраивать, запускать действия, объединять и обмениваться ими для выполнения любой работы, включая CI/CD. Таким образом, с помощью инструмента можно упростить и кастомизировать разработку ПО.
Ключевые термины в GitHub Actions — это рабочий процесс (workflow), задача (job) и действие (action). Рабочий процесс — набор действий, выполняемых в ответ на события, такие как коммиты или запросы на объединение веток. Каждая задача в рабочем процессе выполняется на виртуальной машине и может включать в себя несколько шагов. Действия — это настраиваемые шаги, которые могут быть использованы повторно в различных рабочих процессах, что упрощает создание и поддержку автоматизируемых задач.
Подготовка сервера
Прежде всего подготовим облачный сервер, на котором будет размещаться наш демонстрационный проект. Для этого проделаем следующие шаги.
В панели управления создадим аккаунт или авторизуемся, если уже есть учетная запись. Внутри выбираем Облачная платформа → Серверы и нажимаем Создать сервер.
В настройках указываем произвольное имя и устанавливаем минимальную конфигурацию. Для работы приложения много мощностей не нужно.
Выбираем все необходимые параметры и нажимаем Создать сервер.
Возвращаемся в панель управления и переходим в консоль созданного сервера. Для входа нужен логин (root) и пароль. Нажимаем ЛКМ по иконке Горячие клавиши и добавляем сгенерированный пароль.
На этом пока с настройкой сервера все. Вернемся к ней, когда будем автоматизировать деплой фронтенда и бэкенда.
1. Автоматизация проверки кода (eslint / tests)
Начнем с настройки GitHub Actions для автоматического запуска eslint
и тестов при каждой команде push
или pull request
.
Настройка файловой структуры
Первый шаг, который нужно сделать, чтобы начать работу с действиями, — создать специальную директорию workflows
, где будем хранить файлы конфигурации для GitHub Actions.
Переходим в каталог проекта и подготавливаем нужные пути:
cd /path/to/your/project
mkdir -p .github/workflows
Элементарное действие
Теперь мы можем создать наш первый файл конфигурации. Сформируем простейшее действие. Так мы сначала познакомимся с возможностями GitHub Actions, а уже затем перейдем к написанию полноценной логики.
Начнем с файла TEST.yml
:
name: TEST
on: [push]
jobs:
our-first-job:
runs-on: ubuntu-latest
steps:
- name: Run console log
run: echo "Hello GitHub Actions!"
В первой строке с помощью ключа name
мы задаем название для действия. Далее в значении ключа on
описываем события, при наступлении которых оно должно происходить. Запись on: [push]
говорит, что реакция будет на все push‑команды в репозитории — вне зависимости от ветви, в которую пришли изменения. Мы еще обсудим, как сделать настройку более точной.
Ключевое слово jobs
описывает «задачи», которые GitHub должен выполнить: одну или несколько. В нашем примере our-first-job
— произвольное название.
И вот мы подошли к самой инструкции. Здесь описываем шаги, из которых состоит выполнение задачи, и операционную систему, необходимую для их осуществления.
Полноценное действие
Перейдем к созданию действия, где опишем проверки, которые должны производиться перед объединением кода с какой-либо веткой. Назовем файл CI.yml
:
name: CI
on: [pull_request]
jobs:
check-lint:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '20.12.2'
- name: Install dependencies
run: npm ci
- name: Run linter
run: npm run lint
check-tests:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '20.12.2'
- name: Install dependencies
run: npm ci
- name: Run tests
run: npm test
Конфигурационный файл выше будет запускать линтер и тесты при каждом открытом pull request
.
Здесь инструкции уже посложнее, потому что используются плагины:
actions/checkout@v4
— помогает получить доступ к коду из репозитория в контексте нашей задачи;
actions/setup-node@v4
— отвечает за установку ноды нужной версии.
Если перевести инструкции на понятный язык, то мы прописали буквально следующие шаги.
- Запусти последнюю Ubuntu
- Сделай
git clone
из нашего репозитория. - Установи ноду.
- Установи зависимости проекта.
- Запусти команду.
Гибкая настройка событий
Мы можем настроить наш action и более гибко, например, чтобы он срабатывал только для определенных веток:
on:
push:
branches: [main, dev]
pull_request:
branches: [main]
Фрагмент выше говорит, что действие будет происходить при push
в ветви main
и dev
, а также при создании pull request
в main
.
2. Автоматический деплой фронтенда
Теперь рассмотрим, как настроить автоматическую доставку фронтенд-приложения на сервер при помощи GitHub Actions. Воспользуемся не самым обычным методом — напишем Bash‑скрипт и разместим его на сервере, чтобы подключаться удаленно и запускать скрипт по необходимости через «действия».
Подготовка сервера
Прежде всего нужно подготовить наш сервер. Для этого загрузим необходимое ПО (Nginx, NVM, Git) и настроим SSH‑ключи для безопасного подключения.
Установить сервер nginx
просто — достаточно ввести команду:
sudo apt install nginx
Чтобы получить NVM (Node Version Manager), нужно скачать и запустить установочный скрипт:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
Далее определяемся с расположением каталога настроек:
export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
Устанавливаем Git:
sudo apt install git
Создадим SSH-ключи, чтобы работать с git clone
. Потребуется ввести название файла и пароль.
ssh-keygen -t ed25519 -C "Ваш любой комментарий"
Опция -t
задает алгоритм шифрования. Подробно на его выборе останавливаться не будем, интересующиеся могут заглянуть в дискуссию на StackExchange, где сравниваются особенности различных шифров, в том числе широко используемого RSA.
Комментарий не обязателен, но оказывается полезен, когда сгенерированных пар становится много.
Должно появится два ключа: приватный и публичный. Чтобы удостовериться в этом, перейдем в каталог, где хранятся SSH-ключи:
cd /root/.ssh/
В этом же каталоге создадим или дополним файл config
, чтобы уточнить, какой именно ключ используется для подключения к GitHub. Воспользуемся простейшим редактором nano
:
nano config
Добавляем запись, которая увязывает хост и используемые ключи. Поле <your-private-key> заменяем названием файла, содержащего приватный ключ для соединения с GitHub:
Host github.com
HostName github.com
User git
IdentityFile ~/.ssh/<your-private-key>
StrictHostKeyChecking no
Маленькое отступление про SSH‑ключи
Настало время прояснить один запутанный момент. Наша инструкция взаимодействует сразу с двумя парами SSH‑ключей:
- созданной локально на компьютере для подключения к VPS;
- расположенной на VPS для авторизации в репозитории.
Первая пара уже создана. Ее ключи используются при соединении с сервером и передаются в секреты GitHub Actions. Так появляется возможность выполнения команд через SSH.
Вторая пара нужна исключительно для работоспособности git clone
в нашем скрипте — скопировать репозиторий без ввода пароля можно только с помощью SSH-доступа. Ключ из второй пары мы добавим в настройки GitHub позже.
Это достаточно запутанный момент, но вы справитесь.
Скрипт для обновления приложения
С сервером разобрались. Теперь напишем Bash‑скрипт, который будет выполнять весь процесс обновления приложения. Назовем его deploy.sh:
#!/bin/bash
# Stop on error
set -e
# Load nvm
export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
# Move to folder with the apps from the github
cd /root
# Clone the repo
git clone <your-git-repo-link>
# Move to specific repo
cd /root/<name-of-repo>
# Install Node.js
nvm install
# Check node version
node -v
# Check npm version
npm -v
# Install dependencies
npm ci
# Build application
npm build
# Move build to the www folder
cp -rf /root/<your-project-name>/dist/* /var/www/default
# Remove repo
rm -rf /root/<your-project-name>
Скрипт подробно прокомментирован — несложно разобраться, что происходит.
Настройка GitHub Actions
Создадим новый файл .github/workflows/deploy-frontend.yml
:
name: Deploy
on:
push:
branches: [dev]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Set up SSH
uses: webfactory/ssh-agent@v0.9.0
with:
ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}
- name: Run bash script via ssh
run: |
ssh -o StrictHostKeyChecking=no ${{ secrets.SERVER_USER }}@${{ secrets.SERVER_IP }} "bash ${{ secrets.PATH_TO_SCRIPT }}"
env:
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
На первом шаге мы «объясняем» действию, как работать с SSH, а также передаем в виде параметра приватный ключ. На втором — соединяемся с сервером и запускаем написанный ранее скрипт deploy.sh
.
Но какой ключ добавлять? Из первой пары или второй? Все просто. Добавляем в secrets ключ из первой пары — приватный ключ на локальной машине. И не забываем открыть доступ и в настройках аккаунта GitHub — указываем публичный ключ из второй пары, созданной на сервере.
Чтобы добавить переменные в секреты GitHub Actions, необходимо перейти на страницу репозитория, а затем использовать меню: Settings → Secrets and variables → Actions → New repository secret.
3. Автоматический деплой бэкенда
Подготовка сервера
Воспользуемся PM2 — удобным менеджером процессов для Node.js
, который упрощает управление и мониторинг серверных приложений:
npm install -g pm2
Настройка GitHub Actions
Здесь пойдем немного другим путем (сделано это специально, чтобы показать разные возможные варианты). Создадим файл .github/workflows/deploy-backend.yml
:
name: Deploy Backend
on:
push:
branches: [dev]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Copy files to VPS
uses: appleboy/scp-action@v0.1.0
with:
host: ${{ secrets.VPS_HOST }}
username: ${{ secrets.VPS_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
source: './*'
target: '</path/to/your/app>'
- name: Restart PM2
uses: appleboy/ssh-action@v0.1.0
with:
host: ${{ secrets.VPS_HOST }}
username: ${{ secrets.VPS_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
cd </path/to/your/app>
nvm use
npm install
npm run build
pm2 start <your-app-name>
В этой инструкции мы говорим следующее.
- Получи доступ к нашему репозиторию.
- Скопируй все из репозитория на сервер.
- Выполни команды на сервере: перейди в папку с проектом, установи ноду и зависимости, запусти билд при помощи PM2.
Заключение
GitHub Actions — это полезный инструмент, который может значительно упростить и ускорить процессы разработки. Мы рассмотрели три ключевых сценария автоматизации: проверку кода, доставку фронтенда и бэкенда. Используя эти примеры, вы можете настроить скрипты для своих конкретных нужд. А облачные серверы линейки Shared Line позволяют снизить затраты на обслуживание проекта. Оплата производится только за потребленные мощности — по модели pay-as-you-go.
Не забывайте, что для работы с секретами (SERVER_IP
, SERVER_USER
, SERVER_SSH_KEY
) нужно выполнить соответствующие настройки в репозитории на GitHub. Такой подход обеспечит безопасность данных.