Skip to content

6.2 Packaging and Release

coding man edited this page Nov 4, 2026 · 1 revision

Packaging and Release

Relevant source files

The following files were used as context for generating this wiki page:

This page documents section 6.2 of the VariantScope wiki, covering the build tooling configuration (electron-builder.yml), asset generation and packaging, macOS ad-hoc signing, and the GitHub Actions release workflow (release.yml) which drafts, builds, publishes installers, and computes cryptographic checksums.


1. Overview and Scope

The packaging pipeline bridges development outputs (dist/electron-renderer and electron/) to platform-specific installers (.dmg, .exe, .AppImage, and .deb) using electron-builder.

The core responsibilities of this layer include:

"Natural Language Space" -> "Code Entity Space" Architecture Mapping:

+---------------------------+       +---------------------------------------------+
| Concept / System Name     |       | Code Entity (File / Script / Config)        |
+---------------------------+       +---------------------------------------------+
| Electron Builder Config   | ----> | electron-builder.yml                        |
| macOS Ad-Hoc Sign Hook    | ----> | scripts/adhoc-sign.cjs                      |
| Icon Generation Pipeline  | ----> | scripts/make-icons.mjs, render-icon.cjs     |
| Command Timeout Wrapper   | ----> | scripts/with-timeout.mjs                    |
| Publishing Instructions   | ----> | docs/PUBLISHING.md                          |
+---------------------------+       +---------------------------------------------+

Sources: electron-builder.yml, scripts/adhoc-sign.cjs, scripts/make-icons.mjs, docs/PUBLISHING.md


2. Electron Builder Configuration

The electron-builder.yml file configures application packaging, targeting metadata, ASAR packaging, and publishing channels electron-builder.yml:1-29.

Key Configuration Elements

  • App Metadata: appId (com.reeper316099.variantscope), productName (VariantScope), and copyright notices.
  • Directories: Outputs go to the release/ directory; build resources pull from build/ electron-builder.yml:6-9.
  • Included Files: Only production assets are packaged. The renderer bundle (dist/electron-renderer), main process (electron/), build icons, and package.json are included electron-builder.yml:12-16. Source node modules are excluded because Vite pre-bundles dependencies.
  • ASAR Archival: asar: true packs internal script files into an encrypted-format archive.
  • Artifact Naming: Standardizes output names using ${productName}-${version}-${os}-${arch}.${ext} electron-builder.yml:20.
graph TD
    A["Vite Build Output: dist/electron-renderer"] -->|Included| C["electron-builder"]
    B["Electron Main: electron/"] -->|Included| C
    D["Build Assets: build/icon.png"] -->|Included| C
    C -->|ASAR Archive| E["release/ Installer Artifacts"]
    E --> F["macOS: .dmg"]
    E --> G["Windows: .exe (NSIS & Portable)"]
    E --> H["Linux: .AppImage & .deb"]

    classDef default stroke:#000,fill:none;
Loading

Sources: electron-builder.yml


3. Platform Targets and Asset Pipeline

electron-builder.yml defines platform-specific distribution formats:

Target Matrix

Asset Icons & Rendering

Icons are derived from vector sources via scripts/make-icons.mjs and scripts/render-icon.cjs:

  1. render-icon.cjs spins up a hidden headless Electron BrowserWindow (show: false, offscreen: true) to rasterize build/icon.svg into a clean 1024x1024 transparent PNG scripts/render-icon.cjs:1-28.
  2. make-icons.mjs consumes this master PNG, uses macOS utility sips to build multi-resolution iconsets, packages Apple .icns via iconutil, and constructs multi-image Windows .ico buffers scripts/make-icons.mjs:1-61.
sequenceDiagram
    participant User as Developer / CI
    participant Script as make-icons.mjs
    participant Renderer as render-icon.cjs
    participant Electron as Headless BrowserWindow
    
    User->>Script: npm run make-icons
    Script->>Renderer: Spawns electron with render-icon.cjs
    Renderer->>Electron: Loads build/icon.svg via data URI
    Electron->>Renderer: Captures page contents (webContents.capturePage)
    Renderer->>Script: Writes build/icon.png (1024x1024)
    Script->>Script: Resizes via sips and builds icon.iconset
    Script->>Script: Packs build/icon.icns and build/icon.ico
Loading

Sources: build/icon.ico, build/icon.icns, scripts/render-icon.cjs, scripts/make-icons.mjs


4. macOS Ad-Hoc Signing Hook

Because macOS Silicon enforces code-signature validity for executable bundles, modifying files inside an Electron application bundle after initial compilation causes operating systems to flag the application as damaged.

VariantScope implements an afterPack hook in scripts/adhoc-sign.cjs to sign builds locally or in CI without requiring an Apple Developer ID certificate scripts/adhoc-sign.cjs:1-17.

Implementation Details

  • Platform Guard: Exits immediately if context.electronPlatformName !== 'darwin' scripts/adhoc-sign.cjs:10.
  • Extended Attribute Clearing: Executes xattr -cr on the .app bundle to strip quarantine and provenance attributes (com.apple.provenance) that interfere with code signing utilities scripts/adhoc-sign.cjs:13-14.
  • Ad-Hoc Code Signing: Forces a deep ad-hoc signature via codesign --force --deep --sign - scripts/adhoc-sign.cjs:15.
  • Verification: Executes codesign --verify strictly; failure in verification immediately fails the build pipeline scripts/adhoc-sign.cjs:16.
graph TD
    A["electron-builder afterPack Hook"] --> B{"Is macOS Target?"}
    B -- "No" --> C["Skip (Windows/Linux)"]
    B -- "Yes" --> D["Run xattr -cr to clear extended attributes"]
    D --> E["Run codesign --force --deep --sign -"]
    E --> F["Run codesign --verify --deep --strict"]
    F -->|Failure| G["Abort Build"]
    F -->|Success| H["Continue Packaging DMG"]

    classDef default stroke:#000,fill:none;
Loading

Sources: scripts/adhoc-sign.cjs


5. Release Workflow and Checksums

Releases are managed via tag pushes (v*) which trigger GitHub Actions workflows to assemble draft packages, upload compiled platform artifacts, calculate SHA256 checksums, and publish the final release description docs/PUBLISHING.md:1-105.

Workflow Stages

  1. Draft Job: Creates a draft GitHub release associated with the pushed version tag.
  2. Build Matrix Job: Runs parallel builds across macOS, Windows, and Linux runners to generate installers.
  3. Publish and Checksum Job: Collects all installer assets, generates a SHA256SUMS.txt manifest, flips the release state from draft to published, and attaches all binaries.

Release Verification Steps

Releases can be verified locally using standard hashing utilities against the published checksum manifest:

sha256sum --check SHA256SUMS.txt

Sources: docs/PUBLISHING.md


Clone this wiki locally