name: Release desktop installers on: push: tags: - 'v*' permissions: contents: write jobs: macos: name: build (mac-${{ matrix.artifact_arch }}, Tauri) timeout-minutes: 60 strategy: fail-fast: false matrix: include: - os: macos-15-intel build_arch: x86_64 artifact_arch: x64 - os: macos-15 build_arch: arm64 artifact_arch: arm64 runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v7 - uses: actions/setup-node@v7 with: node-version: 22.22.0 cache: npm - run: npm ci - run: npm test - run: npm run check:version -- "${GITHUB_REF_NAME}" - name: Configure optional Developer ID certificate shell: bash env: APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }} APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} run: | if [ -z "$APPLE_CERTIFICATE" ]; then echo 'No Developer ID certificate configured; using ad-hoc signing.' echo 'APPLE_SIGNING_IDENTITY=-' >> "$GITHUB_ENV" exit 0 fi : "${APPLE_CERTIFICATE_PASSWORD:?APPLE_CERTIFICATE_PASSWORD is required when APPLE_CERTIFICATE is set}" : "${KEYCHAIN_PASSWORD:?KEYCHAIN_PASSWORD is required when APPLE_CERTIFICATE is set}" certificate_path="$RUNNER_TEMP/developer-id.p12" keychain_path="$RUNNER_TEMP/deepseek-harness-signing.keychain-db" printf '%s' "$APPLE_CERTIFICATE" | base64 --decode > "$certificate_path" security create-keychain -p "$KEYCHAIN_PASSWORD" "$keychain_path" security set-keychain-settings -lut 21600 "$keychain_path" security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$keychain_path" security import "$certificate_path" -P "$APPLE_CERTIFICATE_PASSWORD" \ -A -t cert -f pkcs12 -k "$keychain_path" security list-keychain -d user -s "$keychain_path" security set-key-partition-list -S apple-tool:,apple:,codesign: \ -s -k "$KEYCHAIN_PASSWORD" "$keychain_path" identity="$(security find-identity -v -p codesigning "$keychain_path" | \ sed -nE 's/.*"(Developer ID Application: [^"]+)".*/\1/p' | head -1)" test -n "$identity" echo "APPLE_SIGNING_IDENTITY=$identity" >> "$GITHUB_ENV" - name: Package Tauri application shell: bash env: APPLE_ID: ${{ secrets.APPLE_ID }} APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }} APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} run: scripts/build-tauri.sh "${{ matrix.build_arch }}" - name: Verify packaged Tauri runtime run: npm run verify:tauri - name: Enforce Tauri release size budget run: npm run check:release-size -- --platform mac - name: Verify macOS signature shell: bash run: | app='release/DeepSeek Harness Desktop.app' cmp build/icon.icns "$app/Contents/Resources/icon.icns" codesign --verify --deep --strict --verbose=4 "$app" codesign -dvv "$app" 2>&1 | grep -E 'flags=.*runtime' codesign -dvv "$app/Contents/MacOS/node" 2>&1 | grep -E 'flags=.*runtime' codesign -dvv "$app/Contents/MacOS/dsh" 2>&1 | grep -E 'flags=.*runtime' codesign -dvv "$app/Contents/MacOS/pnpm" 2>&1 | grep -E 'flags=.*runtime' if [[ "${APPLE_SIGNING_IDENTITY:-}" == "Developer ID Application:"* ]]; then xcrun stapler validate "$app" spctl --assess --type execute --verbose=4 "$app" else codesign -dvv "$app" 2>&1 | grep -F 'Signature=adhoc' fi - uses: actions/upload-artifact@v7 with: name: installers-mac-${{ matrix.artifact_arch }} path: | release/DeepSeek-Harness-Desktop-*-mac-${{ matrix.artifact_arch }}.dmg release/DeepSeek-Harness-Desktop-*-mac-${{ matrix.artifact_arch }}.zip if-no-files-found: error windows: name: build (win-x64, Electron) timeout-minutes: 45 runs-on: windows-2025 steps: - uses: actions/checkout@v7 - uses: actions/setup-node@v7 with: node-version: 22.22.0 cache: npm - run: npm ci - run: npm test - run: npm run check:version -- "${env:GITHUB_REF_NAME}" - name: Package Electron application run: npm run dist -- --win --x64 --publish never - name: Verify packaged Harness runtime run: npm run verify:packaged - name: Enforce release size budget run: npm run check:release-size -- --platform win - uses: actions/upload-artifact@v7 with: name: installers-win-x64 path: | release/*.exe release/*.zip if-no-files-found: error publish: name: publish release needs: [macos, windows] runs-on: ubuntu-latest timeout-minutes: 10 steps: - uses: actions/download-artifact@v8 with: pattern: installers-* path: installers merge-multiple: true - name: Create GitHub release env: GH_TOKEN: ${{ github.token }} shell: bash run: | cd installers sha256sum * > SHA256SUMS.txt gh release create "${GITHUB_REF_NAME}" * \ --repo "${GITHUB_REPOSITORY}" \ --verify-tag \ --generate-notes \ --title "DeepSeek Harness Desktop ${GITHUB_REF_NAME}"