GitHub Actions

Зачем нужно

GitHub Actions — встроенная CI/CD платформа GitHub. Позволяет автоматизировать проверку, сборку и деплой прямо из репозитория. Бесплатна для публичных репозиториев и включает 2000 минут/месяц для приватных.

Где используется

  • CI — автоматический lint, build, test при каждом PR
  • CD — автоматический деплой при push в main
  • Автоматизация — создание релизов, обновление зависимостей
  • RS School — автоматическая проверка заданий

Основные концепции

Repository
└── .github/
    └── workflows/
        ├── ci.yml          ← Workflow файл
        └── deploy.yml      ← Другой workflow
Workflow (ci.yml)
├── Trigger: on push/PR
├── Job: lint
│   ├── Step: checkout
│   ├── Step: setup Node
│   └── Step: run eslint
├── Job: test
│   ├── Step: checkout
│   ├── Step: setup Node
│   └── Step: run jest
└── Job: build
    ├── Step: checkout
    ├── Step: setup Node
    └── Step: npm run build
Понятие Описание
Workflow Автоматизированный процесс (файл .yml)
Trigger (on) Событие, запускающее workflow
Job Набор шагов, выполняется на раннере
Step Одна задача внутри job
Action Переиспользуемый модуль (из Marketplace)
Runner Виртуальная машина для выполнения

Triggers — события запуска

on:
  # При push в определённые ветки
  push:
    branches: [main, develop]

  # При создании PR
  pull_request:
    branches: [main]

  # По расписанию (cron)
  schedule:
    - cron: '0 9 * * 1'    # каждый понедельник в 9:00 UTC

  # Ручной запуск
  workflow_dispatch:
    inputs:
      environment:
        description: 'Deploy environment'
        required: true
        default: 'staging'

  # При создании тега
  push:
    tags:
      - 'v*'

Базовый CI workflow

# .github/workflows/ci.yml
name: CI

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

jobs:
  lint-and-test:
    runs-on: ubuntu-latest

    steps:
      # 1. Получить код
      - name: Checkout repository
        uses: actions/checkout@v4

      # 2. Настроить Node.js
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'npm'

      # 3. Установить зависимости
      - name: Install dependencies
        run: npm ci

      # 4. Линтер
      - name: Run ESLint
        run: npm run lint

      # 5. Сборка
      - name: Build
        run: npm run build

      # 6. Тесты
      - name: Run tests
        run: npm test

Jobs — параллельные задачи

jobs:
  # Job 1 и Job 2 выполняются параллельно
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'npm'
      - run: npm ci
      - run: npm run lint

  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'npm'
      - run: npm ci
      - run: npm test

  # Job 3 зависит от lint и test
  build:
    needs: [lint, test]    # выполняется только если оба прошли
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'npm'
      - run: npm ci
      - run: npm run build

Матрица — тестирование на нескольких версиях

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [18, 20, 22]

    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
          cache: 'npm'
      - run: npm ci
      - run: npm test

Secrets — секреты

# Секреты добавляются в Settings → Secrets → Actions
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Deploy
        env:
          API_KEY: ${{ secrets.API_KEY }}
          DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}
        run: |
          echo "Deploying with token..."
          curl -H "Authorization: $DEPLOY_TOKEN" https://api.example.com/deploy

Настройка: Repository → Settings → Secrets and variables → Actions → New repository secret

Artifacts — сохранение файлов

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'npm'
      - run: npm ci
      - run: npm run build

      # Сохранить результат сборки
      - name: Upload build artifact
        uses: actions/upload-artifact@v4
        with:
          name: build-output
          path: dist/

  deploy:
    needs: build
    runs-on: ubuntu-latest
    steps:
      # Скачать артефакт из предыдущего job
      - name: Download build artifact
        uses: actions/download-artifact@v4
        with:
          name: build-output
          path: dist/

Actions Marketplace

Готовые action из маркетплейса:

steps:
  # Checkout код
  - uses: actions/checkout@v4

  # Setup Node.js с кэшированием
  - uses: actions/setup-node@v4
    with:
      node-version: 20
      cache: 'npm'

  # Деплой на GitHub Pages
  - uses: peaceiris/actions-gh-pages@v3
    with:
      github_token: ${{ secrets.GITHUB_TOKEN }}
      publish_dir: ./dist

  # Уведомление в Slack
  - uses: 8398a7/action-slack@v3
    with:
      status: ${{ job.status }}

Пример: полный CI/CD для фронтенда

name: CI/CD

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

jobs:
  ci:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'npm'
      - run: npm ci
      - run: npm run lint
      - run: npm run build
      - run: npm test

      - uses: actions/upload-artifact@v4
        with:
          name: dist
          path: dist/

  deploy:
    needs: ci
    if: github.ref == 'refs/heads/main' && github.event_name == 'push'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/download-artifact@v4
        with:
          name: dist
          path: dist/

      - name: Deploy to GitHub Pages
        uses: peaceiris/actions-gh-pages@v3
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: ./dist

Условия и выражения

steps:
  - name: Deploy to staging
    if: github.ref == 'refs/heads/develop'
    run: deploy-staging.sh

  - name: Deploy to production
    if: github.ref == 'refs/heads/main'
    run: deploy-prod.sh

  - name: Notify on failure
    if: failure     # только при ошибке
    run: echo "Build failed!"

Частые ошибки

Ошибка Проблема Решение
Workflow не запускается Файл не в .github/workflows/ Проверь путь и расширение .yml
npm ci fails Нет package-lock.json Закоммить package-lock.json
Секрет пустой в PR от fork Ограничение безопасности Используй pull_request_target осторожно
Долгий CI Нет кэширования Добавь cache: 'npm' в setup-node
Ошибка прав на deploy Нет GITHUB_TOKEN Используй ${{ secrets.GITHUB_TOKEN }}

Практика

  1. Создай .github/workflows/ci.yml для lint + build + test
  2. Настрой запуск на push и pull_request
  3. Добавь бейдж статуса CI в README
  4. Настрой деплой на GitHub Pages через Actions
  5. Добавь матрицу для тестирования на Node 18 и 20

Связанные темы

Ресурсы