Skip to content

Add comprehensive README with usage guide and installation instructions #107

Add comprehensive README with usage guide and installation instructions

Add comprehensive README with usage guide and installation instructions #107

Workflow file for this run

# Workflow to build and upload AppImage for Linux, macOS Universal DMG, and Windows .exe
name: Rust Cross-Platform Builds
# Trigger configuration
on:
push:
branches: ["master"]
pull_request:
branches: ["master"]
workflow_dispatch:
inputs:
version:
description: "Version to build"
required: false
default: "1.0.0"
# Global environment variables
env:
BINARY_NAME: idevice_pair
APP_NAME: idevice_pair
VERSION: ${{ github.event.inputs.version }}
ICON_PNG: icon.png
CARGO_TERM_COLOR: always
jobs:
# Linux builds
build-appimage:
name: Build & Upload AppImage (Linux ${{ matrix.arch }})
runs-on: ${{ matrix.runner }}
strategy:
matrix:
include:
- arch: x86_64
runner: ubuntu-latest
target: x86_64-unknown-linux-gnu
toolfile: appimagetool-x86_64.AppImage
- arch: aarch64
runner: ubuntu-22.04-arm
target: aarch64-unknown-linux-gnu
toolfile: appimagetool-aarch64.AppImage
steps:
- uses: actions/checkout@v4
# Build setup
- name: Setup Rust toolchain
uses: actions-rs/toolchain@v1
with:
toolchain: stable
components: rustfmt, clippy
target: ${{ matrix.target }}
- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
libglib2.0-dev \
libatk1.0-dev \
libgtk-3-dev \
pkg-config \
libfuse2 \
appstream \
usbmuxd
- name: Cache Cargo
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{matrix.target}}-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: linux-cargo-
# Build and package
- name: Build binary
run: cargo build --release --bin ${{ env.BINARY_NAME }} --target ${{ matrix.target }}
- name: Download appimagetool
run: |
wget -c https://github.com/AppImage/AppImageKit/releases/download/continuous/${{ matrix.toolfile }} \
-O appimagetool.AppImage
chmod +x appimagetool.AppImage
- name: Prepare AppDir
run: |
mkdir -p AppDir/usr/bin AppDir/usr/lib AppDir/usr/share/icons/hicolor/256x256/apps AppDir/etc/udev/rules.d
cp target/${{ matrix.target }}/release/${{ env.BINARY_NAME }} AppDir/usr/bin/
cp $(which usbmuxd) AppDir/usr/bin/
sudo cp /lib/udev/rules.d/39-usbmuxd.rules AppDir/etc/udev/rules.d/
ICON_NAME=${ICON_PNG##*/}; BASENAME=${ICON_NAME%.*}
cp ${{ env.ICON_PNG }} AppDir/${BASENAME}.png
cp ${{ env.ICON_PNG }} AppDir/usr/share/icons/hicolor/256x256/apps/${BASENAME}.png
cat > AppDir/${{ env.BINARY_NAME }}.desktop <<EOF
[Desktop Entry]
Type=Application
Name=${{ env.APP_NAME }}
Exec=${{ env.BINARY_NAME }} %u
Icon=${BASENAME}
Categories=Utility;
EOF
ln -s usr/bin/${{ env.BINARY_NAME }} AppDir/AppRun
chmod +x AppDir/AppRun
- name: Build AppImage
run: |
FILENAME="${{ env.APP_NAME }}-${{ env.VERSION }}-linux-${{ matrix.arch }}.AppImage"
./appimagetool.AppImage AppDir "$FILENAME"
- name: Upload AppImage
uses: actions/upload-artifact@v4
with:
name: ${{ env.APP_NAME }}-${{ env.VERSION }}-linux-${{ matrix.arch }}.AppImage
path: ${{ env.APP_NAME }}-${{ env.VERSION }}-linux-${{ matrix.arch }}.AppImage
# macOS builds
macos-universal:
name: Build macOS slices
runs-on: macos-latest
strategy:
matrix:
include:
- arch: x86_64
target: x86_64-apple-darwin
- arch: arm64
target: aarch64-apple-darwin
steps:
- uses: actions/checkout@v4
- name: Set up Rust for ${{ matrix.arch }}
uses: actions-rs/toolchain@v1
with:
toolchain: stable
components: rustfmt, clippy
target: ${{ matrix.target }}
- name: Cache Cargo
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{matrix.target}}-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: linux-cargo-
- name: Build ${{ matrix.arch }} slice
run: |
cargo build --release \
--bin ${{ env.BINARY_NAME }} \
--target ${{ matrix.target }}
- name: Upload slice ${{ matrix.arch }}
uses: actions/upload-artifact@v4
with:
name: slice-${{ matrix.arch }}
path: target/${{ matrix.target }}/release/${{ env.BINARY_NAME }}
macos-bundle:
name: Create, Sign, Notarize & Upload Universal DMG
needs: macos-universal
runs-on: macos-latest
env:
HAVE_SIGNING_SECRETS: ${{ secrets.DEV_ID_P12_BASE64 != '' && secrets.DEV_ID_P12_PASSWORD != '' && secrets.DEV_IDENTITY_NAME != '' }}
HAVE_NOTARIZE_SECRETS: ${{ secrets.NOTARIZE_APPLE_ID != '' && secrets.NOTARIZE_APP_SPECIFIC_PASS != '' && secrets.NOTARIZE_TEAM_ID != '' }}
steps:
- uses: actions/checkout@v4
- name: Download x86_64 slice
uses: actions/download-artifact@v4
with:
name: slice-x86_64
path: slice-x86_64
- name: Download arm64 slice
uses: actions/download-artifact@v4
with:
name: slice-arm64
path: slice-arm64
- name: Import Developer ID Certificate
if: env.HAVE_SIGNING_SECRETS == 'true'
uses: apple-actions/import-codesign-certs@v5
with:
p12-file-base64: ${{ secrets.DEV_ID_P12_BASE64 }}
p12-password: ${{ secrets.DEV_ID_P12_PASSWORD }}
- name: Build & Assemble Universal .app
run: |
APP="${{ env.APP_NAME }}.app"
mkdir -p "$APP/Contents/MacOS" "$APP/Contents/Resources"
# 1) Merge slices
lipo slice-x86_64/${{ env.BINARY_NAME }} \
slice-arm64/${{ env.BINARY_NAME }} \
-create -output "$APP/Contents/MacOS/${{ env.APP_NAME }}"
# 2) Write Info.plist
cat > "$APP/Contents/Info.plist" <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"><dict>
<key>CFBundleName</key><string>${{ env.APP_NAME }}</string>
<key>CFBundleDisplayName</key><string>${{ env.APP_NAME }}</string>
<key>CFBundleIdentifier</key><string>com.github.se2cird2.${{ env.APP_NAME }}</string>
<key>CFBundleVersion</key><string>${{ env.VERSION }}</string>
<key>CFBundleShortVersionString</key><string>${{ env.VERSION }}</string>
<key>CFBundleExecutable</key><string>${{ env.APP_NAME }}</string>
<key>CFBundlePackageType</key><string>APPL</string>
<key>CFBundleIconFile</key><string>icon.icns</string>
</dict></plist>
EOF
# 3) Generate .icns from PNG
ICONSET_DIR="icons.iconset"
mkdir -p "$ICONSET_DIR"
sips -z 16 16 "${{ env.ICON_PNG }}" --out "$ICONSET_DIR/icon_16x16.png"
sips -z 32 32 "${{ env.ICON_PNG }}" --out "$ICONSET_DIR/[email protected]"
sips -z 32 32 "${{ env.ICON_PNG }}" --out "$ICONSET_DIR/icon_32x32.png"
sips -z 64 64 "${{ env.ICON_PNG }}" --out "$ICONSET_DIR/[email protected]"
sips -z 128 128 "${{ env.ICON_PNG }}" --out "$ICONSET_DIR/icon_128x128.png"
sips -z 256 256 "${{ env.ICON_PNG }}" --out "$ICONSET_DIR/[email protected]"
sips -z 256 256 "${{ env.ICON_PNG }}" --out "$ICONSET_DIR/icon_256x256.png"
sips -z 512 512 "${{ env.ICON_PNG }}" --out "$ICONSET_DIR/[email protected]"
sips -z 512 512 "${{ env.ICON_PNG }}" --out "$ICONSET_DIR/icon_512x512.png"
sips -z 1024 1024 "${{ env.ICON_PNG }}" --out "$ICONSET_DIR/[email protected]"
iconutil -c icns "$ICONSET_DIR" -o "$APP/Contents/Resources/icon.icns"
rm -rf "$ICONSET_DIR"
# 4) Clean any stray xattrs
xattr -rc "$APP"
- name: Code-sign with Hardened Runtime & Timestamp
if: env.HAVE_SIGNING_SECRETS == 'true'
run: |
APP="${{ env.APP_NAME }}.app"
codesign --force --deep --options runtime --timestamp \
--sign "${{ secrets.DEV_IDENTITY_NAME }}" "$APP"
- name: Fix Permissions
run: |
APP="${{ env.APP_NAME }}.app"
find "$APP" -type d -exec chmod 755 {} +
find "$APP" -type f -exec chmod 644 {} +
chmod +x "$APP/Contents/MacOS/${{ env.APP_NAME }}"
- name: Create DMG
run: |
DMG="dist/${{ env.APP_NAME }}-${{ env.VERSION }}-macos-universal.dmg"
mkdir -p dist dmg-staging
cp -R "${{ env.APP_NAME }}.app" dmg-staging/
ln -s /Applications dmg-staging/Applications
hdiutil create \
-volname "${{ env.APP_NAME }}" \
-srcfolder dmg-staging \
-ov -format UDZO \
"$DMG"
rm -rf dmg-staging
echo "$DMG" > dmg-path.txt
- name: Notarize & Staple DMG
if: env.HAVE_NOTARIZE_SECRETS == 'true'
run: |
DMG=$(cat dmg-path.txt)
xcrun notarytool submit "$DMG" \
--apple-id "${{ secrets.NOTARIZE_APPLE_ID }}" \
--password "${{ secrets.NOTARIZE_APP_SPECIFIC_PASS }}" \
--team-id "${{ secrets.NOTARIZE_TEAM_ID }}" \
--wait --verbose
xcrun stapler staple "$DMG"
- name: Upload DMG
uses: actions/upload-artifact@v4
with:
name: ${{ env.APP_NAME }}-${{ env.VERSION }}-macos-universal.dmg
path: dist/${{ env.APP_NAME }}-${{ env.VERSION }}-macos-universal.dmg
# Windows build
build-windows:
name: Build Windows x64
runs-on: windows-latest
steps:
- uses: actions/checkout@v3
- name: Set up Rust
uses: actions-rs/toolchain@v1
with:
toolchain: stable
components: rustfmt, clippy
target: x86_64-pc-windows-msvc
- name: Cache Cargo
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: windows-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: linux-cargo-
- name: Build and Rename Executable
shell: bash
run: |
cargo build --release --bin ${{ env.BINARY_NAME }} --target x86_64-pc-windows-msvc
mkdir -p release
cp target/x86_64-pc-windows-msvc/release/${{ env.BINARY_NAME }}.exe \
release/${{ env.APP_NAME }}-${{ env.VERSION }}-windows-x86_64.exe
- name: Upload Windows .exe
uses: actions/upload-artifact@v4
with:
name: ${{ env.APP_NAME }}-${{ env.VERSION }}-windows-x86_64.exe
path: release/${{ env.APP_NAME }}-${{ env.VERSION }}-windows-x86_64.exe