GitHub Actions

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

Типичные сценарии использования включают: автоматический запуск тестов после отправки кода, автоматическое развёртывание на серверах после слияния PR, а также запуск скриптов сбора данных по расписанию.

GitHub Actions дляпубличных репозиториев полностью бесплатен., для приватных репозиториев доступна бесплатная квота 2,000 минут в месяц.


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

Прежде чем писать файл конфигурации, нужно понять следующие основные концепции, а связи между ними таковы:

仓库(Repository)
└── Workflow(工作流)          ← 一个 .yml 文件 = 一个 Workflow
    ├── Event(触发事件)        ← 什么情况下启动这个 Workflow,如 push、PR
    └── Job(作业)× N          ← 一个 Workflow 可以包含多个并行或串行的 Job
        ├── Runner(运行器)     ← 执行 Job 的服务器,如 ubuntu-latest
        └── Step(步骤)× N     ← Job 内按顺序执行的一系列操作
            ├── Action          ← 可复用的封装好的操作,如 actions/checkout
            └── Run             ← 直接执行 Shell 命令
Концепции Описание Аналогия
Рабочий процесс Весь автоматизированный рабочий процесс определяется.ymlфайлом, хранящимся в.github/workflows/в каталоге полный план работы.
Event Условия, запускающие Workflow, например отправка кода, создание PR, запланированные задачи и т. д. Условие запуска плана.
Job(задание) Независимая единица задачи в Workflow. Каждый Job выполняется на отдельной виртуальной машине, а несколько Job по умолчанию выполняются параллельно. Раздел в плане.
Шаг Наименьшая единица операции, выполняемая последовательно внутри Job; это может быть команда Shell или Action. Каждый конкретный шаг в разделе.
Действие Переиспользуемые упакованные операции, от официальных GitHub, сторонних или самостоятельно написанных, черезusesСсылка Готовые шаблоны инструментов
Runner Сервер, который выполняет Jobs. GitHub предоставляет три хостируемые среды: Ubuntu, Windows и macOS. Исполнитель, который выполняет план.

Создайте свой первый Workflow.

1. Структура каталогов

Все файлы Workflow должны храниться в.github/workflows/каталоге в корне репозитория, а имена файлов должны заканчиваться на.ymlили.yamlИмя файла можно настроить:

your-repo/
├── .github/
│   └── workflows/
│       ├── ci.yml          ← 持续集成流程(如运行测试)
│       ├── deploy.yml      ← 部署流程
│       └── scheduled.yml   ← 定时任务
├── src/
├── package.json
└── README.md

Репозиторий может содержать несколько файлов Workflow, которые независимы друг от друга и запускаются соответствующими определёнными событиями.

2. Простейший рабочий процесс

Ниже приведён самый простой пример: каждый раз, когда код отправляется в репозиторий, выводится строка "Привет, GitHub Actions!".

Пример

# .github/workflows/hello.yml

name
: Привет, мир                  # Название рабочего процесса, отображаемое на странице GitHub Actions

on
: push                           # Условие запуска: срабатывает при отправке кода в любую ветку

jobs
:                             # Определить все задания
  say-hello
:                      # ID задания (пользовательское имя, уникальное в пределах одного рабочего процесса)
    name
: Вывести приветствие# Отображаемое имя задания (необязательно; если пусто, отображается ID задания)
    runs-on
: ubuntu-latest         # Указать среду выполнения: использовать последнюю виртуальную машину Ubuntu, предоставленную GitHub

    steps
:                        # Все шаги этого задания выполняются по порядку
      - name
: printMessage# Имя шага (необязательно, используется для идентификации этого шага в логах)
        run
: echo "Привет, GitHub Actions!"   # run: напрямую выполнить команды Shell

YAML-файлы очень чувствительны к отступам и должны использоватьпробелдля отступов, и нельзя использовать клавишу Tab. Рекомендуется использовать VS Code и установить плагин YAML, который может обнаруживать ошибки форматирования в реальном времени.


События-триггеры (on)

onЭто поле определяет, какие события запускают этот Workflow. Это может быть одно событие или комбинация нескольких событий.

1. Общие события-триггеры

Events Момент срабатывания Типичные применения
push Когда код отправляется в репозиторий. Запуск тестов, проверок кода
pull_request Когда создается или обновляется Pull Request. Автоматическая проверка и тестирование перед слиянием PR.
schedule Запуск по расписанию с использованием Cron-выражения. Плановые резервные копии, плановый сбор данных.
workflow_dispatch Ручной запуск на веб-странице GitHub Развертывание по требованию, ручной запуск скриптов.
release При публикации новой версии (создании релиза) Автоматическая упаковка и публикация в production.
workflow_call При вызове из других рабочих процессов Повторное использование публичных рабочих процессов (например, публичных рабочих процессов тестирования)

2. Фильтрация по веткам или путям

Пример

span style="color: #0053A6;">
on:
  push
:
    branches
:
     - main            # Срабатывает только при push в ветку main
      - develop         # Или срабатывает при push в ветку develop
      - 'release/**'    # Или срабатывает при push в любую ветку, начинающуюся с release/ (** соответствует любым символам)
    paths
:
     - 'src/**'        # Дополнительная фильтрация: срабатывает только при изменении файлов в каталоге src/.
      - 'package.json'  # Или срабатывает при изменении файла package.json
                        # Эти два находятся в отношении «ИЛИ»; срабатывает любой из них

  pull_request
:
    branches
:
     - main            # Срабатывает только на PR, у которых целевая ветка — main (то есть на PR, предназначенных для слияния в main)
    types
:
     - opened          # Когда создаётся PR
      - synchronize     # Когда в PR отправляется новый коммит
      - reopened        # Когда PR открывается повторно

3. Триггеры по расписанию (schedule)

Используйте стандартное Cron-выражение для определения времени выполнения; часовой пояс — UTC (пекинское время = UTC+8, требуется преобразование):

Пример

span style="color: #0053A6;">
on:
  schedule
:
   # Формат Cron: минута час день месяц неделя
    - cron
: '0 2 * * *'       # Запускать раз в день в 02:00 UTC (то есть в 10:00 по пекинскому времени)
    - cron
: '0 9 * * 1'       # Выполняется один раз каждый понедельник в 09:00 UTC (т.е. в 17:00 по пекинскому времени)
    - cron
: '*/30 * * * *'    # Запускать каждые 30 минут

# Краткий справочник по распространённым cron-выражениям:
# '0 0 * * *' Каждый день в полночь (UTC 00:00)
# '0 * * * *' каждый час ровно в начале часа
# '0 0 * * 0' каждое воскресенье в полночь
# '0 0 1 * *' Полночь 1-го числа каждого месяца

4. Ручной запуск (workflow_dispatch)

workflow_dispatchПозволяет вручную нажать кнопку на вкладке Actions веб-страницы GitHub, чтобы запустить Workflow, а также можно задать входные параметры:

Пример

span style="color: #0053A6;">
on:
  workflow_dispatch
:
    inputs
:
      environment
:             # Имя входного параметра (можно ссылаться в шагах через ${{ inputs.environment }})
        description
: 'Целевая среда развёртывания'# Описание параметра, отображается в форме ручного запуска
        required
: true          # Требуется ли это?
        default
: 'staging'      # Значение по умолчанию
        type
: choice            # Тип параметра: choice (выбор из выпадающего списка)
        options
:
         - staging             # Необязательные значения
          - production

      run_tests
:
        description
: 'Запускать ли тесты'
        required
: false
        type
: boolean           # Тип параметра: boolean (флажок)
        default
: true

jobs
:
  deploy
:
    runs-on
: ubuntu-latest
    steps
:
      - name
: Отобразить параметры развертывания
        run
: |
echo "Целевая среда: ${{ inputs.environment }}"
echo "Run tests: ${{ inputs.run_tests }}"


Подробное объяснение заданий и шагов

1. Базовая структура задания

Пример

span style="color: #0053A6;">
jobs:
  build
:                         # Идентификатор задания, должен быть уникальным в пределах одного рабочего процесса
    name
: structurebuildProject# Отображаемое имя задания (необязательно)
    runs-on
: ubuntu-latest        # Среда выполнения (обязательно)

    # Необязательно: задать переменные окружения для всего задания, доступные всем шагам в задании
    env
:
      NODE_ENV
: production
      APP_PORT
: 8080

    # Необязательно: задать тайм-аут в минутах. Задание будет автоматически отменено после тайм-аута, чтобы предотвратить зависание.
    timeout-minutes
: 30

    steps
:
     # Способ шага 1: использовать Action (ссылка с помощью uses)
      - name
: Извлечь код
        uses
: actions/checkout@v4         # Ссылка на официальный checkout Action (@v4 указывает, что используется версия v4)

      # Синтаксис шага 2: выполнить команду Shell (указывается с помощью run)
      - name
: Вывести версию Node
        run
: node --version

      # Шаг 3: выполнение многострочных команд Shell (использование | для нескольких строк)
      - name
: Установить зависимости и собрать структуру
        run
: |
         npm install
          npm run build
echo "Build complete"

2. Среда выполнения (runs-on)

GitHub предоставляет следующие бесплатные размещённые раннеры, которые вы можете выбрать по необходимости:

Теги Операционная система Описание
ubuntu-latest Ubuntu (последняя LTS) Наиболее часто используемый, быстрый и имеет самую щедрую бесплатную квоту. Рекомендуется использовать в первую очередь.
ubuntu-22.04 Ubuntu 22.04 Укажите фиксированную версию, чтобы избежать проблем несовместимости, вызванных последними обновлениями.
windows-latest Windows Server (последний) Используется для тестирования или сборки, требующей среды Windows.
macos-latest macOS (последняя) Используется для сборки приложений iOS/macOS, быстрее всего расходует бесплатную квоту (примерно в 10 раз больше, чем у Ubuntu).

3. Зависимости между заданиями (needs)

По умолчанию несколько заданий выполняются параллельно. ИспользуйтеneedsВы можете задать порядок выполнения заданий, формируя последовательные зависимости:

Пример

span style="color: #0053A6;">
jobs:
  test
:                          # Шаг 1: Запустить тесты
    runs-on
: ubuntu-latest
    steps
:
      - uses
: actions/checkout@v4
      - run
: npm test

  build
:                         # Шаг 2: Сборка проекта
    runs-on
: ubuntu-latest
    needs
: test                   # build запустится только после успешного завершения задания test
    steps
:
      - uses
: actions/checkout@v4
      - run
: npm run build

  deploy
:                        # Шаг 3: Развертывание
    runs-on
: ubuntu-latest
    needs
: [test, build]          # Deploy должен дождаться, пока и test, и build успешно завершатся
    steps
:
      - run
: echo Начинаем развертывание...

# Порядок выполнения: test → build → deploy (последовательно)
# Если убрать needs, три задания будут выполняться параллельно.

4. Условное выполнение (if)

ЧерезifВы можете управлять тем, будет ли выполняться Job или Step; это обычно используется для различения веток, определения того, успешно ли завершился предыдущий шаг, и т. д.:

Пример

span style="color: #0053A6;">
jobs:
  deploy
:
    runs-on
: ubuntu-latest
    # если написать if на уровне Job: весь Job выполняется только при push в ветку main
    if
: github.ref == 'refs/heads/main'
    steps
:
      - uses
: actions/checkout@v4

      - name
: Развертывание в производственную среду
        run
: ./deploy.sh

      # if также можно записать на уровне шага, чтобы контролировать, выполняется ли конкретный шаг
      - name
: Отправить уведомление об успехе
        if
: success()             # success(): выполняется только когда все вышеуказанные шаги завершатся успешно
        run
: echo "Развертывание успешно, отправьте уведомление"

      - name
: Отправить уведомление о сбое
        if
: failure()             # failure(): выполняется только при сбое любого шага
        run
: echo Развертывание не удалось, отправьте оповещение

      - name
: Шаги очистки выполняются всегда
        if
: always()              # always(): Выполняется независимо от успеха или сбоя (часто используется для очистки временных файлов)
        run
: rm -rf ./tmp

Переменные среды и секреты

1. Переменные среды (env)

Переменные среды можно определить на трёх уровнях в рабочем процессе, при этом область действия уменьшается в указанном порядке:

Пример

# Уровень 1: уровень рабочего процесса (доступны всем заданиям и шагам)
env
:
  APP_NAME
: my-app
  NODE_VERSION
: '18'

jobs
:
  build
:
    runs-on
: ubuntu-latest

    # Уровень 2: уровень задания (доступны только шагам внутри текущего задания)
    env
:
      BUILD_MODE
: production

    steps
:
      - name
: Отобразить переменные среды
        # Уровень 3: уровень шага (доступны только текущему шагу)
        env
:
          STEP_VAR
: hello
        run
: |
echo "Имя приложения: $APP_NAME" # Доступ к переменной уровня рабочего процесса
echo "Режим сборки: $BUILD_MODE" # Доступ к переменной уровня задания
echo "Переменная шага: $STEP_VAR" # Доступ к переменной уровня шага
echo "Версия Node: $NODE_VERSION"

2. Встроенные переменные GitHub (контекст github)

GitHub Actions предоставляет набор встроенных переменных контекста, к которым можно получить доступ в любом месте с помощью${{ }}Справочник по синтаксису:

Пример

span style="color: #0053A6;">
steps:
  - name
: Вывести общие встроенные переменные
    run
: |
echo "Имя репозитория: ${{ github.repository }}" # Например: your-user/your-repo
echo "Событие запуска: ${{ github.event_name }}" # напр., push, pull_request
echo "Текущая ветка: ${{ github.ref_name }}" # напр., main, develop
echo "Submit SHA:${{ github.sha }}" # текущее значение полного SHA-хеша коммита
echo "Committer: ${{ github.actor }}" # имя пользователя, запустившего этот Workflow
echo "Working directory: ${{ github.workspace }}" # путь к каталогу, где находится код после checkout
echo "Run ID:${{ github.run_id }}" # уникальный ID каждого запуска Workflow
echo "RuneditNumber:${{ github.run_number }}" # количество запусков этого Workflow

3. Secrets (управление конфиденциальной информацией)

Конфиденциальная информация, такая как пароли, ключи API, адреса серверов и т. д.Не может быть записана напрямую в файл yml.(Поскольку код является публичным), она должна храниться в Secrets репозитория GitHub.

Шаги настройки: перейдите на страницу репозитория →Settings → Secrets and variables → Actions→ НажмитеNew repository secretзаполните имя и значение, затем сохраните.

Пример

span style="color: #0053A6;">
steps:
 # В Step ссылайтесь на настроенный Secret через ${{ secrets.secret_name }}
  # Значения Secret автоматически маскируются с помощью *** в логах и не будут раскрыты
  - name
: Развертывание на сервере
    env
:
      SSH_KEY
: ${{ secrets.SSH_PRIVATE_KEY }}       # Приватный SSH-ключ сервера
      SERVER_IP
: ${{ secrets.DEPLOY_SERVER_IP }}    # IP-адрес сервера
    run
: |
     echo "$SSH_KEY" > ~/.ssh/id_rsa
      chmod 600 ~/.ssh/id_rsa
      ssh user@$SERVER_IP "cd /app && git pull && pm2 restart all"

  # GitHub автоматически предоставляет GITHUB_TOKEN для операций с этим репозиторием (например, отправка кода, создание релизов)
  # Не нужно создавать вручную, просто используйте его напрямую
  - name
: Отправить изменения в репозиторий
    run
: |
     git config user.name "github-actions[bot]"
      git config user.email "github-actions[bot]@users.noreply.github.com"
      git add .
git commit -m "Автообновление [skip ci]"
      git push

    env
:
      GITHUB_TOKEN
: ${{ secrets.GITHUB_TOKEN }}     # GitHub предоставляет автоматически, не нужно создавать вручную

Введение в общие Actions

Официальный GitHub и сообщество предоставляют большое количество готовых к использованию Actions, черезuses: action名称@版本ссылки, вы можете избежать повторного написания общих операций.

1. actions/checkout (получение кода)

Почти первым шагом каждого Workflow является получение кода репозитория с использованием официальногоactions/checkout:

Пример

span style="color: #0053A6;">
steps:
 # Самое основное использование: получить последнюю версию кода текущей ветки в рабочий каталог
  - uses
: actions/checkout@v4

  # Расширенное использование: настройка путём передачи параметров с помощью 'with'
  - uses
: actions/checkout@v4
    with
:
      ref
: develop              # Получить указанную ветку (по умолчанию получает ветку, в которой произошло событие-триггер)
      fetch-depth
: 0            # Получить полную историю git (по умолчанию извлекается только последний коммит)
                                # Установите 0, чтобы получить всю историю, тогда команды вроде git log смогут работать правильно.
      submodules
: true          # Также инициализировать и обновить git-подмодули

2. actions/setup-node (настройка окружения Node.js)

Пример

span style="color: #0053A6;">
steps:
  - uses
: actions/checkout@v4

  - name
: Настройка окружения Node.js
    uses
: actions/setup-node@v4
    with
:
      node-version
: '20'        # Укажите версию Node.js

  # После завершения настройки команды npm и node можно использовать напрямую
  - run
: node --version
  - run
: npm install
  - run
: npm test

3. actions/setup-python (настройка окружения Python)

Пример

span style="color: #0053A6;">
steps:
  - uses
: actions/checkout@v4

  - name
: Настройка окружения Python
    uses
: actions/setup-python@v5
    with
:
      python-version
: '3.11'   # Укажите версию Python

  - name
: Установка зависимостей
    run
: pip install -r requirements.txt

  - name
: Запуск тестов
    run
: pytest tests/

4. actions/cache (кэширование зависимостей для ускорения сборок)

Скачивание зависимостей при каждом запуске рабочего процесса может быть медленным. Использование действия cache позволяет кэшировать зависимости и напрямую использовать их при следующем запуске, что значительно сокращает время сборки:

Пример

span style="color: #0053A6;">
steps:
  - uses
: actions/checkout@v4

  - uses
: actions/setup-node@v4
    with
:
      node-version
: '20'

  - name
: Кэшировать node_modules
    uses
: actions/cache@v4
    with
:
      path
: ~/.npm                            # Укажите каталог для кэширования
      key
: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
      # key: уникальный идентификатор для кэша
      # hashFiles('**/package-lock.json'): сгенерировать хеш-значение на основе содержимого lock-файла
      # Если lock-файл не изменён, ключ не изменён, и кэш попадает напрямую; если lock-файл изменяется, зависимости переустанавливаются.

      restore-keys
: |
       ${{ runner.os }}-node-
      # restore-keys: стратегия запасного сопоставления при промахе ключа, использующая самый свежий действительный кэш

  - run
: npm ci                              # npm ci лучше подходит для CI-сценариев, чем npm install: быстрее и строже
  - run
: npm test

5. actions/upload-artifact / download-artifact (передача файлов между заданиями)

Разные задания выполняются на независимых виртуальных машинах, поэтому файлы нельзя совместно использовать напрямую. С помощью артефактов можно передать выходные файлы одного задания другому заданию:

Пример

span style="color: #0053A6;">
jobs:
  build
:
    runs-on
: ubuntu-latest
    steps
:
      - uses
: actions/checkout@v4
      - run
: npm install && npm run build     # Артефакты сборки будут выведены в каталог ./dist

      - name
: Загрузить артефакты сборки
        uses
: actions/upload-artifact@v4
        with
:
          name
: dist-files                   # Имя артефакта (на него ссылаются по этому имени при скачивании)
          path
: ./dist                       # Каталог или путь к файлу для загрузки
          retention-days
: 7                  # Количество дней хранения артефакта (макс. 90 дней)

  deploy
:
    runs-on
: ubuntu-latest
    needs
: build                             # Выполняется после завершения задания build
    steps
:
      - name
: Скачать артефакты сборки
        uses
: actions/download-artifact@v4
        with
:
          name
: dist-files                   # То же, что и имя при загрузке
          path
: ./dist                       # Каталог для скачивания локально

      - name
: DeploymentFile
        run
: rsync -avz ./dist/ user@server:/var/www/html/

Матричные сборки (Matrix)

Матричные сборки позволяют запускать одну конфигурацию задания параллельно в нескольких средах; обычно используются для тестирования совместимости между версиями и операционными системами:

Пример

span style="color: #0053A6;">
jobs:
  test
:
    name
: Тест Node ${{ matrix.node-version }} на ${{ matrix.os }}
    runs-on
: ${{ matrix.os }}         # Читает среду выполнения из переменных матрицы

    strategy
:
      matrix
:
        os
: [ubuntu-latest, windows-latest, macos-latest]   # 3 операционные системы
        node-version
: ['18', '20', '22']                    # 3 версии Node
        # Приведённые выше комбинации дают 3 × 3 = 9 параллельных заданий

      fail-fast
: false                # По умолчанию true: отменяет все оставшиеся задания, если одно задание завершается с ошибкой.
                                      # Установите false: даже если комбинация завершается с ошибкой, другие комбинации продолжают выполняться,
                                      # Удобно видеть результаты тестов для всех окружений

    steps
:
      - uses
: actions/checkout@v4

      - name
: Настроить Node.js ${{ matrix.node-version }}
        uses
: actions/setup-node@v4
        with
:
          node-version
: ${{ matrix.node-version }}   # Ссылка на переменные matrix

      - run
: npm ci
      - run
: npm test

Пример

# Расширенное использование: используйте exclude, чтобы исключить определённые нежелательные комбинации, и используйте include, чтобы добавить специальные конфигурации
strategy
:
  matrix
:
    os
: [ubuntu-latest, windows-latest]
    node-version
: ['18', '20']
    exclude
:
      - os
: windows-latest
        node-version
: '18'    # Исключить комбинацию Windows + Node 18

    include
:
      - os
: ubuntu-latest
        node-version
: '20'
        experimental
: true    # Добавьте дополнительные переменные для конкретных комбинаций (на них можно ссылаться в шагах с помощью matrix.experimental)

Практические примеры

Пример 1: CI проекта Node.js (автоматизированное тестирование)

Каждый раз, когда код отправляется или создаётся PR, автоматически устанавливайте зависимости и запускайте проверки кода и тесты:

Пример

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

на
:
  push
:
    branches
: [main, develop]
  pull_request
:
    branches
: [main]

jobs
:
  test
:
    name
: CodeChecksandTesting
    runs-on
: ubuntu-latest

    steps
:
      - name
: Извлечь код
        uses
: actions/checkout@v4

      - name
: Настройка окружения Node.js
        uses
: actions/setup-node@v4
        with
:
          node-version
: '20'
          cache
: 'npm'                       # setup-node имеет встроенную поддержку кэширования, что более лаконично, чем отдельно использовать действие cache

      - name
: Установка зависимостей
        run
: npm ci                          # npm ci будет устанавливать строго в соответствии с package-lock.json,
                                             # Больше подходит для сценариев CI, чем npm install

      - name
: Запустить линтинг кода (ESLint)
        run
: npm run lint

      - name
: Запустить модульные тесты
        run
: npm test -- --coverage          # Также сгенерировать отчёт о покрытии тестов

      - name
: Загрузить отчёт о покрытии
        uses
: actions/upload-artifact@v4
        if
: always()                         # Загрузить отчёт независимо от того, пройдёт ли тест (чтобы было легко просмотреть причины сбоя)
        with
:
          name
: coverage-report
          path
: ./coverage

Пример 2: CI проекта на Python

Пример

# .github/workflows/python-ci.yml
name
: Python CI

на
:
  push
:
    branches
: [main]
  pull_request
:

jobs
:
  test
:
    runs-on
: ubuntu-latest

    steps
:
      - uses
: actions/checkout@v4

      - name
: Настройка окружения Python
        uses
: actions/setup-python@v5
        with
:
          python-version
: '3.11'
          cache
: 'pip'                       # Кэшировать зависимости pip

      - name
: Установка зависимостей
        run
: |
         python -m pip install --upgrade pip
          pip install -r requirements.txt
pip install flake8 pytest # Установить инструменты линтинга и тестирования кода

      - name
: Запустить проверку форматирования кода (flake8)
        run
: |
# Проверить синтаксические ошибки и неопределённые переменные (серия E9, F63, F7, F82) и сразу завершить с ошибкой, если обнаружена любая проблема
          flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
# Проверить стиль кода (максимальная длина строки 120), только подсчитать количество проблем, не завершать с ошибкой.
          flake8 . --count --max-line-length=120 --statistics

      - name
: Запуск тестов
        run
: pytest tests/ -v                # -v выводит подробные результаты тестов

Пример 3: Сборка и отправка Docker-образа(ов)

Пример

# .github/workflows/docker.yml
name
: Сборка и отправка Docker-образа

на
:
  push
:
    branches
: [main]
    tags
:
     - 'v*'                               # Запуск при отправке тегов, начинающихся с v, например v1.0.0

jobs
:
  docker
:
    runs-on
: ubuntu-latest
    steps
:
      - uses
: actions/checkout@v4

      # Используйте официальный Docker Action для генерации тегов образа.
      # Например, при отправке v1.2.3 автоматически создаются несколько тегов, таких как 1.2.3, 1, latest
      -
: Извлечение метаданных Docker (теги образа и т. д.)
        id
: meta                           # Установите ID для этого шага, чтобы последующие шаги могли ссылаться на его вывод.
        uses
: docker/metadata-action@v5
        with
:
          images
: your-dockerhub-username/your-image-name

      - name
: Вход в Docker Hub
        uses
: docker/login-action@v3
        with
:
          username
: ${{ secrets.DOCKERHUB_USERNAME }}
          password
: ${{ secrets.DOCKERHUB_TOKEN }}   # Используйте Access Token вместо пароля для лучшей безопасности

      - name
: structurebuildandPush образ
        uses
: docker/build-push-action@v5
        with
:
          context
: .                       # Каталог, в котором находится Dockerfile (текущий каталог)
          push
: true                       # true: отправить в Registry после завершения сборки
          tags
: ${{ steps.meta.outputs.tags }}       # Ссылается на список тегов, сгенерированный шагом meta
          labels
: ${{ steps.meta.outputs.labels }}   # Ссылается на информацию о тегах, сгенерированную шагом meta

Пример 4: Автоматическое развёртывание на сервер после сборки

Пример

# .github/workflows/deploy.yml
name
: Сборка и развёртывание

на
:
  push
:
    branches
: [main]                       # Развёртывание запускается только при push в ветку main

jobs
:
  build-and-deploy
:
    runs-on
: ubuntu-latest

    steps
:
      - uses
: actions/checkout@v4

      - uses
: actions/setup-node@v4
        with
:
          node-version
: '20'
          cache
: 'npm'

      - name
: Установить зависимости и собрать структуру
        run
: |
         npm ci
npm run build # Артефакты сборки выводятся в каталог ./dist

      - name
: Развернуть на сервере через SSH
        uses
: appleboy/[email protected]   # Сторонний SSH Action, не нужно вручную настраивать SSH
        with
:
          host
: ${{ secrets.SERVER_HOST }}       # IP-адрес или домен сервера
          username
: ${{ secrets.SERVER_USER }}   # Имя пользователя для входа по SSH
          key
: ${{ secrets.SSH_PRIVATE_KEY }}    # Содержимое приватного ключа SSH (соответствующего открытому ключу на сервере)
          port
: 22                               # Порт SSH, по умолчанию 22
          script
: |
# Следующие команды выполняются на удалённом сервере
            cd /var/www/my-app
            git pull origin main
            npm ci --production
pm2 restart my-app # Перезапустить приложение Node.js с помощью pm2
echo "Развёртывание завершено: $(date)"

Пример 5: Запланированная задача (автоматическое резервное копирование базы данных)

Пример

# .github/workflows/backup.yml
name
: определить, когда создавать резервную копию базы данных

на
:
  schedule
:
    - cron
: '0 2 * * *'                    # Запускать ежедневно в 02:00 UTC (10:00 по пекинскому времени)
  workflow_dispatch
:                       # Также поддерживает ручной запуск для временных резервных копий

jobs
:
  backup
:
    runs-on
: ubuntu-latest

    steps
:
      - name
: Выполнить скрипт резервного копирования через SSH
        uses
: appleboy/[email protected]
        with
:
          host
: ${{ secrets.SERVER_HOST }}
          username
: ${{ secrets.SERVER_USER }}
          key
: ${{ secrets.SSH_PRIVATE_KEY }}
          script
: |
           TIMESTAMP=$(date +%Y%m%d_%H%M%S)
            BACKUP_FILE="/backup/db_$TIMESTAMP.sql"

# Выполнить резервное копирование базы данных
            mysqldump -u root -p${{ secrets.DB_PASSWORD }} my_database > $BACKUP_FILE

# Сжать файлы резервных копий
            gzip $BACKUP_FILE

# Удалить файлы резервных копий старше 30 дней, чтобы диск не переполнялся
            find /backup -name "*.sql.gz" -mtime +30 -delete

echo "Резервное копирование завершено: ${BACKUP_FILE}.gz"


Советы по отладке

1. Включение журналов отладки

Когда запуск Workflow завершается неудачно, но информации в журнале недостаточно, можно включить подробный режим отладки. Способ: перейдите в репозиторийSettings → Secrets and variables → Actions, добавьте следующие два Secrets (установите оба значения вtrue):

  • ACTIONS_RUNNER_DEBUGВключить подробные журналы runner
  • ACTIONS_STEP_DEBUG: Включить подробное логирование отладки для каждого шага.

2. Вывод контекстной информации для облегчения устранения неполадок

Пример

span style="color: #0053A6;">
steps:
  - name
: Вывести всю контекстную информацию (для отладки; добавляйте при устранении неполадок, удаляйте после решения)
    run
: |
echo "=== github context ==="
echo '${{ toJson(github) }}' # toJson() преобразует объект в строковый вывод JSON
echo "=== контекст env ==="
      echo '${{ toJson(env) }}'
echo "=== контекст job ==="
      echo '${{ toJson(job) }}'

3. Локальное тестирование рабочего процесса (с помощью act)

Тестировать рабочий процесс, каждый раз только отправляя код, очень неэффективно.act— это инструмент с открытым исходным кодом, который позволяет локально имитировать выполнение GitHub Actions, значительно повышая эффективность отладки:

# 安装 act(需要本地已安装 Docker)
# macOS
brew install act

# Linux
curl https://raw.githubusercontent.com/nektos/act/master/install.sh | sudo bash

# 在仓库根目录运行所有 Workflow
act

# 只运行指定事件触发的 Workflow
act push

# 只运行指定的 Job
act -j build

При запуске локальных тестов,actОн использует Docker-контейнеры для имитации среды выполнения GitHub, но некоторые Actions (такие какactions/cache) могут вести себя иначе при локальной имитации по сравнению с реальной средой. Окончательные результаты зависят от того, что фактически выполняется на GitHub.


Типичные проблемы и примечания

1. Проблема с разрешениями (Permission denied)

Если Workflow нужно отправить код в репозиторий или работать с Issues, необходимо явно объявить разрешения в файле конфигурации:

Пример

# Задайте разрешения на верхнем уровне Workflow или на уровне Job
разрешения
:
  contents
: write       # Разрешает чтение/запись содержимого репозитория (код, файлы)
  issues
: write         # Разрешает создание и изменение Issues
  pull-requests
: write  # Разрешает операции с Pull Requests

# Принцип наименьших привилегий: предоставляйте только фактически необходимые разрешения, остальные по умолчанию read или none

2. Как избежать циклических срабатываний Workflow

Если Workflow автоматически отправляет код в репозиторий, это может вызвать новое событие push, что приведёт к бесконечному циклу. Решение: в сообщении автоматического коммита добавьте[skip ci]ключевое слово, и GitHub пропустит срабатывание Workflow для этого коммита:

git commit -m "自动格式化代码 [skip ci]"

3. Экранирование специальных символов в YAML

ВrunВ Shell-команде поля используйте${{ }}выражение, если выражение содержит двоеточие (:) и другие специальные символы YAML, нужно заключить всё значение в кавычки или вместо этого сначала присвоить его переменной окружения, а затем использовать переменную окружения:

Пример

span style="color: #0053A6;">
steps:
 # Не рекомендуется: прямое встраивание сложных команд в выражения ${{ }} может вызвать ошибки синтаксического анализа YAML.
  - run
: echo ${{ github.event.pull_request.title }}

  # Рекомендуется: сначала присвоить значение переменной окружения, затем использовать переменную окружения в Shell
  - name
: Вывести заголовок PR
    env
:
      PR_TITLE
: ${{ github.event.pull_request.title }}
    run
: echo "Заголовок PR: $PR_TITLE"

Для получения более полной документации, пожалуйста, обратитесь к официальной документации:https://docs.github.com/zh/actions

Другие расширения