Налаштування автоматичного 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







