name: Publish Desktop Artifacts to Release on: workflow_dispatch: inputs: tag: description: "Existing release tag to attach artifacts to (e.g. v0.6.5)" required: true release: types: [published] permissions: contents: write concurrency: group: desktop-release-${{ github.event.release.tag_name || github.event.inputs.tag || github.ref }} cancel-in-progress: false jobs: desktop: name: Desktop (${{ matrix.label }}) runs-on: ${{ matrix.runner }} strategy: fail-fast: false matrix: include: - label: macOS arm64 runner: macos-14 target_os: darwin target_arch: arm64 electron_target: "--mac dmg zip --arm64" artifact_files: | packages/desktop/release/*.dmg packages/desktop/release/*.dmg.blockmap packages/desktop/release/*.zip packages/desktop/release/*.zip.blockmap - label: macOS x64 runner: macos-15-intel target_os: darwin target_arch: x64 electron_target: "--mac dmg zip --x64" artifact_files: | packages/desktop/release/*.dmg packages/desktop/release/*.dmg.blockmap packages/desktop/release/*.zip packages/desktop/release/*.zip.blockmap - label: Windows x64 runner: windows-latest target_os: win32 target_arch: x64 electron_target: "--win nsis --x64" artifact_files: | packages/desktop/release/*.exe packages/desktop/release/*.exe.blockmap packages/desktop/release/latest*.yml - label: Linux x64 runner: ubuntu-22.04 target_os: linux target_arch: x64 electron_target: "--linux AppImage deb --x64" artifact_files: | packages/desktop/release/*.AppImage packages/desktop/release/*.deb packages/desktop/release/latest*.yml - label: Linux arm64 runner: ubuntu-22.04-arm target_os: linux target_arch: arm64 electron_target: "--linux AppImage --arm64" artifact_files: | packages/desktop/release/*.AppImage packages/desktop/release/latest*.yml steps: - name: Checkout repository uses: actions/checkout@v4 with: ref: ${{ github.event.release.tag_name || github.event.inputs.tag }} - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: 24 cache: npm cache-dependency-path: | package-lock.json packages/desktop/package-lock.json - name: Install uv uses: astral-sh/setup-uv@v3 - name: Install web UI dependencies run: | npm ci --ignore-scripts npm rebuild node-pty - name: Build web UI run: npm run build - name: Keep production web UI dependencies only run: npm prune --omit=dev --no-audit --no-fund - name: Install desktop dependencies run: npm ci --prefix packages/desktop --no-audit --no-fund - name: Prepare bundled Python env: TARGET_OS: ${{ matrix.target_os }} TARGET_ARCH: ${{ matrix.target_arch }} run: npm --prefix packages/desktop run prepare:python - name: Configure macOS signing if: matrix.target_os == 'darwin' shell: bash env: MAC_CSC_LINK: ${{ secrets.MAC_CSC_LINK }} MAC_CSC_KEY_PASSWORD: ${{ secrets.MAC_CSC_KEY_PASSWORD }} MAC_APPLE_ID: ${{ secrets.APPLE_ID }} MAC_APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }} MAC_APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} run: | write_env() { local name="$1" local value="$2" if [ -n "$value" ]; then { echo "$name<> "$GITHUB_ENV" fi } if [ -z "${MAC_CSC_LINK:-}" ]; then echo "CSC_IDENTITY_AUTO_DISCOVERY=false" >> "$GITHUB_ENV" echo "MAC_BUILD_EXTRA_ARGS=--config.mac.notarize=false" >> "$GITHUB_ENV" echo "No macOS signing certificate configured; building unsigned and skipping notarization." exit 0 fi write_env "CSC_LINK" "$MAC_CSC_LINK" write_env "CSC_KEY_PASSWORD" "$MAC_CSC_KEY_PASSWORD" if [ -n "${MAC_APPLE_ID:-}" ] && [ -n "${MAC_APPLE_APP_SPECIFIC_PASSWORD:-}" ] && [ -n "${MAC_APPLE_TEAM_ID:-}" ]; then write_env "APPLE_ID" "$MAC_APPLE_ID" write_env "APPLE_APP_SPECIFIC_PASSWORD" "$MAC_APPLE_APP_SPECIFIC_PASSWORD" write_env "APPLE_TEAM_ID" "$MAC_APPLE_TEAM_ID" echo "macOS signing and notarization are configured." else echo "MAC_BUILD_EXTRA_ARGS=--config.mac.notarize=false" >> "$GITHUB_ENV" echo "macOS signing certificate configured; Apple notarization credentials incomplete, skipping notarization." fi - name: Build desktop artifact shell: bash run: npm --prefix packages/desktop run dist -- ${{ matrix.electron_target }} ${MAC_BUILD_EXTRA_ARGS:-} --publish never - name: Upload macOS update manifest artifact if: matrix.target_os == 'darwin' uses: actions/upload-artifact@v4 with: name: latest-mac-${{ matrix.target_arch }} path: packages/desktop/release/latest-mac.yml if-no-files-found: error retention-days: 1 - name: Upload artifacts to release uses: softprops/action-gh-release@v2 with: tag_name: ${{ github.event.release.tag_name || github.event.inputs.tag }} fail_on_unmatched_files: true files: ${{ matrix.artifact_files }} mac-update-manifest: name: Merge macOS updater manifest needs: desktop runs-on: ubuntu-22.04 steps: - name: Checkout repository uses: actions/checkout@v4 with: ref: ${{ github.event.release.tag_name || github.event.inputs.tag }} - name: Download macOS update manifests uses: actions/download-artifact@v4 with: pattern: latest-mac-* path: /tmp/hermes-mac-manifests merge-multiple: false - name: Merge macOS update manifests shell: bash run: | node packages/desktop/scripts/merge-mac-latest-yml.mjs \ /tmp/hermes-mac-manifests/latest-mac-arm64/latest-mac.yml \ /tmp/hermes-mac-manifests/latest-mac-x64/latest-mac.yml \ > /tmp/latest-mac.yml - name: Upload merged macOS updater manifest to release uses: softprops/action-gh-release@v2 with: tag_name: ${{ github.event.release.tag_name || github.event.inputs.tag }} fail_on_unmatched_files: true files: /tmp/latest-mac.yml