Настройка автоматического CI/CD для сборки десктоп-приложения
Десктоп-приложение на Electron, Tauri или Qt — это не веб-сервис: каждый релиз нужно собрать под Windows (x64, arm64), macOS (Intel, Apple Silicon), Linux (deb, rpm, AppImage). Делать это руками — значит тратить полдня на 8–10 сборок, потенциально ошибиться с подписью и вручную публиковать. Типичная ситуация: разработчик запускает сборку на своей Windows-машине, забывает подписать — и пользователи видят SmartScreen. macOS-сборку приходится делать на офисном Mac mini, который занят. Linux — отдельная история с глючными пакетами. Мы настраиваем CI/CD, который берёт эту работу на себя: от lint до публикации релиза и уведомлений в Slack. Ниже — наш типовой пайплайн и практические приёмы, проверенные на десятках проектов.
Почему CI/CD для десктопа — необходимость?
Без автоматизации каждое обновление требует ручного запуска сборщика на каждой ОС. Типичные проблемы: забыли подписать Windows-сборку — SmartScreen блокирует установку; не нотаризовали macOS — Gatekeeper не даст запустить; перепутали версию — пользователи получают старый билд. CI/CD исключает эти риски: одно нажатие на тег — и через 15–20 минут готовы все артефакты с корректной подписью. Экономия времени по сравнению с ручным процессом — до 40% на каждом релизе. Сертификат Apple Developer Program стоит $99/год, а EV Code Signing для Windows — $200–300 в год, но эти расходы окупаются за счёт доверия пользователей.
Как настроить CI/CD для десктоп-приложения за 5 шагов
- Проектирование пайплайна — определяем платформы, инструменты (Electron/Tauri), схему версионирования.
- Получение сертификатов — для Windows (Code Signing), для macOS (Developer ID Application) с последующей настройкой в GitHub Secrets.
- Написание конфигурации GitHub Actions — матричная сборка с кэшированием зависимостей.
- Интеграция подписи и нотаризации — добавление шагов для подписания исполняемых файлов.
- Публикация релиза и автообновление — создание GitHub Release с артефактами, настройка проверки обновлений в приложении.
Архитектура и конфигурация пайплайна
Пайплайн состоит из нескольких параллельных джоб для каждой платформы:
- линтер и юнит-тесты (быстро на ubuntu-latest),
- сборка под Windows (windows-latest) с подписью,
- сборка под macOS (macos-latest) с нотаризацией,
- сборка под Linux (ubuntu-latest),
- публикация артефактов в GitHub Release.
Используем матричную сборку:
name: Build Desktop App
on:
push:
tags:
- 'v*'
workflow_dispatch:
jobs:
build:
strategy:
fail-fast: false
matrix:
include:
- os: windows-latest
platform: win
arch: x64
- os: macos-latest
platform: mac
arch: x64
- os: macos-latest
platform: mac
arch: arm64
- os: ubuntu-22.04
platform: linux
arch: x64
runs-on: ${{ matrix.os }}
name: Build ${{ matrix.platform }}-${{ matrix.arch }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build & package (Electron)
env:
CSC_LINK: ${{ secrets.APPLE_CERT_P12 }}
CSC_KEY_PASSWORD: ${{ secrets.APPLE_CERT_PASSWORD }}
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
WIN_CSC_LINK: ${{ secrets.WIN_CERT_P12 }}
WIN_CSC_KEY_PASSWORD: ${{ secrets.WIN_CERT_PASSWORD }}
run: |
npx electron-builder \
--${{ matrix.platform }} \
--${{ matrix.arch }} \
--publish never
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: dist-${{ matrix.platform }}-${{ matrix.arch }}
path: dist/
retention-days: 7
Как решается проблема подписи кода?
Без подписи Windows показывает SmartScreen, macOS блокирует Gatekeeper. Для Windows используем Code Signing сертификат (EV даёт мгновенную репутацию). Для macOS — Developer ID Application сертификат из Apple Developer Program ($99/год) плюс нотаризация через Apple. Сертификаты хранятся в GitHub Secrets в виде base64-строки. Нотаризация добавляет 1–5 минут к сборке macOS.
Автообновление и версионирование
Для Electron используем electron-updater, который проверяет latest.yml в GitHub Releases при старте. Версия автоматически выставляется из тега:
// main.js
const { autoUpdater } = require('electron-updater');
autoUpdater.setFeedURL({ provider: 'github', owner: 'your-org', repo: 'your-app', private: false });
app.whenReady().then(() => autoUpdater.checkForUpdatesAndNotify());
autoUpdater.on('update-downloaded', () => autoUpdater.quitAndInstall());
Версионирование: при пуше тега v1.2.3 CI проставляет номер в package.json командой npm version $VERSION --no-git-tag-version.
После сборки создаём черновик GitHub Release со всеми артефактами:
publish:
needs: build
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/')
steps:
- uses: actions/download-artifact@v4
with:
path: dist-all/
- uses: softprops/action-gh-release@v2
with:
draft: true
generate_release_notes: true
files: |
dist-all/**/*.exe
dist-all/**/*.dmg
dist-all/**/*.AppImage
dist-all/**/*.deb
dist-all/**/*.rpm
Кэширование зависимостей
node_modules под Electron весит 500+ МБ. Кэш от actions/setup-node с cache: 'npm' сокращает установку с 3–4 минут до 30–60 секунд. Для Tauri дополнительно кэшируем Cargo с помощью Swatinem/rust-cache.
Сравнение этапов: CI/CD vs ручная сборка
| Этап | Ручная сборка | CI/CD автоматизация |
|---|---|---|
| Установка зависимостей | 3–4 мин на каждую ОС | 30–60 сек (с кэшем) |
| Компиляция и упаковка | 5–10 мин на ОС | 8–15 мин параллельно |
| Подпись кода | 1–2 мин на файл | 1–5 мин встроено |
| Загрузка релиза | 2–3 мин ручной заливки | Автоматически 1 мин |
| Проверка обновлений | Отсутствует | Автоматически при старте |
Когда стоит выбрать Tauri вместо Electron?
Tauri (Rust backend) даёт меньший размер приложения и лучшую производительность, но требует знаний Rust. Для него используем официальный tauri-action:
- name: Build Tauri app
uses: tauri-apps/tauri-action@v0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
with:
tagName: ${{ github.ref_name }}
releaseName: 'App v__VERSION__'
releaseBody: 'See CHANGELOG for details'
releaseDraft: true
Пример конфигурации для Tauri в GitHub Actions
name: Build Tauri
on:
push:
tags: ['v*']
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-22.04, windows-latest, macos-latest]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- uses: actions-rust-lang/setup-rust-toolchain@v1
- run: npm install
- run: npx tauri build
- uses: actions/upload-artifact@v4
with:
path: src-tauri/target/release/bundle/
Сравнение ключевых характеристик:
| Характеристика | Electron | Tauri |
|---|---|---|
| Размер приложения | ~150–200 МБ | ~5–10 МБ |
| Время сборки (с кэшем) | 4–8 мин | 8–15 мин |
| Сложность настройки CI | Низкая | Средняя |
| Требуемые навыки | JavaScript/Node.js | Rust + JavaScript |
На практике Electron проще в настройке CI/CD в 2 раза быстрее, чем Tauri, если команда не владеет Rust.
Что входит в работу?
При настройке CI/CD мы предоставляем:
- Документацию пайплайна с описанием всех шагов
- Конфигурации для Windows, macOS и Linux
- Настройку подписи кода (сертификаты и секреты)
- Интеграцию автообновления
- Инструкцию по публикации релизов
- Неделю поддержки после внедрения
Мы — команда с 7+ годами опыта в DevOps и десктоп-разработке. За время работы настроили CI/CD для 50+ проектов, включая Electron и Tauri. Гарантируем корректную подпись и нотаризацию. Если хотите автоматизировать сборку десктоп-приложения — свяжитесь с нами для консультации. Настроим пайплайн под ключ за 1–2 дня, включая подпись и автоматическое обновление. Получите оценку вашего проекта — пишите в удобный мессенджер.
Документация GitHub Actions: https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions







