Package AutoSubs for MacOS and Linux #1190
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Package AutoSubs for MacOS and Linux | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| tag: | |
| description: 'Release tag to build for' | |
| required: true | |
| type: string | |
| permissions: | |
| contents: write | |
| env: | |
| # Resolve tag for both release-triggered and manual runs | |
| TAG: ${{ github.event.release.tag_name || inputs.tag }} | |
| jobs: | |
| build-mac: | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - platform: macos-15 | |
| arch: arm64 | |
| target: aarch64-apple-darwin | |
| features: mac-aarch | |
| pkg_suffix: ARM | |
| - platform: macos-15-intel | |
| arch: x86_64 | |
| target: x86_64-apple-darwin | |
| features: mac-x86_64 | |
| pkg_suffix: Intel | |
| runs-on: ${{ matrix.platform }} | |
| steps: | |
| - name: Checkout AutoSubs Repo Code | |
| uses: actions/checkout@v4 | |
| - name: Ensure TAG is set | |
| run: | | |
| if [ -z "${TAG}" ]; then | |
| echo "ERROR: TAG is empty. Trigger this workflow from a Release event or provide the 'tag' input when using workflow_dispatch." | |
| exit 1 | |
| fi | |
| - name: Use Xcode 16.4 (ARM only) | |
| if: matrix.arch == 'arm64' | |
| run: | | |
| sudo xcode-select -s /Applications/Xcode_16.4.app | |
| echo "DEVELOPER_DIR=/Applications/Xcode_16.4.app/Contents/Developer" >> $GITHUB_ENV | |
| echo "SDKROOT=$(xcrun --sdk macosx --show-sdk-path)" >> $GITHUB_ENV | |
| echo "MACOSX_DEPLOYMENT_TARGET=13.3" >> $GITHUB_ENV | |
| echo "CC=$(xcrun -f clang)" >> $GITHUB_ENV | |
| echo "CXX=$(xcrun -f clang++)" >> $GITHUB_ENV | |
| xcodebuild -version | |
| xcrun --sdk macosx --show-sdk-version | |
| xcrun --sdk macosx --show-sdk-path | |
| xcrun -find clang | |
| xcrun clang --version | |
| - name: Import Apple Certificates | |
| env: | |
| APP_CERTIFICATE_BASE64: ${{ secrets.APPLE_SIGNING_CERTIFICATE }} | |
| APP_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} | |
| INSTALLER_CERTIFICATE_BASE64: ${{ secrets.APPLE_INSTALLER_CERTIFICATE }} | |
| INSTALLER_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} | |
| KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} | |
| APPLE_NOTARIZE_KEY: ${{ secrets.APPLE_NOTARIZE_KEY }} | |
| APPLE_NOTARIZE_ID: ${{ secrets.APPLE_NOTARIZE_ID }} | |
| APPLE_ISSUER: ${{ secrets.APPLE_ISSUER }} | |
| run: | | |
| # Define paths | |
| APP_CERT_PATH=$RUNNER_TEMP/app_certificate.p12 | |
| INSTALLER_CERT_PATH=$RUNNER_TEMP/installer_certificate.p12 | |
| KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db | |
| # Decode and save certificates | |
| echo "$APP_CERTIFICATE_BASE64" | base64 --decode > $APP_CERT_PATH | |
| echo "$INSTALLER_CERTIFICATE_BASE64" | base64 --decode > $INSTALLER_CERT_PATH | |
| # Create and configure temporary keychain | |
| 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 list-keychains -s $KEYCHAIN_PATH | |
| # Import Application certificate | |
| security import $APP_CERT_PATH -P "$APP_CERTIFICATE_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH | |
| security set-key-partition-list -S apple-tool:,apple: -s -k "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH | |
| # Import Installer certificate | |
| security import $INSTALLER_CERT_PATH -P "$INSTALLER_CERTIFICATE_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH | |
| security set-key-partition-list -S apple-tool:,apple: -s -k "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH | |
| # Import Notarization credentials | |
| echo "$APPLE_NOTARIZE_KEY" | base64 --decode > Notarization_AuthKey.p8 | |
| xcrun notarytool store-credentials "AC_PASSWORD" \ | |
| --key "Notarization_AuthKey.p8" \ | |
| --key-id "$APPLE_NOTARIZE_ID" \ | |
| --issuer "$APPLE_ISSUER" | |
| - name: Install Dependencies | |
| run: | | |
| cd AutoSubs-App | |
| npm install | |
| - name: Download ffmpeg binary | |
| env: | |
| GH_TOKEN: ${{ secrets.GH_TOKEN }} | |
| run: | | |
| set -euo pipefail | |
| cd AutoSubs-App/src-tauri | |
| mkdir -p binaries | |
| cd binaries | |
| # Determine architecture and corresponding asset names from matrix | |
| if [ "${{ matrix.arch }}" = "arm64" ]; then | |
| ZIP_NAME="ffmpeg-aarch64-apple-darwin.zip" | |
| FFMPEG_SRC="ffmpeg-aarch64-apple-darwin" | |
| else | |
| # Fallback to x86_64 naming if runner arch isn't arm64 | |
| ZIP_NAME="ffmpeg-x86_64-apple-darwin.zip" | |
| FFMPEG_SRC="ffmpeg-x86_64-apple-darwin" | |
| fi | |
| # Download the appropriate archive from the ffmpeg-binaries repo | |
| gh release download \ | |
| --repo tmoroney/ffmpeg-binaries \ | |
| --pattern "$ZIP_NAME" \ | |
| --clobber | |
| # Unzip directly into current folder (junk paths to avoid nested dirs) | |
| unzip -jo "$ZIP_NAME" | |
| # Ensure executables (keep architecture-specific names expected by Tauri v2) | |
| chmod +x "$FFMPEG_SRC" | |
| # Cleanup archive | |
| rm -f "$ZIP_NAME" | |
| - name: Configure ggml/whisper for ARM (disable i8mm) | |
| if: matrix.arch == 'arm64' | |
| run: | | |
| # Prevent the preprocessor from enabling i8mm paths | |
| echo 'CFLAGS=-U__ARM_FEATURE_MATMUL_INT8' >> "$GITHUB_ENV" | |
| echo 'CXXFLAGS=-U__ARM_FEATURE_MATMUL_INT8' >> "$GITHUB_ENV" | |
| # Also disable ggml i8mm + native flags (deterministic across runners) | |
| echo 'CMAKE_ARGS=-DGGML_I8MM=OFF -DGGML_NATIVE=OFF -DCMAKE_OSX_DEPLOYMENT_TARGET=13.3' >> "$GITHUB_ENV" | |
| - name: Build Tauri | |
| run: | | |
| cd AutoSubs-App | |
| export APPLE_SIGNING_IDENTITY="Developer ID Application: ${{ secrets.APPLE_IDENTITY }}" | |
| export TAURI_SIGNING_PRIVATE_KEY="${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}" | |
| export TAURI_SIGNING_PRIVATE_KEY_PASSWORD="${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}" | |
| npm run tauri build -- -- --no-default-features --features "${{ matrix.features }}" | |
| - name: Create Mac Package | |
| run: | | |
| # Create the package directory | |
| mkdir Mac-Package/Payload | |
| # Move the app to the package | |
| mv AutoSubs-App/src-tauri/target/release/bundle/macos/AutoSubs.app Mac-Package/Payload | |
| - name: Create PKG Installer | |
| run: | | |
| # Give permissions to the scripts | |
| chmod +x Mac-Package/Scripts/* | |
| # Create the package | |
| # Resolve version from TAG (strip leading 'v' if present) | |
| VERSION="${TAG}" | |
| # Strip leading 'v' if present | |
| VERSION=${VERSION#v} | |
| pkgbuild --identifier com.tom-moroney.autosubs \ | |
| --version "$VERSION" \ | |
| --install-location "/Applications" \ | |
| --root Mac-Package/Payload \ | |
| --scripts Mac-Package/Scripts \ | |
| AutoSubs-unsigned.pkg | |
| - name: Sign PKG Installer | |
| run: | | |
| productsign --sign "Developer ID Installer: ${{ secrets.APPLE_IDENTITY }}" \ | |
| --timestamp \ | |
| "AutoSubs-unsigned.pkg" \ | |
| "AutoSubs-Mac-${{ matrix.pkg_suffix }}.pkg" | |
| - name: Notarize PKG Installer | |
| run: | | |
| # Function to notarize and staple the package | |
| notarize_and_staple() { | |
| xcrun notarytool submit "AutoSubs-Mac-${{ matrix.pkg_suffix }}.pkg" \ | |
| --keychain-profile "AC_PASSWORD" \ | |
| --wait | |
| xcrun stapler staple "AutoSubs-Mac-${{ matrix.pkg_suffix }}.pkg" | |
| } | |
| # Try notarization up to 3 times in case of bus error | |
| for i in {1..3}; do | |
| notarize_and_staple && break || { | |
| echo "Notarization attempt $i failed. Retrying..." | |
| sleep 10 | |
| } | |
| done | |
| - name: Collect Tauri Updater Artifacts (macOS) | |
| run: | | |
| set -euo pipefail | |
| # Paths | |
| MACOS_BUNDLE_DIR="AutoSubs-App/src-tauri/target/release/bundle/macos" | |
| OUT_DIR="release-artifacts" | |
| mkdir -p "$OUT_DIR" | |
| # Rename updater archives per-arch to avoid filename collisions in the release | |
| if [ -f "$MACOS_BUNDLE_DIR/AutoSubs.app.tar.gz" ]; then | |
| if [ "${{ matrix.arch }}" = "arm64" ]; then | |
| NEW_NAME="AutoSubs-macos-aarch64.app.tar.gz" | |
| else | |
| NEW_NAME="AutoSubs-macos-x86_64.app.tar.gz" | |
| fi | |
| mv "$MACOS_BUNDLE_DIR/AutoSubs.app.tar.gz" "$MACOS_BUNDLE_DIR/$NEW_NAME" | |
| if [ -f "$MACOS_BUNDLE_DIR/AutoSubs.app.tar.gz.sig" ]; then | |
| mv "$MACOS_BUNDLE_DIR/AutoSubs.app.tar.gz.sig" "$MACOS_BUNDLE_DIR/$NEW_NAME.sig" | |
| else | |
| echo "ERROR: Updater signature AutoSubs.app.tar.gz.sig not found in $MACOS_BUNDLE_DIR" >&2 | |
| exit 1 | |
| fi | |
| fi | |
| # Copy renamed updater artifacts to release output | |
| if [ "${{ matrix.arch }}" = "arm64" ]; then | |
| cp "$MACOS_BUNDLE_DIR/AutoSubs-macos-aarch64.app.tar.gz" "$OUT_DIR/" | |
| cp "$MACOS_BUNDLE_DIR/AutoSubs-macos-aarch64.app.tar.gz.sig" "$OUT_DIR/" | |
| else | |
| cp "$MACOS_BUNDLE_DIR/AutoSubs-macos-x86_64.app.tar.gz" "$OUT_DIR/" | |
| cp "$MACOS_BUNDLE_DIR/AutoSubs-macos-x86_64.app.tar.gz.sig" "$OUT_DIR/" | |
| fi | |
| - name: Upload Build Artifacts to Release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| files: | | |
| AutoSubs-Mac-${{ matrix.pkg_suffix }}.pkg | |
| release-artifacts/* | |
| token: ${{ secrets.GH_TOKEN }} | |
| tag_name: ${{ env.TAG }} | |
| build-linux: | |
| needs: [build-mac] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout AutoSubs Repo Code | |
| uses: actions/checkout@v4 | |
| - name: Install Vulkan SDK (for glslc) | |
| run: | | |
| set -euxo pipefail | |
| sudo apt-get update | |
| sudo apt-get install -y curl ca-certificates gnupg lsb-release | |
| CODENAME="$(. /etc/os-release && echo "${VERSION_CODENAME:-}")" | |
| if [ -z "$CODENAME" ]; then | |
| CODENAME="$(lsb_release -cs || echo noble)" | |
| fi | |
| # Add LunarG signing key to a keyring | |
| curl -fsSL https://packages.lunarg.com/lunarg-signing-key-pub.asc \ | |
| | gpg --dearmor \ | |
| | sudo tee /usr/share/keyrings/lunarg-archive-keyring.gpg >/dev/null | |
| # Remove any existing LunarG lists to avoid duplicate/conflicting entries | |
| sudo rm -f /etc/apt/sources.list.d/lunarg-vulkan*.list || true | |
| # Add a single apt source entry with signed-by to avoid conflicts | |
| echo "deb [signed-by=/usr/share/keyrings/lunarg-archive-keyring.gpg] https://packages.lunarg.com/vulkan $CODENAME main" \ | |
| | sudo tee /etc/apt/sources.list.d/lunarg-vulkan.list >/dev/null | |
| sudo apt-get update | |
| sudo apt-get install -y vulkan-sdk | |
| glslc --version | |
| - name: Install Linux dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y \ | |
| libgtk-3-dev \ | |
| libwebkit2gtk-4.1-dev \ | |
| libsoup-3.0-dev \ | |
| libayatana-appindicator3-dev \ | |
| librsvg2-dev \ | |
| build-essential \ | |
| pkg-config \ | |
| libvulkan-dev \ | |
| mesa-vulkan-drivers \ | |
| unzip \ | |
| rpm | |
| - name: Install NPM deps | |
| run: | | |
| cd AutoSubs-App | |
| npm install | |
| - name: Build Tauri (Linux x86_64) | |
| run: | | |
| cd AutoSubs-App | |
| export TAURI_SIGNING_PRIVATE_KEY="${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}" | |
| export TAURI_SIGNING_PRIVATE_KEY_PASSWORD="${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}" | |
| # Disable default features (mac-specific) for Linux build | |
| npm run tauri build -- -- --no-default-features --features linux | |
| - name: Collect Linux artifacts | |
| run: | | |
| set -euo pipefail | |
| LINUX_BUNDLE_DIR="AutoSubs-App/src-tauri/target/release/bundle" | |
| DEB_FILE=$(ls -1 "$LINUX_BUNDLE_DIR/deb"/*.deb 2>/dev/null | head -n1 || true) | |
| if [ -n "$DEB_FILE" ]; then | |
| cp "$DEB_FILE" "AutoSubs-linux-x86_64.deb" | |
| else | |
| echo "ERROR: .deb package not found in $LINUX_BUNDLE_DIR/deb" | |
| exit 1 | |
| fi | |
| RPM_FILE=$(ls -1 "$LINUX_BUNDLE_DIR/rpm"/*.rpm 2>/dev/null | head -n1 || true) | |
| if [ -n "$RPM_FILE" ]; then | |
| cp "$RPM_FILE" "AutoSubs-linux-x86_64.rpm" | |
| else | |
| echo "ERROR: .rpm package not found in $LINUX_BUNDLE_DIR/rpm" | |
| exit 1 | |
| fi | |
| - name: Upload Linux artifacts to Release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| files: | | |
| AutoSubs-linux-x86_64.deb | |
| AutoSubs-linux-x86_64.rpm | |
| token: ${{ secrets.GH_TOKEN }} | |
| tag_name: ${{ env.TAG }} | |
| compose-latest-json: | |
| needs: [build-mac] | |
| uses: ./.github/workflows/generate-updater-json.yml | |
| with: | |
| tag: ${{ github.event.release.tag_name || inputs.tag }} | |
| secrets: inherit |