update version to 2.1.0 #307
Workflow file for this run
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: Build All Platforms | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| run_all: | |
| description: Run all platform jobs | |
| type: boolean | |
| default: true | |
| android: | |
| description: Run Android job | |
| type: boolean | |
| default: false | |
| ios: | |
| description: Run iOS job | |
| type: boolean | |
| default: false | |
| macos: | |
| description: Run macOS job | |
| type: boolean | |
| default: false | |
| windows: | |
| description: Run Windows job | |
| type: boolean | |
| default: false | |
| linux: | |
| description: Run Linux job | |
| type: boolean | |
| default: false | |
| push: | |
| tags: | |
| - '[0-9]+.[0-9]+.[0-9]+*' | |
| pull_request: | |
| branches: | |
| - main | |
| permissions: | |
| contents: write | |
| env: | |
| FLUTTER_VERSION: '3.41.2' | |
| jobs: | |
| # Android APK + AAB | |
| android: | |
| if: ${{ github.event_name != 'workflow_dispatch' || inputs.run_all || inputs.android }} | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-java@v4 | |
| with: | |
| distribution: temurin | |
| java-version: '17' | |
| - uses: subosito/flutter-action@v2 | |
| with: | |
| flutter-version: ${{ env.FLUTTER_VERSION }} | |
| - name: Set up signing | |
| env: | |
| ANDROID_KEYSTORE_BASE64: ${{ secrets.ANDROID_KEYSTORE_BASE64 }} | |
| STORE_TYPE: ${{ secrets.ANDROID_KEYSTORE_TYPE }} | |
| STORE_PASSWORD: ${{ secrets.ANDROID_STORE_PASSWORD }} | |
| KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }} | |
| KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }} | |
| run: | | |
| # On PRs from forks the signing secrets are not available. Skip signing | |
| # setup so Gradle falls back to debug signing and the build still runs. | |
| if [ -z "$ANDROID_KEYSTORE_BASE64" ]; then | |
| echo "No Android keystore secret; skipping release signing (debug-signed build)." | |
| exit 0 | |
| fi | |
| # Use printf (not echo) to avoid adding a trailing newline that can corrupt binary decode on some shells. | |
| printf '%s' "$ANDROID_KEYSTORE_BASE64" | base64 --decode > android/app/release.keystore | |
| cat > android/keystore.properties <<EOF | |
| storeFile=../release.keystore | |
| storeType=$STORE_TYPE | |
| storePassword=$STORE_PASSWORD | |
| keyAlias=$KEY_ALIAS | |
| keyPassword=$KEY_PASSWORD | |
| EOF | |
| # Fail fast with a clearer error if the keystore secret or type is wrong. | |
| if [ -n "$STORE_TYPE" ]; then | |
| keytool -list -v -keystore android/app/release.keystore -storetype "$STORE_TYPE" -storepass "$STORE_PASSWORD" >/dev/null | |
| else | |
| keytool -list -v -keystore android/app/release.keystore -storepass "$STORE_PASSWORD" >/dev/null | |
| fi | |
| - name: Build | |
| run: | | |
| chmod +x build-android.sh | |
| ./build-android.sh | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: android | |
| path: | | |
| Moonfin_Android_v*.* | |
| Moonfin_AndroidTV_v*.* | |
| # iOS unsigned IPA | |
| ios: | |
| if: ${{ github.event_name != 'workflow_dispatch' || inputs.run_all || inputs.ios }} | |
| runs-on: macos-26 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: subosito/flutter-action@v2 | |
| with: | |
| flutter-version: ${{ env.FLUTTER_VERSION }} | |
| - name: Select Xcode 26.3 | |
| run: sudo xcode-select -s /Applications/Xcode_26.3.app/Contents/Developer | |
| - name: Build unsigned IPA | |
| run: | | |
| VERSION=$(grep '^version:' pubspec.yaml | sed 's/version:[[:space:]]*//' | cut -d'+' -f1 | tr -d '[:space:]') | |
| flutter clean | |
| flutter pub get | |
| flutter build ipa --release --no-codesign | |
| APP_PATH=$(find build/ios/archive -type d -path '*/Products/Applications/*.app' | head -1) | |
| TMPDIR=$(mktemp -d) | |
| mkdir -p "$TMPDIR/Payload" | |
| cp -R "$APP_PATH" "$TMPDIR/Payload/" | |
| (cd "$TMPDIR" && zip -qry "$OLDPWD/Moonfin_iOS_v${VERSION}_unsigned.ipa" Payload) | |
| rm -rf "$TMPDIR" | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: ios-ipa | |
| path: Moonfin_iOS_v*_unsigned.ipa | |
| # macOS signed DMG | |
| macos: | |
| if: ${{ github.event_name != 'workflow_dispatch' || inputs.run_all || inputs.macos }} | |
| runs-on: macos-26 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: subosito/flutter-action@v2 | |
| with: | |
| flutter-version: ${{ env.FLUTTER_VERSION }} | |
| - name: Select Xcode 26.3 | |
| run: sudo xcode-select -s /Applications/Xcode_26.3.app/Contents/Developer | |
| - name: Import signing certificate | |
| env: | |
| MACOS_CERTIFICATE_BASE64: ${{ secrets.MACOS_CERTIFICATE_BASE64 }} | |
| MACOS_CERTIFICATE_PASSWORD: ${{ secrets.MACOS_CERTIFICATE_PASSWORD }} | |
| run: | | |
| # On PRs from forks the certificate secret is not available. Skip the | |
| # signing setup; build-macos.sh produces an unsigned build when no | |
| # identity is present. | |
| if [ -z "$MACOS_CERTIFICATE_BASE64" ]; then | |
| echo "No macOS certificate secret; skipping signing setup (unsigned build)." | |
| exit 0 | |
| fi | |
| CERT_PATH="$RUNNER_TEMP/certificate.p12" | |
| KEYCHAIN_PATH="$RUNNER_TEMP/build.keychain-db" | |
| KEYCHAIN_PASSWORD="$(openssl rand -hex 20)" | |
| echo "$MACOS_CERTIFICATE_BASE64" | base64 -D -o "$CERT_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 "$CERT_PATH" -P "$MACOS_CERTIFICATE_PASSWORD" \ | |
| -A -t cert -f pkcs12 -k "$KEYCHAIN_PATH" | |
| security set-key-partition-list -S apple-tool:,apple: \ | |
| -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" | |
| security list-keychains -d user -s "$KEYCHAIN_PATH" login.keychain-db | |
| - name: Store notarytool credentials | |
| env: | |
| APPLE_ID: ${{ secrets.APPLE_ID }} | |
| APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} | |
| APPLE_APP_PASSWORD: ${{ secrets.APPLE_APP_PASSWORD }} | |
| run: | | |
| if [ -z "$APPLE_ID" ]; then | |
| echo "No Apple ID configured, skipping notarytool credentials" | |
| exit 0 | |
| fi | |
| xcrun notarytool store-credentials "moonfin-notary" \ | |
| --apple-id "$APPLE_ID" \ | |
| --team-id "$APPLE_TEAM_ID" \ | |
| --password "$APPLE_APP_PASSWORD" | |
| - name: Build signed DMG | |
| env: | |
| APP_SIGN_ID: ${{ secrets.MACOS_APP_SIGN_ID }} | |
| INSTALLER_ID: ${{ secrets.MACOS_INSTALLER_ID }} | |
| NOTARYTOOL_PROFILE: ${{ secrets.APPLE_ID != '' && 'moonfin-notary' || '' }} | |
| TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} | |
| BUILD_APPSTORE_PKG: '0' | |
| run: | | |
| chmod +x build-macos.sh | |
| ./build-macos.sh | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: macos-dmg | |
| path: Moonfin_macOS_v*.dmg | |
| # Windows installer EXE | |
| windows: | |
| if: ${{ github.event_name != 'workflow_dispatch' || inputs.run_all || inputs.windows }} | |
| runs-on: windows-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: subosito/flutter-action@v2 | |
| with: | |
| flutter-version: ${{ env.FLUTTER_VERSION }} | |
| - name: Install Inno Setup | |
| shell: pwsh | |
| run: choco install innosetup -y --no-progress | |
| - name: Build installer | |
| shell: pwsh | |
| run: .\build-windows.ps1 | |
| - name: Verify Windows artifact | |
| shell: pwsh | |
| run: | | |
| $artifacts = Get-ChildItem -Path . -Filter "Moonfin_Windows_v*.exe" -File -ErrorAction SilentlyContinue | |
| if (-not $artifacts -or $artifacts.Count -eq 0) { | |
| throw "Windows build did not produce Moonfin_Windows_v*.exe" | |
| } | |
| Write-Host "Found Windows artifact(s):" | |
| $artifacts | ForEach-Object { Write-Host " - $($_.Name)" } | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: windows-exe | |
| path: Moonfin_Windows_v*.exe | |
| if-no-files-found: error | |
| # Linux packages | |
| linux: | |
| if: ${{ github.event_name != 'workflow_dispatch' || inputs.run_all || inputs.linux }} | |
| runs-on: ubuntu-24.04 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: subosito/flutter-action@v2 | |
| with: | |
| flutter-version: ${{ env.FLUTTER_VERSION }} | |
| - name: Install system build dependencies | |
| run: | | |
| set -euo pipefail | |
| sudo apt-get update | |
| sudo apt-get install -y \ | |
| clang cmake ninja-build pkg-config \ | |
| libgtk-3-dev libglib2.0-dev \ | |
| libwebkit2gtk-4.1-dev \ | |
| libmpv-dev libsecret-1-dev libasound2-dev \ | |
| libarchive-dev \ | |
| rpm \ | |
| flatpak flatpak-builder \ | |
| libfuse2 | |
| - name: Verify webkit2gtk availability | |
| run: | | |
| set -euo pipefail | |
| if pkg-config --exists webkit2gtk-4.1; then | |
| echo "Found webkit2gtk-4.1: $(pkg-config --modversion webkit2gtk-4.1)" | |
| elif pkg-config --exists webkit2gtk-4.2; then | |
| echo "Found webkit2gtk-4.2: $(pkg-config --modversion webkit2gtk-4.2)" | |
| elif pkg-config --exists webkit2gtk-4.3; then | |
| echo "Found webkit2gtk-4.3: $(pkg-config --modversion webkit2gtk-4.3)" | |
| else | |
| echo "No supported webkit2gtk version found (need 4.1/4.2/4.3)." | |
| exit 1 | |
| fi | |
| - name: Install appimagetool | |
| run: | | |
| sudo curl -fsSL -o /usr/local/bin/appimagetool \ | |
| https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage | |
| sudo chmod +x /usr/local/bin/appimagetool | |
| - name: Install snapcraft | |
| run: sudo snap install snapcraft --classic | |
| - name: Prepare snapd and core22 | |
| run: | | |
| sudo snap wait system seed.loaded | |
| sudo snap list core22 >/dev/null 2>&1 || sudo snap install core22 --channel=latest/stable | |
| - name: Build all Linux packages | |
| run: | | |
| chmod +x build-linux.sh | |
| ./build-linux.sh all | |
| - name: Verify Linux artifacts | |
| run: | | |
| set -euo pipefail | |
| shopt -s nullglob | |
| patterns=( | |
| "Moonfin_Linux_v*.tar.gz" | |
| "Moonfin_Linux_v*.AppImage" | |
| "Moonfin_Linux_v*.deb" | |
| "Moonfin_Linux_v*.rpm" | |
| "Moonfin_Linux_v*.snap" | |
| "Moonfin_Linux_v*.flatpak" | |
| ) | |
| missing=0 | |
| for pattern in "${patterns[@]}"; do | |
| matches=( $pattern ) | |
| if [ ${#matches[@]} -eq 0 ]; then | |
| echo "Missing artifact for pattern: $pattern" | |
| missing=1 | |
| else | |
| for m in "${matches[@]}"; do | |
| echo "Found artifact: $m" | |
| done | |
| fi | |
| done | |
| if [ $missing -ne 0 ]; then | |
| echo "One or more Linux package artifacts are missing." | |
| exit 1 | |
| fi | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: linux-packages | |
| path: | | |
| Moonfin_Linux_v*.tar.gz | |
| Moonfin_Linux_v*.AppImage | |
| Moonfin_Linux_v*.deb | |
| Moonfin_Linux_v*.rpm | |
| Moonfin_Linux_v*.snap | |
| Moonfin_Linux_v*.flatpak | |
| if-no-files-found: error | |
| # GitHub Release | |
| release: | |
| if: startsWith(github.ref, 'refs/tags/') | |
| needs: [android, ios, macos, windows, linux] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| merge-multiple: true | |
| - uses: softprops/action-gh-release@v2 | |
| with: | |
| draft: true | |
| files: Moonfin_* | |
| generate_release_notes: true |