GitHub Actions на практике: от простых workflow до продвинутой автоматизации

GitHub Actions на практике: от простых workflow до продвинутой автоматизации

GitHub Actions — это мощный инструмент автоматизации, встроенный прямо в GitHub. Он позволяет создавать, тестировать и развертывать код без необходимости в сторонних сервисах. В этой статье мы разберем реальные примеры workflow, которые помогут вам автоматизировать рутинные задачи и вывести разработку на новый уровень.

Что такое GitHub Actions и workflow?

Workflow в GitHub Actions — это автоматизированный процесс, который вы описываете в YAML-файле в директории .github/workflows вашего репозитория. Каждый workflow состоит из одного или нескольких заданий (jobs), которые, в свою очередь, содержат шаги (steps). Эти шаги могут быть либо действиями (actions) — готовыми блоками логики, либо обычными командами shell.

GitHub Actions работает на основе событий (events). Самый распространенный триггер — push в определенную ветку (например, main) или pull_request. Но можно запускать workflow по расписанию (cron), вручную или при создании релиза.

Базовый пример: CI для Node.js проекта

Создайте файл .github/workflows/node-ci.yml. Этот workflow будет запускать тесты при каждом пуше в ветку main или при открытии pull request.

name: Node.js CI

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
    - name: Use Node.js
      uses: actions/setup-node@v4
      with:
        node-version: '20'
    - run: npm ci
    - run: npm run build --if-present
    - run: npm test

Разберем ключевые моменты:

  • on: Определяет события-триггеры.
  • jobs.build: Создает задание с именем "build".
  • runs-on: Указывает, на какой операционной системе (виртуальной машине) будет выполняться задание.
  • steps: Последовательность шагов. uses — использует готовое действие из Marketplace. run

Продвинутый пример: мультиплатформенная сборка и деплой

Допустим, у вас есть проект на Python, который нужно протестировать на разных версиях ОС и Python, а затем автоматически опубликовать пакет в PyPI при создании тега.

Workflow для тестирования на нескольких ОС

name: Python package

on: [push, pull_request]

jobs:
  test:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest, macos-latest]
        python-version: ['3.9', '3.10', '3.11']
    steps:
    - uses: actions/checkout@v4
    - name: Set up Python ${{ matrix.python-version }}
      uses: actions/setup-python@v5
      with:
        python-version: ${{ matrix.python-version }}
    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip
        pip install -r requirements.txt
        pip install pytest
    - name: Test with pytest
      run: pytest -v

Здесь используется мощная функция матричной стратегии (matrix strategy). Она позволяет запустить одно и то же задание в нескольких конфигурациях параллельно. В данном случае — на трех ОС и с тремя версиями Python.

Workflow для публикации в PyPI

name: Publish Python Package

on:
  release:
    types: [published]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
    - name: Set up Python
      uses: actions/setup-python@v5
      with:
        python-version: '3.11'
    - name: Install dependencies
      run: pip install setuptools wheel twine
    - name: Build and publish
      env:
        TWINE_USERNAME: __token__
        TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
      run: |
        python setup.py sdist bdist_wheel
        twine upload dist/*

Секреты (Secrets), такие как PYPI_API_TOKEN, хранятся в настройках репозитория (Settings > Secrets and variables > Actions) и никогда не отображаются в логах workflow. Это безопасный способ работы с чувствительными данными.

Креативные примеры использования

GitHub Actions — это не только про CI/CD. Вот несколько неочевидных, но полезных сценариев:

  1. Автоматическое обновление зависимостей: Используйте действие peter-evans/create-pull-request, чтобы автоматически создавать PR с обновленными версиями пакетов из requirements.txt или package.json.
  2. Проверка орфографии в Markdown-файлах: Запускайте проверку правописания для всей документации в проекте.
  3. Сборка и деплой статического сайта (например, на GitHub Pages): При пуше в ветку docs можно автоматически собирать сайт с помощью Jekyll, Hugo или Docusaurus и публиковать его.
  4. Уведомления в Telegram/Slack: Отправляйте сообщение в чат команды об успешном или неудачном выполнении workflow.

FAQ: Часто задаваемые вопросы о GitHub Actions

Сколько стоит использование GitHub Actions?

Для публичных репозиториев и для приватных репозиториев в рамках бесплатного плана GitHub предоставляет определенное количество бесплатных минут и место для хранения артефактов. Для приватных репозиториев на платных тарифах лимиты выше. Детали всегда можно уточнить на официальном сайте.

Где хранятся секреты (secrets) и как их использовать?

Секреты хранятся в зашифрованном виде в настройках репозитория или организации. В workflow они доступны через контекст ${{ secrets.ИМЯ_СЕКРЕТА }}. Их нельзя вывести в логах командой echo — GitHub автоматически маскирует такие попытки.

Можно ли запускать workflow вручную?

Да, для этого нужно добавить триггер workflow_dispatch в секцию on. Тогда в интерфейсе GitHub появится кнопка "Run workflow", и вы сможете при необходимости передать входные параметры.

Как отлаживать упавший workflow?

В первую очередь смотрите детальные логи каждого шага на вкладке "Actions" вашего репозитория. Часто проблема в отсутствии зависимости, неправильном пути к файлу или в недостаточных правах. Локально можно использовать инструмент act для приблизительного прогона workflow, но это не дает 100% точности.

Что такое кэширование зависимостей и как его настроить?

Кэширование (например, пакетов npm или pip) позволяет не скачивать зависимости заново при каждом запуске, что значительно ускоряет выполнение workflow. Для этого используются специальные действия, например, actions/cache. Нужно указать ключ (key) и путь к кэшируемым директориям.