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







