Представьте ситуацию: вы загрузили код на GitHub и все нужно проверять заново. На это уходит много времени и сил. Но мы же все любим автоматизировать — тем более, для этого есть все инструменты.

Привет, Хабр! На связи Виктор Рябков. Я — разработчик и создатель одноименного YouTube-канала. Сегодня погрузимся в мир GitHub Actions и узнаем, как эта система упрощает процессы разработки при взаимодействии с репозиторием. Рассмотрим ключевые аспекты: автоматизацию проверки кода и деплой на сервер.

Доставку специально осуществим немного разными способами, чтобы захватить как можно больше контекста. Приятного чтения!

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 — отвечает за установку ноды нужной версии.

Если перевести инструкции на понятный язык, то мы прописали буквально следующие шаги.
  1. Запусти последнюю Ubuntu
  2. Сделай git clone из нашего репозитория.
  3. Установи ноду.
  4. Установи зависимости проекта.
  5. Запусти команду.

Гибкая настройка событий


Мы можем настроить наш 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, необходимо перейти на страницу репозитория, а затем использовать меню: SettingsSecrets and variablesActionsNew 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>

В этой инструкции мы говорим следующее.

  1. Получи доступ к нашему репозиторию.
  2. Скопируй все из репозитория на сервер.
  3. Выполни команды на сервере: перейди в папку с проектом, установи ноду и зависимости, запусти билд при помощи PM2.

Заключение


GitHub Actions — это полезный инструмент, который может значительно упростить и ускорить процессы разработки. Мы рассмотрели три ключевых сценария автоматизации: проверку кода, доставку фронтенда и бэкенда. Используя эти примеры, вы можете настроить скрипты для своих конкретных нужд. А облачные серверы линейки Shared Line позволяют снизить затраты на обслуживание проекта. Оплата производится только за потребленные мощности — по модели pay-as-you-go.

Не забывайте, что для работы с секретами (SERVER_IP, SERVER_USER, SERVER_SSH_KEY) нужно выполнить соответствующие настройки в репозитории на GitHub. Такой подход обеспечит безопасность данных.

Надеемся, статья была полезной для вас. Если не хватило наглядности, смотрите видео на YouTube. А если остались вопросы — не стесняйтесь задавать их в комментариях или Telegram‑канале. Удачи в ваших проектах!

Комментарии (0)