CI/CD для Rust проектов: настройка GitHub Actions

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Введение: почему CI/CD важен для Rust-проектов?

Разработка на Rust — это не только написание безопасного и быстрого кода, но и обеспечение его стабильности в долгосрочной перспективе. CI/CD (Continuous Integration / Continuous Deployment) — это практика, которая автоматизирует сборку, тестирование и развёртывание вашего проекта. Для Rust, с его строгим компилятором и системой типов, CI/CD особенно полезен: он позволяет ловить ошибки на ранних стадиях, проверять совместимость зависимостей и автоматически публиковать новые версии.

GitHub Actions — это встроенный инструмент CI/CD на платформе GitHub. Он предоставляет готовые шаблоны для Rust, мощные матрицы тестирования и возможность интеграции с любыми облачными сервисами. В этой статье мы разберём, как настроить полноценный пайплайн для Rust-проекта: от базовой проверки до публикации на crates.io.

1. Основы: создание первого workflow для Rust

Workflow в GitHub Actions — это YAML-файл, который описывает последовательность шагов. Для Rust-проекта минимальный workflow должен включать: установку Rust, загрузку зависимостей, сборку и запуск тестов.

Создайте файл .github/workflows/ci.yml в корне вашего репозитория:

name: Rust CI

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

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v4
    - name: Setup Rust
      uses: actions-rs/toolchain@v1
      with:
        toolchain: stable
        override: true
        components: clippy, rustfmt
    - name: Cache dependencies
      uses: actions/cache@v3
      with:
        path: |
          ~/.cargo/registry
          ~/.cargo/git
          target
        key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
    - name: Build
      run: cargo build --verbose
    - name: Run tests
      run: cargo test --verbose
    - name: Lint with Clippy
      run: cargo clippy -- -D warnings
    - name: Check formatting
      run: cargo fmt --check

Этот workflow запускается при каждом push в основную ветку или при создании pull request. Кэширование зависимостей (actions/cache) значительно ускоряет последующие запуски. Обратите внимание на флаг -- -D warnings в clippy — он превращает предупреждения в ошибки, что повышает качество кода.

1.1. Matrix-тестирование: проверка на нескольких версиях Rust

Rust имеет три основных канала релизов: stable, beta и nightly. Чтобы убедиться, что ваш код работает на всех версиях, используйте матрицу стратегий:

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        rust: [stable, beta, nightly]
    steps:
    - uses: actions/checkout@v4
    - name: Setup Rust ${{ matrix.rust }}
      uses: actions-rs/toolchain@v1
      with:
        toolchain: ${{ matrix.rust }}
        override: true
    - name: Build and test
      run: |
        cargo build
        cargo test

Добавьте также проверку на минимальную поддерживаемую версию Rust (MSRV). Это особенно важно для библиотек. Например, если ваш Cargo.toml указывает rust-version = "1.60", добавьте в матрицу rust: [1.60.0, stable].

2. Продвинутые техники: оптимизация и безопасность

2.1. Кэширование с учётом профилей

По умолчанию cargo build использует профиль debug. Для release-сборок кэш будет другим. Разделите кэш для разных профилей:

- name: Cache dependencies
  uses: actions/cache@v3
  with:
    path: |
      ~/.cargo/registry
      ~/.cargo/git
      target
    key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}-${{ matrix.rust }}-${{ matrix.profile }}
  env:
    CARGO_TERM_COLOR: always

В матрицу добавьте profile: [debug, release].

2.2. Проверка безопасности зависимостей

Используйте cargo audit для поиска уязвимостей в зависимостях. Установите его как дополнительный шаг:

- name: Install cargo-audit
  run: cargo install cargo-audit
- name: Security audit
  run: cargo audit

Для экономии времени можно использовать готовый action: actions-rs/audit-check@v1. Он автоматически проверяет уязвимости и сообщает о результатах.

2.3. Генерация документации

Если вы разрабатываете библиотеку, автоматическая генерация документации — хорошая практика. Добавьте шаг для создания документации и её публикации на GitHub Pages:

- name: Build documentation
  run: cargo doc --no-deps
- name: Deploy to GitHub Pages
  uses: peaceiris/actions-gh-pages@v3
  with:
    github_token: ${{ secrets.GITHUB_TOKEN }}
    publish_dir: ./target/doc

Не забудьте включить GitHub Pages в настройках репозитория (ветка gh-pages).

3. Деплой: публикация на crates.io и бинарные релизы

3.1. Автоматическая публикация на crates.io

Чтобы публиковать новую версию библиотеки при создании тега, используйте следующий workflow:

name: Publish to crates.io

on:
  push:
    tags:
      - 'v*'

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
    - name: Setup Rust
      uses: actions-rs/toolchain@v1
      with:
        toolchain: stable
        override: true
    - name: Publish
      run: cargo publish
      env:
        CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}

Для работы этого пайплайна необходимо добавить токен crates.io в секреты репозитория (Settings → Secrets → Actions → New repository secret). Токен можно получить на сайте crates.io в разделе "Account Settings".

3.2. Сборка бинарных артефактов для разных платформ

Если вы создаёте CLI-инструмент, полезно собирать бинарники для Windows, macOS и Linux. Используйте actions-rs/cargo@v1 с матрицей по ОС:

jobs:
  build:
    strategy:
      matrix:
        os: [ubuntu-latest, macos-l                

Блоги

Рекомендаций по книгам