Continuous Delivery (CD), или непрерывное развертывание уже давно стало одним из золотых стандартном разработки и неотъемлемой частью схемы CI/CD. Принцип CI/CD означает, что вся работа над проектом ведется в системе контроля версий (git), код лежит в репозитории, а развертывание происходит автоматически по мере готовности. До недавнего времени эта последняя часть, а именно непосредственная отправка готового кода на сервер, требовала сложной настройки или использования платных сервисов, типа deployhq.com.
С появлением Github Actions, эта возможность доступна всем абсолютно бесплатно. По сути, GitHub Actions дает вам возможность быстро заливать все изменения из репозитория на живой сервер с помощью rsync.
Создание нового процесса в GitHub Actions
С помощью GitHub Actions можно создавать достаточно сложные процессы, которые будут запускаться любым событием на Гитхабе. Также, есть каталог готовых решений, которые можно использовать в своих проектах, собирая нужные вам процессы как конструктор.
Для начала, во вкладке Actions создадим новый процесс, кликнув на Set up a workflow yourself. Откроется редактор с базовым .yaml шаблоном, который будет сохранен в папке .github/workflows вашего репозитория.
У каждого процесса есть:
name— названиеon— условия, при которых процесс запускаетсяjobs— контейнер для скриптов, которые запускаются внутри процесса, параллельно или последовательно. Скрипты могут иметь различные стадии внутри самих себя.

Назначение события для запуска процесса развертывания
Самый простой процесс (которого я сам придерживаюсь), заключается в автоматическим деплое всего из ветки master. Прямые коммиты в master обычно запрещены, код заливается туда с помощью Pull Requests, которые проходят проверку перед слиянием. Предполагается, что ветка master полностью совпадает с кодовой базой на боевом сервере, поэтому все, что в нее попадает, должно автоматически быть отправлено на сервер.
А вот так это настраивается в шаблоне процесса:
name: Deploy to Live
on:
push:
branches: [ master ]
Настройка доступов к серверу
GitHub будет самостоятельно отправлять файлы на ваш сервер, для этого ему потребуются доступы. В отличие от большинства сервисов развертывания, где требуется только ваш публичный ключ, здесь настройка несколько сложнее. Вот как это делается:
- Создаем новую пару SSH ключей с помощью команды
ssh-keygen(без пароля!). - Добавляем публичный ключ к боевому серверу в папку
~/.ssh/authorized_keys(или в интерфейсе настройки, если есть) - Добавляем приватный (!) ключ как секрет к вашему репозиторию (вкладка Settings -> Secrets). Назовем его
DEPLOY_KEY, это имя потом понадобится.

Настройка отправки файлов на сервер
На CSS-tricks есть похожая статья по настройке Github Actions для деплоя, где автор советует не использовать решения из каталога действий, а написать все с нуля. Мне такой подход не очень нравится, хотя бы потому что кода получается больше, а преимущества не очевидны.
Поэтому недолго думая, взял за основу решение вот этих ребят, которое представляет из себя простую и удобную обертку к rsync. Вот как это выглядит:
- name: Deploy files
id: deploy
uses: Pendect/action-rsyncer@v1.1.0
env:
DEPLOY_KEY: ${{secrets.DEPLOY_K}}
with:
flags: '-avzr --delete'
options: '--exclude="wp-content/uploads/*" --exclude="wp-content/cache/*"'
ssh_options: '-p 99999'
src: 'www/'
dest: 'user@yourserver.com:/www/site/public'
По-умолчанию скрипт полностью синхронизирует указанные папки в репозитории и на сервере, удаляя с сервера файлы, которых нет в GitHub. Картинки в репозитории обычно не хранятся, поэтому очень важно добавить эту папку в исключения: --exclude="wp-content/uploads/*". Таким же образом можно добавлять и другие папки.
Я использую Vagrant для локальной разработки, который также находится в репозитории. Чтобы не заливать его на сервер при деплое, в конфиге указываю локальный путь к папке с сайтом: src: 'www/'.
Параметр ssh_options позволяет добавлять дополнительные параметры для SSH соединения, например, порт.
Последний параметр dest (сокращение от destination), нужен для ввода логина, адреса сервера и абсолютного пути к папке с сайтом. Само собой, юзер должен обладать правами на запись в эту папку.
Финальный конфиг
name: Deploy to Live
on:
push:
branches: [ master ]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Deploy files
id: deploy
uses: Pendect/action-rsyncer@v1.1.0
env:
DEPLOY_KEY: ${{secrets.DEPLOY_KEY}}
with:
flags: '-avzr --delete'
options: '--exclude="wp-content/uploads/*" --exclude="wp-content/cache/*"'
ssh_options: '-p 99999'
src: 'www/'
dest: 'user@yourserver.com:/www/site/public'
- name: Display status from deploy
run: echo "${{ steps.deploy.outputs.status }}"v
Не забудьте поменять SSH порт и параметры доступа в строке dest:. После этого достаточно сохранить файл с конфигурацией (сделать коммит) и запушить что-нибудь в ветку master.
Можно следить за ходом выполнения процесса на вкладке Actions в вашем репозитории. История всех запусков с подробными логами на каждом этапе хранится там, очень удобно.

Напоследок стоит отметить, что развертывание с помощью Github Actions происходит очень быстро. Какое-то время я пользовался deployhq для этих целей, и первичный деплой проекта нередко занимал 10-20 минут. С помощью Github Actions аналогичный процесс занял 30 секунд.