CI/CD: выкладка по коммиту
Зачем:Залить сайт по FTP руками значит надеяться, что ничего не забыто. После урока вы понимаете, что такое непрерывная интеграция и доставка, читаете и пишете файл конвейера для GitHub Actions, который проверяет, собирает и выкладывает ваш сайт, прячете секреты в настройках и знаете, как откатить плохую версию.
25 минут
Озвучено синтезом речи (Qwen3-TTS), голос не принадлежит человеку.
CI/CD — конвейер, который на каждый коммит сам проверяет, собирает и выкладывает сайт, причём выкладка идёт, только когда все проверки прошли.
Пятница, вечер, FTP
Вспомните, как выкладывали сайт в 2010 году: открыть программу, подключиться к серверу, перетащить файлы из одной папки в другую. Что здесь может пойти не так? Всё. Забыли один файл. Залили не ту версию. Не заметили битую ссылку. Правка уехала на живой сайт без проверки, а прежней версии нигде нет. И знает всё это один человек, который «умеет заливать».
Современный ответ называется CI/CD, и за двумя буквами скрыта простая идея: пусть выкладкой занимается машина, по записанным правилам, каждый раз одинаково.
- CI (continuous integration, непрерывная интеграция): каждое изменение сразу автоматически собирается и проверяется. Небольшие правки, частые проверки, и ошибка находится, пока свежа.
- CD (continuous delivery или deployment): проверенная версия автоматически доходит до людей. При доставке (delivery) версия всегда готова, а последнее нажатие «выкатить» делает человек. При развёртывании (deployment) после зелёных проверок сайт обновляется сам. Для небольшого сайта обычно выбирают второе.
Для вас это значит, что правка сайта превращается из ритуала в коммит: сохранили изменение в репозитории (вы знаете Git как способ хранить версии), отправили в основную ветку, и дальше всё идёт само.
Станции конвейера
Конвейер это цепочка станций, и каждая что-то проверяет или делает. Если станция «заклинила» (красная), дальше ничего не идёт.
- Запуск: событие, например коммит в ветку
mainили открытый запрос на изменение. - Проверки: битые ссылки, ошибки разметки, тесты, доступность, наличие нужных страниц.
- Сборка: превращает исходники в готовый сайт (о сборке вы читали в части про JavaScript).
- Предпросмотр: черновик по временному адресу, чтобы посмотреть глазами. Многие платформы делают его на каждый запрос на изменение.
- Выкладка: замена живого сайта, но только когда всё предыдущее зелёное.
- Уведомление: сообщение в чат или на почту: «вышло» или «упало на проверке ссылок».
Запустите изменение на схеме. Потом заклините разные станции и сравните с выкладкой вручную: там никто не останавливает плохую правку. Включите «ошибку, которую проверки не видят» и нажмите «Откатить».
Нажмите на станцию, чтобы «заклинить» её, потом запустите.
-
Вы сохранили правку и отправили её в основную ветку (push).
-
Ссылки, разметка, страница согласия на обработку данных.
-
Собирает страницы: Главная, Услуги, Контакты.
-
Выкладывает черновик по временному адресу, чтобы посмотреть глазами.
-
Заменяет живой сайт новой версией, когда всё выше прошло.
-
Пишет в чат или на почту: что выложено или что упало.
Результат появится после запуска.
Проверьте себя: почему выкладка стоит после проверок, а не рядом с ними?
Чтобы плохая версия не попала на живой сайт: если любая проверка красная, до выкладки дело не доходит, и сайт остаётся прежним.
Как это выглядит: GitHub Actions
Конвейер записывают в файле. В GitHub Actions это текстовый YAML в папке .github/workflows/. Вот файл для сайта на GitHub Pages (урок про публикацию покажет его в деле):
name: Проверка и выкладка сайта
on:
push:
branches: [main]
permissions:
contents: read
pages: write
id-token: write
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- name: Ссылки и разметка
run: npm run check:links && npm run check:html
- name: Сборка страниц
run: npm run build
- name: Страница политики и согласия на месте
run: test -f dist/politika/index.html
- uses: actions/upload-pages-artifact@v5
with:
path: dist
deploy:
needs: check
runs-on: ubuntu-latest
environment: github-pages
steps:
- uses: actions/deploy-pages@v5 Прочтите как инструкцию. on: push: branches: [main]: запускать при каждом коммите в main. Два задания: check (проверить и собрать) и deploy. Строка needs: check говорит, что выкладка ждёт успеха проверок, а если проверки красные, она не запустится. Каждый шаг это либо готовое действие (uses:, например получение кода), либо команда (run:). Номера версий действий (@v7, @v5) меняются: актуальные смотрите в документации (она в источниках).
Строки с npm run check:links и подобные это ваши команды: они определены в проекте. Что делает каждая, зависит от выбранных вами инструментов: проверяльщика ссылок, проверяльщика разметки, сборщика. Этот учебник проверяется так же: на каждое изменение запускаются проверки типов, тесты, проверка доступности, проверка ссылок и проверка содержимого, и только потом основная ветка выкладывается на Pages. Если на сайте есть форма, добавьте проверку, что страница политики и согласия существует (шаг в примере): так важное не потеряется при очередной правке.
GitLab записывает то же самое в файл .gitlab-ci.yml, платформы вроде Netlify, Vercel и Cloudflare Pages обходятся без файла вообще: подключили репозиторий, и они сами собирают и выкладывают на каждый коммит. Это самый простой конвейер, и для многих сайтов его хватает.
Секреты
Конвейеру нужны права: выложить на хостинг, написать в чат. Эти права записаны в токенах и ключах. Главное правило такое же, как в Docker: секреты не лежат в репозитории. Ни в файле конвейера, ни в коде, ни в README. Репозиторий читают коллеги, подрядчики, а иногда весь мир, а история Git хранит всё навсегда: удалённый файл остаётся в старых коммитах.
Секреты кладут в настройки сервиса (у GitHub это раздел Secrets and variables в настройках репозитория). В файле пишут только имя, например secrets.NOTIFY_URL, и платформа подставляет значение при запуске, скрывая его в журнале. Ещё три привычки: давать токену минимальные права (только выкладка), закреплять версии чужих действий (чужой код запускается с вашими правами) и помнить, что запросы на изменение из чужих копий репозитория секретов не получают.
Проверьте себя: почему нельзя просто удалить токен из репозитория после того, как он туда попал?
Он остаётся в истории коммитов, и любой, кто её читал или скопировал, мог его увидеть. Токен, попавший в репозиторий, считают утёкшим: его отзывают и выпускают новый.
Откат
Любой конвейер однажды выпустит плохую версию: проверки не видят всего. Поэтому заранее решите, как возвращаться.
- Через Git. Команда
git revertсоздаёт новый коммит, отменяющий плохой. Вы отправляете его вmain, и тот же конвейер выкладывает прежнее поведение. Историю основной ветки не переписывают принудительной отправкой: так теряют чужую работу. - Через панель хостинга. Статические платформы хранят прошлые выкладки, и одну из них можно сделать живой кнопкой.
- Сначала вернуть, потом разбираться. Минуты простоя ценнее, чем красивое понимание причины.
Единственное, что откатом не исправить, это данные: если плохая версия испортила базу, вернуть надо данные, а для этого нужны копии (последний урок части).
Практика
Перед вами сайт вашего проекта и под ним файл конвейера с пропусками. Допишите его: запуск по push в main, задание check со сборкой и проверками (ссылки, разметка и, если в проекте есть форма, страница политики), задание deploy с needs: check, секрет как secrets.ИМЯ. Потом напишите, что проверяет сборка для каждого раздела из брифа, и как вы будете откатывать.
Файл здесь только читается и проверяется, запустить Actions в песочнице нельзя. В следующем уроке вы выложите настоящий сайт, и этот файл вам пригодится.
Что было не так раньше
В 2010 году слова «релиз» боялись: раз в месяц, ночью, с чек-листом на шесть страниц, и один человек, у которого «всё настроено». После релиза неделя уходила на исправление найденного. Идея постоянной интеграции появилась раньше (в конце 1990-х), но обычным делом для небольших сайтов стала только когда появились бесплатные конвейеры при репозиториях. Теперь релиз скучен, и это как раз то, чего добивались.
Практика
Готовлю вашу страницу…
Тест
Вопрос 1 из 5
Карточки
Эти карточки попадут в повторение, когда вы завершите урок.
Что такое CI и CD?
Ответ
CI (непрерывная интеграция): каждое изменение автоматически собирается и проверяется. CD: непрерывная доставка (версия всегда готова, выкладка по кнопке) или развёртывание (после проверок уходит на сайт сама).
Из чего состоит конвейер сайта?
Ответ
Запуск по коммиту, проверки (ссылки, разметка, согласие), сборка, предпросмотр, выкладка только после зелёных проверок, уведомление. Упала любая станция: дальше ничего не идёт.
Где хранить токены и ключи конвейера?
Ответ
В настройках секретов сервиса (secrets). Файл конвейера ссылается на имя, значение в репозиторий не попадает. Кто-то прочитал репозиторий, значит прочитал и всё, что в нём.
Как откатить плохую версию?
Ответ
Вернуть предыдущее: git revert плохого коммита и push (конвейер выложит прошлое) или выбрать прошлую выкладку в панели хостинга. Историю main не переписывают.
Источники
- GitHub Docs: Understanding GitHub Actions CC BY, по-английски
- GitHub Docs: Using custom workflows with GitHub Pages CC BY, по-английски
- GitLab Docs: CI/CD только ссылка, по-английски
- Википедия: Непрерывная интеграция CC BY-SA, по-русски
- The Twelve-Factor App (на русском) только ссылка, по-русски
Дальше
Теперь вы знаете: CI/CD: проверка и выкладка по коммиту.