Перейти к основному содержимому

Лабораторная работа №9. Использование GitHub Actions для CI/CD в .NET

Лабораторная работа: Введение в GitHub Actions для C# проектов

Цели работы

  1. Освоить основы GitHub Actions и научиться применять его для автоматизации процессов CI/CD в проектах на C#.
  2. Научиться создавать файлы конфигурации YAML для автоматизации сборки, тестирования и анализа кода C# приложений.
  3. Изучить различные подходы к организации пайплайнов с последовательным, параллельным и комбинированным выполнением задач.

Теоретическая часть: Подробное введение в GitHub Actions для C# проектов

1. Что такое GitHub Actions?

GitHub Actions — это встроенная в GitHub платформа для автоматизации рабочих процессов. Она позволяет создавать сценарии для выполнения автоматических действий при каждом изменении в репозитории, будь то push, pull request или даже создание тега. С помощью GitHub Actions можно построить CI/CD пайплайн для автоматизации процессов интеграции и развертывания, что делает работу с кодом более надёжной и быстрой.

Основные преимущества GitHub Actions:

  • Простота использования: конфигурационные файлы легко создаются и поддерживаются.
  • Гибкость: GitHub Actions позволяет запускать рабочие процессы на различных операционных системах и версиях платформ.
  • Интеграция с GitHub: GitHub Actions тесно связан с самим репозиторием, что упрощает взаимодействие с его содержимым, доступ к переменным окружения и настройку разрешений.
  • Масштабируемость: GitHub Actions позволяет создавать пайплайны разной сложности — от простой сборки до сложных развертываний с несколькими этапами.

Применение GitHub Actions в CI/CD (Continuous Integration / Continuous Deployment) помогает автоматизировать рутинные задачи и повышает надёжность выпускаемых приложений.

2. Что такое YAML?

YAML (YAML Ain't Markup Language) — это формат данных, который позволяет записывать структурированные данные в удобочитаемом виде. YAML используется для написания конфигурационных файлов в GitHub Actions. Основное его преимущество — простота и гибкость. В отличие от JSON или XML, YAML использует отступы и визуально легко воспринимается, что делает его подходящим для описания сложных структур данных.

Основные принципы YAML:

  • Структура через отступы: данные организуются в виде отступов, что позволяет создавать вложенные структуры.
  • Ключ-значение: пары ключ-значение отделяются двоеточием (:).
  • Списки: элементы списка отмечаются дефисом (-) перед каждым элементом.
  • Комментарии: добавляются через символ #.

Пример YAML-файла:

name: Sample Workflow
on: [push] # Событие, при котором запускается workflow
jobs:
build:
runs-on: ubuntu-latest # Платформа для запуска задачи
steps:
- name: Checkout code
uses: actions/checkout@v4

3. Основные компоненты GitHub Actions

3.1 Workflow (Рабочий процесс)

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

Структура workflow:

  • Имя workflow: поле name (опционально), которое служит для обозначения рабочего процесса.
  • Триггеры запуска (on): определяют события, при которых запускается workflow, например, push, pull_request, schedule (для расписания).
  • Jobs (Задачи): основной набор действий, который выполняется в рамках workflow.

Пример простого workflow:

name: Build and Test Workflow

on: [push, pull_request]

jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '6.0.x'
- name: Build
run: dotnet build src/YourProject.csproj

3.2 Jobs (Задачи)

Job — это набор steps (шагов), которые выполняются в рамках одного окружения. Каждый job может выполняться на разных платформах и может содержать команды, действия или даже сценарии. В GitHub Actions можно создавать несколько jobs в одном workflow, которые выполняются как последовательно, так и параллельно.

Основные параметры для jobs:

  • runs-on: платформа, на которой будет выполняться задача (например, ubuntu-latest, windows-latest, macos-latest).
  • steps: описание шагов, которые нужно выполнить.

Пример job:

build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '6.0.x'
- name: Build project
run: dotnet build src/YourProject.csproj

3.3 Steps (Шаги)

Step — это действие, выполняемое внутри задачи (job). Шаг может быть командой в командной строке, командой, записанной непосредственно в YAML, или встроенным действием. Шаги выполняются последовательно в рамках одного job.

Типы шагов:

  • Команда: выполняется напрямую в рамках job (например, run: dotnet build).
  • Действие (Action): шаг, использующий готовое действие из GitHub Marketplace (например, uses: actions/checkout@v4).

Пример steps:

steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '6.0.x'
- name: Build project
run: dotnet build src/YourProject.csproj

3.4 Actions (Действия)

Action — это единица, которая позволяет выполнить определённое действие в рамках GitHub Actions. Существуют как встроенные действия, разработанные GitHub, так и действия, опубликованные сообществом. Действия могут устанавливаться из GitHub Marketplace или создаваться и использоваться локально.

Примеры популярных действий:

  • actions/checkout: для загрузки кода из репозитория.
  • actions/setup-dotnet: для установки .NET SDK.

4. Типы выполнения пайплайнов

GitHub Actions поддерживает несколько типов выполнения задач. Выбор подходящего типа выполнения зависит от структуры проекта и требований к CI/CD.

4.1 Последовательное выполнение

Последовательное выполнение — это выполнение задач одна за другой. В таких случаях следующая задача запускается только после завершения предыдущей. Этот тип подходит для задач, которые зависят друг от друга, например, сборка и тестирование (тестирование невозможно, если сборка не завершена).

Пример последовательного выполнения:

name: Sequential Workflow

on: [push]

jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '6.0.x'
- name: Build project
run: dotnet build src/YourProject.csproj

test:
needs: build
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Run tests
run: dotnet test src/YourProject.Tests.csproj

В данном примере test зависит от завершения build и выполняется только после него, что задаётся ключевым словом needs.

4.2 Параллельное выполнение

При параллельном выполнении задачи запускаются одновременно. Это удобно для одновременного выполнения различных видов тестирования или проверки кода в разных конфигурациях.

Пример параллельного выполнения:

name: Parallel Workflow

on: [push]

jobs:
build-debug:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '6.0.x'
- name: Build Debug
run: dotnet build src/YourProject.csproj --configuration Debug

build-release:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '6.0.x'
- name: Build Release
run: dotnet build src/YourProject.csproj --configuration Release

build-debug и build-release выполняются параллельно и проверяют разные конфигурации (Debug и Release).

4.3 Комбинированное выполнение

Комбинированное выполнение сочетает последовательные и параллельные задачи. Например, можно сначала собрать проект, а затем запустить параллельно тесты и анализ кода кода. Комбинированное выполнение позволяет создавать более гибкие и эффективные сценарии для CI/CD, где часть задач выполняется последовательно, а часть — параллельно. Этот подход полезен для сложных пайплайнов, где важно обеспечить определённые зависимости между задачами.

Пример комбинированного выполнения:

name: Combined Workflow

on: [push]

jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '6.0.x'
- name: Build project
run: dotnet build src/YourProject.csproj

test:
needs: build
runs-on: ubuntu-latest
strategy:
matrix:
configuration: [Debug, Release]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '6.0.x'
- name: Run tests
run: dotnet test src/YourProject.Tests.csproj --configuration ${{ matrix.configuration }}

analyze:
needs: build
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Run code analysis
run: dotnet tool install -g dotnet-format && dotnet format src/YourProject.csproj

В этом примере:

  • Сначала выполняется задача build (сборка).
  • После её завершения параллельно запускаются задачи test и analyze.
  • test выполняется на двух конфигурациях (Debug и Release) с помощью matrix, что позволяет одновременно протестировать разные настройки.

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

5. Как настроить workflow в GitHub Actions

Создание workflow с нуля

Чтобы создать workflow с нуля:

  1. В корне репозитория создайте папку .github/workflows.
  2. В этой папке создайте файл конфигурации с расширением .yml (например, ci.yml).
  3. Опишите workflow с использованием YAML.

События для запуска workflow

GitHub Actions позволяет настраивать автоматический запуск workflow на основе различных событий:

  • push: запускается при каждом коммите в репозиторий.
  • pull_request: запускается при открытии, обновлении или закрытии pull request.
  • schedule: запускается по расписанию, например, каждый день или каждую неделю, используя синтаксис cron.
  • workflow_dispatch: позволяет вручную запускать workflow с GitHub UI.

Пример с различными событиями:

on:
push:
branches:
- main
pull_request:
branches:
- main
schedule:
- cron: '0 0 * * 1' # Запуск каждую неделю в понедельник

Переменные и секреты в GitHub Actions

GitHub Actions позволяет использовать переменные окружения и секреты для управления конфиденциальной информацией, например, токенами и паролями.

  • Переменные окружения можно объявить прямо в YAML, используя ключ env:

    jobs:
    build:
    runs-on: ubuntu-latest
    env:
    ENVIRONMENT: production
    steps:
    - name: Print environment
    run: echo "Environment is $ENVIRONMENT"
  • Секреты (secrets) можно задавать в настройках репозитория на GitHub и использовать в workflow:

    jobs:
    deploy:
    runs-on: ubuntu-latest
    steps:
    - name: Deploy to server
    env:
    API_TOKEN: ${{ secrets.API_TOKEN }}
    run: curl -X POST -H "Authorization: Bearer $API_TOKEN" https://api.example.com/deploy

6. Практические сценарии применения GitHub Actions

  1. Сборка и тестирование: Автоматизация сборки и тестирования проекта при каждом коммите или pull request позволяет оперативно находить ошибки.
  2. Анализ кода: Инструменты анализа кода (линтеры и форматтеры) помогают поддерживать единый стиль кода и следить за его качеством.
  3. Публикация артефактов: Можно настроить автоматическую публикацию артефактов, таких как сборки или отчёты, для последующего использования или анализа.
  4. Развертывание: GitHub Actions позволяет настроить автоматическое развертывание кода на сервере или облачной платформе после успешного прохождения всех проверок.

Практическая часть

Общее задание

  1. Создайте новый репозиторий на GitHub и добавьте туда простой C# проект (решение содержащее: консольное приложение, библиотеку классов или ASP.NET проект и unit тесты к нему, можно использовать лабораторные по тестированию за прошлый семестр).
  2. Создайте папку .github/workflows и в ней файл ci.yml.
  3. Настройте ci.yml для последовательного выполнения задач:
    • Добавьте задачу для сборки приложения.
    • Добавьте задачу для тестирования, которая зависит от задачи сборки.
  4. Модифицируйте ci.yml для параллельного выполнения:
    • Добавьте параллельное тестирование приложения в различных конфигурациях (Debug и Release).
  5. Создайте комбинированный пайплайн:
    • Настройте задачу для сборки.
    • Добавьте задачи тестирования и анализа кода, которые выполняются параллельно после сборки.

Индивидуальное задание (на высокий балл)

Задание 1: Публикация артефактов с несколькими конфигурациями

Описание: Настройте workflow, который выполняет сборку и тестирование проекта в двух конфигурациях (Debug и Release), а затем сохраняет артефакты сборки для каждой из конфигураций.

Требования:

  1. Workflow должен запускаться при открытии pull request.
  2. Настройте build с матрицей конфигураций (Debug и Release), чтобы сборка выполнялась параллельно для обеих конфигураций.
  3. Сохраните артефакты сборки (исполняемые файлы или библиотеки) в виде отдельных архивов для каждой конфигурации (Debug и Release).
  4. Убедитесь, что оба артефакта доступны для загрузки после успешного выполнения workflow.

Задание 2: Настройка отчёта о покрытии кода и публикация его как артефакта

Описание: Настройте workflow, который выполняет сборку и тестирование проекта, а затем генерирует отчёт о покрытии кода. Опубликуйте отчёт о покрытии в виде артефакта, доступного для загрузки.

Требования:

  1. Workflow должен запускаться при коммите в ветку main.
  2. Настройте задачу build для сборки проекта в конфигурации Release.
  3. Добавьте задачу test, которая запускает тесты с генерацией отчёта о покрытии кода (например, используя coverlet для покрытия в формате cobertura).
  4. Сохраните отчёт о покрытии кода как артефакт с именем code-coverage и сделайте его доступным для загрузки после выполнения workflow.

Вопросы для закрепления материала

  1. Какова цель использования GitHub Actions?
  2. Какую роль выполняют YAML файлы в GitHub Actions?
  3. Чем отличается последовательное выполнение задач от параллельного?
  4. В каких случаях рекомендуется использовать комбинированное выполнение?
  5. Что такое needs в GitHub Actions и для чего оно используется?