Skip to content

tweak macos

tweak macos #22

Workflow file for this run

name: Build Desktop Apps
on:
push:
tags:
- 'v*' # Build on version tags (v1.0.0, v2.1.0, etc.)
workflow_dispatch: # Allow manual triggering
jobs:
build-macos:
runs-on: macos-latest
env:
APP_PATH: build/macos/Build/Products/Release/View Source Vibe.app
DMG_PATH: ViewSourceVibe.dmg
steps:
- uses: actions/checkout@v4
- name: Setup Flutter
uses: subosito/flutter-action@v2
with:
flutter-version: '3.41.6'
cache: true
- name: Get dependencies
run: flutter pub get
- name: Import Apple signing certificate
env:
APPLE_CERTIFICATE_P12: ${{ secrets.APPLE_CERTIFICATE_P12 }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
KEYCHAIN_PASSWORD: ${{ github.run_id }}-${{ github.run_attempt }}
run: |
CERTIFICATE_PATH="$RUNNER_TEMP/apple-signing-certificate.p12"
KEYCHAIN_PATH="$RUNNER_TEMP/app-signing.keychain-db"
echo "$APPLE_CERTIFICATE_P12" | base64 -D > "$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 default-keychain -s "$KEYCHAIN_PATH"
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
security find-identity -v -p codesigning "$KEYCHAIN_PATH"
- name: Configure Apple development team
env:
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
run: |
if [ -z "$APPLE_TEAM_ID" ]; then
echo "APPLE_TEAM_ID secret is required."
exit 1
fi
perl -0pi -e 's/DEVELOPMENT_TEAM = [A-Z0-9]+;/DEVELOPMENT_TEAM = $ENV{APPLE_TEAM_ID};/g' macos/Runner.xcodeproj/project.pbxproj
- name: Build macOS
run: flutter build macos --release
- name: Sign macOS app
env:
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
run: |
SIGNING_IDENTITY="$(security find-identity -v -p codesigning | awk -F '"' '/Developer ID Application/ { print $2; exit }')"
if [ -z "$SIGNING_IDENTITY" ]; then
echo "No Developer ID Application signing identity found in the keychain."
security find-identity -v -p codesigning
exit 1
fi
if [ -d "$APP_PATH/Contents/Frameworks" ]; then
while IFS= read -r -d '' FRAMEWORK; do
codesign \
--force \
--options runtime \
--timestamp \
--sign "$SIGNING_IDENTITY" \
"$FRAMEWORK"
done < <(find "$APP_PATH/Contents/Frameworks" -type d -name "*.framework" -print0)
while IFS= read -r -d '' LIBRARY; do
codesign \
--force \
--options runtime \
--timestamp \
--sign "$SIGNING_IDENTITY" \
"$LIBRARY"
done < <(find "$APP_PATH/Contents/Frameworks" -type f \( -name "*.dylib" -o -name "*.so" \) -print0)
fi
codesign \
--force \
--options runtime \
--timestamp \
--entitlements macos/Runner/Release.entitlements \
--sign "$SIGNING_IDENTITY" \
"$APP_PATH"
codesign --verify --deep --strict --verbose=2 "$APP_PATH"
spctl --assess --type execute --verbose=4 "$APP_PATH" || true
- name: Create macOS DMG
run: |
brew install create-dmg
create-dmg \
--volname "View Source Vibe" \
--window-pos 200 120 \
--window-size 600 300 \
--icon-size 100 \
--app-drop-link 425 120 \
"$DMG_PATH" \
"$APP_PATH"
- name: Sign and notarize macOS DMG
env:
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
run: |
SIGNING_IDENTITY="$(security find-identity -v -p codesigning | awk -F '"' '/Developer ID Application/ { print $2; exit }')"
if [ -z "$SIGNING_IDENTITY" ]; then
echo "No Developer ID Application signing identity found in the keychain."
security find-identity -v -p codesigning
exit 1
fi
codesign \
--force \
--timestamp \
--sign "$SIGNING_IDENTITY" \
"$DMG_PATH"
codesign --verify --verbose=2 "$DMG_PATH"
xcrun notarytool submit "$DMG_PATH" \
--apple-id "$APPLE_ID" \
--password "$APPLE_PASSWORD" \
--team-id "$APPLE_TEAM_ID" \
--wait
xcrun stapler staple "$DMG_PATH"
xcrun stapler validate "$DMG_PATH"
spctl --assess --type open --context context:primary-signature --verbose=4 "$DMG_PATH"
- name: Upload macOS DMG
uses: actions/upload-artifact@v4
with:
name: ViewSourceVibe-macOS
path: ${{ env.DMG_PATH }}
- name: Clean up signing keychain
if: always()
run: |
security delete-keychain "$RUNNER_TEMP/app-signing.keychain-db" || true
build-windows:
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
- name: Setup Flutter
uses: subosito/flutter-action@v2
with:
flutter-version: '3.41.6'
cache: true
- name: Get dependencies
run: flutter pub get
- name: Build Windows
run: flutter build windows --release
- name: Create Windows installer
run: |
$iss = @"
[Setup]
AppName=View Source Vibe
AppVersion=${{ github.ref_name }}
DefaultDirName={autopf}\View Source Vibe
OutputDir=installer
OutputBaseFilename=ViewSourceVibe-Setup
Compression=lzma
SolidCompression=yes
ArchitecturesInstallIn64BitMode=x64compatible
[Files]
Source: "build\windows\x64\runner\Release\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs
[Icons]
Name: "{autoprograms}\View Source Vibe"; Filename: "{app}\view_source_vibe.exe"
Name: "{autodesktop}\View Source Vibe"; Filename: "{app}\view_source_vibe.exe"
[Run]
Filename: "{app}\view_source_vibe.exe"; Description: "Launch View Source Vibe"; Flags: nowait postinstall skipifsilent
"@
$iss | Out-File -FilePath setup.iss -Encoding UTF8
& "C:\Program Files (x86)\Inno Setup 6\ISCC.exe" setup.iss
shell: pwsh
- name: Upload Windows installer
uses: actions/upload-artifact@v4
with:
name: ViewSourceVibe-Windows
path: installer/ViewSourceVibe-Setup.exe
build-ios:
if: false
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- name: Setup Flutter
uses: subosito/flutter-action@v2
with:
flutter-version: '3.41.6'
cache: true
- name: Get dependencies
run: flutter pub get
- name: Build iOS
run: flutter build ios --release --no-codesign
- name: Package iOS artifact
run: zip -r ViewSourceVibe-iOS.zip build/ios/iphoneos/Runner.app
- name: Upload iOS artifact
uses: actions/upload-artifact@v4
with:
name: ViewSourceVibe-iOS
path: ViewSourceVibe-iOS.zip
build-android:
if: false
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Flutter
uses: subosito/flutter-action@v2
with:
flutter-version: '3.41.6'
cache: true
- name: Get dependencies
run: flutter pub get
- name: Decode keystore
run: |
echo "${{ secrets.ANDROID_KEYSTORE }}" | base64 --decode > $GITHUB_WORKSPACE/android/app/release.keystore
ls -la $GITHUB_WORKSPACE/android/app/release.keystore
- name: Build Android APK
run: flutter build apk --release
env:
ANDROID_STORE_PASSWORD: ${{ secrets.ANDROID_STORE_PASSWORD }}
ANDROID_KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }}
ANDROID_KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }}
ANDROID_KEYSTORE_PATH: ${{ github.workspace }}/android/app/release.keystore
- name: Build Android App Bundle
run: flutter build appbundle --release
env:
ANDROID_STORE_PASSWORD: ${{ secrets.ANDROID_STORE_PASSWORD }}
ANDROID_KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }}
ANDROID_KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }}
ANDROID_KEYSTORE_PATH: ${{ github.workspace }}/android/app/release.keystore
- name: Upload Android APK
uses: actions/upload-artifact@v4
with:
name: ViewSourceVibe-Android-APK
path: build/app/outputs/apk/release/app-release.apk
- name: Upload Android App Bundle
uses: actions/upload-artifact@v4
with:
name: ViewSourceVibe-Android-AAB
path: build/app/outputs/bundle/release/app-release.aab
create-release:
needs: [build-macos, build-windows]
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/')
permissions:
contents: write
steps:
- uses: actions/download-artifact@v4
- name: Create Release
uses: softprops/action-gh-release@v2
with:
files: |
ViewSourceVibe-macOS/ViewSourceVibe.dmg
ViewSourceVibe-Windows/ViewSourceVibe-Setup.exe
# ViewSourceVibe-iOS/ViewSourceVibe-iOS.zip
# ViewSourceVibe-Android-APK/app-release.apk
# ViewSourceVibe-Android-AAB/app-release.aab