Зависимости задач в GitHub Actions

GitBeginner
Практиковаться сейчас

Введение

В реальных CI/CD пайплайнах рабочие процессы (workflows) редко представляют собой просто единый список шагов. Они часто состоят из нескольких отдельных "задач" (jobs), которые должны выполняться в определенном порядке.

Например, у вас может быть задача Build (Сборка), которая компилирует ваш код, и задача Deploy (Развертывание), которая отправляет его на сервер. Вы определенно не хотите, чтобы задача Deploy запускалась, если задача Build завершилась неудачей, и вы не можете запускать их одновременно, поскольку для развертывания требуются собранные артефакты.

В этой лабораторной работе вы разделите свой рабочий процесс на две отдельные задачи и используете ключевое слово needs для обеспечения зависимости, гарантируя, что задача развертывания будет ждать успешного завершения задачи сборки.

Эта лабораторная работа основана на репозитории, который вы создали в предыдущих лабораторных работах. Вы будете работать с репозиторием github-actions-demo.

Определение задачи сборки (build job)

Сначала мы очистим наш существующий рабочий процесс (workflow), чтобы осталось сфокусированное задание build. Мы упростим стратегию матрицы из предыдущей лабораторной работы для большей ясности, вернувшись к одной версии, чтобы сосредоточиться на зависимостях заданий.

  1. На странице вашего репозитория GitHub для github-actions-demo нажмите зеленую кнопку Code.
  2. Убедитесь, что выбрана вкладка HTTPS, и скопируйте URL. Он должен выглядеть как https://github.com/your-username/github-actions-demo.git.
  3. Откройте терминал в среде LabEx. Путь по умолчанию — ~/project.
  4. Используйте команду git clone для загрузки репозитория. Замените your-username на ваш фактический логин на GitHub.
cd ~/project
git clone https://github.com/your-username/github-actions-demo.git

Пример вывода:

Cloning into 'github-actions-demo'...
remote: Enumerating objects: X, done.
remote: Counting objects: 100% (X/X), done.
remote: Total X (delta 0), reused 0 (delta 0), pack-reused 0
Receiving objects: 100% (X/X), done.
  1. Перейдите в клонированный репозиторий:
cd ~/project/github-actions-demo
  1. Создайте новый файл рабочего процесса .github/workflows/job-dependencies.yml с помощью редактора WebIDE. Вы можете найти этот файл в проводнике файлов слева, в разделе project/github-actions-demo/.github/workflows/.

  2. Начните с создания базовой структуры рабочего процесса. Добавьте имя рабочего процесса и триггер:

name: Job Dependencies

on: [push]
  1. Добавьте секцию заданий (jobs) и определите задание сборки (build) с указанием раннера:
jobs:
  build:
    runs-on: ubuntu-latest
  1. Добавьте секцию шагов (steps). Сначала добавьте шаг checkout для получения кода репозитория:
steps:
  - uses: actions/checkout@v4
  1. Добавьте шаг настройки Node.js:
- name: Use Node.js
  uses: actions/setup-node@v4
  with:
    node-version: "20"
  1. Добавьте шаг для установки зависимостей:
- name: Install dependencies
  run: npm install
  1. Добавьте шаг для запуска тестов:
- name: Run tests
  run: npm test
  1. Добавьте шаг сборки, который создает директорию артефакта и файл:
- name: Build project
  run: |
    mkdir dist
    echo "Build artifact created at $(date)" > dist/build.txt
  1. Наконец, добавьте шаг загрузки артефакта (Upload artifact). Этот шаг имеет решающее значение, поскольку он сохраняет результат сборки, чтобы следующее задание могло его использовать:
- name: Upload build artifact
  uses: actions/upload-artifact@v4
  with:
    name: dist-files
    path: dist

Ваш полный файл теперь должен выглядеть следующим образом:

name: Job Dependencies

on: [push]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Use Node.js
        uses: actions/setup-node@v4
        with:
          node-version: "20"
      - name: Install dependencies
        run: npm install
      - name: Run tests
        run: npm test
      - name: Build project
        run: |
          mkdir dist
          echo "Build artifact created at $(date)" > dist/build.txt
      - name: Upload build artifact
        uses: actions/upload-artifact@v4
        with:
          name: dist-files
          path: dist

Объяснение

  • Мы удалили стратегию matrix для упрощения.
  • Мы сохранили шаг Upload build artifact. Это критически важно, так как эти файлы понадобятся следующему заданию!

Сохраните файл (Ctrl+S или Cmd+S) после внесения изменений.

Определение задачи развертывания (deploy job) с зависимостью от сборки

Теперь мы добавим второе задание с именем deploy. Это задание должно выполняться только в том случае, если build завершилось успешно. Мы достигаем этого с помощью needs: build.

  1. Добавьте следующее задание deploy в ваш файл .github/workflows/job-dependencies.yml. Убедитесь, что оно находится на том же уровне отступа, что и build.

  2. Начните с добавления определения задания развертывания с указанием раннера (runner) и зависимостей:

deploy:
  runs-on: ubuntu-latest
  needs: build

Строка needs: build имеет решающее значение — она сообщает GitHub Actions, что это задание зависит от успешного завершения задания build.

  1. Добавьте секцию шагов (steps). Сначала добавьте шаг для загрузки артефакта:
steps:
  - name: Download artifact
    uses: actions/download-artifact@v4
    with:
      name: dist-files
      path: dist

Это загружает артефакт, который был загружен на шаге build. Параметр name должен совпадать с именем, использованным на шаге загрузки.

  1. Добавьте шаг развертывания:
- name: Deploy project
  run: |
    echo "Deploying project..."
    ls -R dist
    echo "Deployment successful!"

Этот шаг имитирует развертывание путем вывода списка загруженных файлов.

  1. Полная структура вашего файла должна выглядеть следующим образом:
name: Job Dependencies

on: [push]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Use Node.js
        uses: actions/setup-node@v4
        with:
          node-version: "20"
      - name: Install dependencies
        run: npm install
      - name: Run tests
        run: npm test
      - name: Build project
        run: |
          mkdir dist
          echo "Build artifact created at $(date)" > dist/build.txt
      - name: Upload build artifact
        uses: actions/upload-artifact@v4
        with:
          name: dist-files
          path: dist

  deploy:
    runs-on: ubuntu-latest
    needs: build
    steps:
      - name: Download artifact
        uses: actions/download-artifact@v4
        with:
          name: dist-files
          path: dist
      - name: Deploy project
        run: |
          echo "Deploying project..."
          ls -R dist
          echo "Deployment successful!"

Объяснение

  • needs: build: Это ключевая строка. Она сообщает GitHub Actions, что это задание зависит от успешного завершения задания build.
  • uses: actions/download-artifact@v4: Поскольку задания выполняются на разных виртуальных машинах, они не имеют общего файлового пространства. Чтобы получить папку dist, созданную в задании build, мы должны загрузить артефакт, который загрузили ранее.
  • name: dist-files: Должно совпадать с именем, использованным на шаге загрузки.

Сохраните файл (Ctrl+S или Cmd+S).

Зафиксируйте (Commit), отправьте (push) и проверьте последовательное выполнение

Теперь давайте проверим, что задания (jobs) выполняются в правильном порядке.

  1. Убедитесь, что вы находитесь в директории репозитория:
cd ~/project/github-actions-demo
  1. Добавьте изменения в индекс (Stage the changes):
git add .
  1. Зафиксируйте изменения (Commit the changes):
git commit -m "Add deploy job with dependency on build"
  1. Отправьте изменения в удаленный репозиторий на GitHub:
git push

Примечание об аутентификации:
Когда вы выполните команду git push, WebIDE автоматически предложит вам пройти аутентификацию. Следуйте этим подробным шагам:

  1. Появится всплывающее окно с сообщением: "The extension 'GitHub' wants to sign in using GitHub." Нажмите Allow.
  2. Появится новое уведомление. Нажмите "Copy&Continue to GitHub", затем нажмите "Open" в следующем запросе.
  3. Войдите в свою учетную запись GitHub в открывшемся окне браузера и введите скопированный код авторизации. После подтверждения авторизации страница закроется автоматически.
  4. Подождите несколько секунд, и вы увидите, как терминал успешно завершит операцию пуша.

Примечание о конфиденциальности: WebIDE запросит полный доступ к вашей учетной записи GitHub для целей аутентификации. Вам не нужно беспокоиться о проблемах конфиденциальности — виртуальная машина LabEx будет немедленно уничтожена после завершения текущей лабораторной работы, и ваши учетные данные и информация об авторизации не будут сохранены.

Этот процесс аутентификации не требует ручной настройки имени пользователя или Personal Access Token.

Проверка на GitHub

  1. Посетите ваш репозиторий на GitHub в веб-браузере.
  2. Нажмите на вкладку Actions.
  3. Нажмите на последний запуск рабочего процесса (workflow run).
  4. Посмотрите на визуализационный граф. Вы должны увидеть два круга (задания/jobs), соединенных линией.
    • Задание build будет слева.
    • Задание deploy будет справа.
  5. Наблюдайте за прогрессом. Вы заметите, что deploy остается в состоянии "Pending" или "Waiting", пока build не станет зеленым (Success).
  6. Как только build завершится, начнется deploy.
  7. Нажмите на логи задания deploy, чтобы увидеть сообщение "Deploying project..." и список файлов загруженного артефакта.
GitHub Actions job dependencies

Резюме

В этой лабораторной работе вы узнали, как оркестрировать рабочие процессы с несколькими задачами (multi-job workflows) в GitHub Actions. Вы:

  1. Создали отдельные задачи build и deploy.
  2. Использовали ключевое слово needs для определения зависимости, гарантируя, что deploy запускается только после build.
  3. Использовали upload-artifact и download-artifact для передачи данных (файлов) между этими отдельными задачами.

Этот шаблон является основополагающим для построения надежных CI/CD конвейеров, где вы хотите выполнить сборку один раз, а затем развернуть ее в нескольких средах (staging, production) только в том случае, если предыдущие шаги были успешными.