name: Release on: push: tags: - 'v*' permissions: contents: read concurrency: group: release-${{ github.workflow }}-${{ github.ref }} cancel-in-progress: false env: FLUTTER_VERSION: 3.47.2 jobs: build-linux: name: Linux / ${{ matrix.architecture }} runs-on: ${{ matrix.runner }} timeout-minutes: 60 strategy: fail-fast: false matrix: include: - runner: ubuntu-24.04 architecture: x64 native_arch: x86_64 - runner: ubuntu-24.04-arm architecture: arm64 native_arch: aarch64 steps: - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 - name: Validate release version env: RELEASE_TAG: ${{ github.ref_name }} run: | version=$(python3 packaging/release_version.py --tag "$RELEASE_TAG") echo "RELEASE_VERSION=$version" >> "$GITHUB_ENV" - uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2 if: matrix.architecture == 'x64' with: channel: stable architecture: x64 flutter-version: ${{ env.FLUTTER_VERSION }} - name: Bootstrap Flutter on Linux arm64 if: matrix.architecture == 'arm64' # The SDK archive index has no Linux arm64 bundle. Flutter's own # bootstrap downloads the native Dart SDK and engine artifacts. run: | flutter_root="$RUNNER_TEMP/flutter-${FLUTTER_VERSION}" git clone --depth 1 --branch "$FLUTTER_VERSION" \ https://github.com/flutter/flutter.git "$flutter_root" echo "$flutter_root/bin" >> "$GITHUB_PATH" echo "FLUTTER_ROOT=$flutter_root" >> "$GITHUB_ENV" echo "PUB_CACHE=$HOME/.pub-cache" >> "$GITHUB_ENV" "$flutter_root/bin/flutter" --version "$flutter_root/bin/flutter" precache --linux - run: flutter pub get --enforce-lockfile - name: Install Linux packaging dependencies run: | sudo apt-get update sudo apt-get install -y --no-install-recommends \ clang cmake ninja-build pkg-config libgtk-3-dev libblkid-dev liblzma-dev \ ruby ruby-dev build-essential rpm zstd libarchive-tools flatpak patchelf desktop-file-utils \ libgdk-pixbuf2.0-dev squashfs-tools imagemagick sudo gem install --no-document fpm -v 1.16.0 - name: Build Linux bundle run: | flutter config --enable-linux-desktop flutter build linux --release - name: Build AppImage run: bash github_appimage_build.sh "${{ matrix.architecture }}" dist - name: Build Deb, RPM, Pacman and Nix packages run: bash packaging/linux.sh "${{ matrix.architecture }}" "$RELEASE_VERSION" dist - name: Build Flatpak bundle run: bash packaging/flatpak.sh "${{ matrix.architecture }}" dist - name: Install Nix for package verification uses: cachix/install-nix-action@13d8dd58da0234aa297dedd986986ccb8e7f3e24 # v31 with: nix_path: nixpkgs=channel:nixos-26.05 - name: Verify Nix package builds run: | mkdir -p "$RUNNER_TEMP/nix-package" tar -xzf "dist/flut-renamer-${RELEASE_VERSION}-${{ matrix.native_arch }}.nix.tar.gz" -C "$RUNNER_TEMP/nix-package" nix-build "$RUNNER_TEMP/nix-package" --no-out-link - name: Upload Linux packages uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: flut-renamer-linux-${{ matrix.architecture }} path: dist/* if-no-files-found: error retention-days: 7 build-android: name: Android runs-on: ubuntu-24.04 steps: - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 - uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2 with: channel: stable architecture: x64 flutter-version: ${{ env.FLUTTER_VERSION }} - run: flutter pub get --enforce-lockfile - name: Fix libdartjni build ID run: sed -i -e 's/-Wl,/-Wl,--build-id=none,/' "${PUB_CACHE}"/hosted/*/jni-*/src/CMakeLists.txt - uses: actions/setup-java@v6 with: distribution: zulu java-version: '17' - name: Decode Android signing key env: KEYSTORE_BASE64: ${{ secrets.KEYSTORE_BASE64 }} run: | test -n "$KEYSTORE_BASE64" || { echo 'Missing KEYSTORE_BASE64 secret.' >&2; exit 1; } printf '%s' "$KEYSTORE_BASE64" | base64 --decode > "$RUNNER_TEMP/flut-renamer.jks" echo "KEYSTORE=$RUNNER_TEMP/flut-renamer.jks" >> "$GITHUB_ENV" - name: Build signed Android APKs env: KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }} KEY_ALIAS: ${{ secrets.KEY_ALIAS }} KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }} run: | test -n "$KEYSTORE_PASSWORD" && test -n "$KEY_ALIAS" && test -n "$KEY_PASSWORD" || { echo 'Missing Android signing secrets.' >&2 exit 1 } flutter build apk --release flutter build apk --release --split-per-abi - name: Upload Android APKs uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: flut-renamer-android path: build/app/outputs/flutter-apk/*.apk if-no-files-found: error retention-days: 7 - name: Remove Android signing key if: always() run: rm -f -- "$RUNNER_TEMP/flut-renamer.jks" build-windows: name: Windows runs-on: windows-2022 steps: - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 - uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2 with: channel: stable architecture: x64 flutter-version: ${{ env.FLUTTER_VERSION }} - name: Install project dependencies run: flutter pub get --enforce-lockfile - name: Enable Windows build run: flutter config --enable-windows-desktop - name: Build Windows artifacts run: flutter build windows --release - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: node-version: '24' - name: Install Enigma Virtual Box run: npm install --global enigmavirtualbox@0.9.10 - name: Create Enigma Virtual Box configuration run: dart run dev/windows_evb_config_generator.dart - name: Build single-file executable run: enigmavirtualbox cli 'flut-renamer.evb' - name: Upload Windows executable uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: flut-renamer-win path: flut-renamer.exe if-no-files-found: error retention-days: 7 build-macos: name: macOS and iOS verification runs-on: macos-14 steps: - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 - uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2 with: channel: stable architecture: arm64 flutter-version: ${{ env.FLUTTER_VERSION }} - name: Install project dependencies run: flutter pub get --enforce-lockfile - name: Enable macOS build run: flutter config --enable-macos-desktop - name: Build macOS artifacts run: flutter build macos --release - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: node-version: '24' - name: Install DMG packaging tool run: npm install --global appdmg@0.6.6 - name: Build unsigned DMG run: appdmg ./dmg/config.json ./build/macos/Build/Products/Release/flut-renamer.dmg - name: Upload macOS DMG uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: flut-renamer-macos path: build/macos/Build/Products/Release/flut-renamer.dmg if-no-files-found: error retention-days: 7 - name: Build unsigned iOS IPA run: | flutter build ios --release --no-codesign mkdir -p Payload cp -R build/ios/iphoneos/Runner.app Payload/Runner.app ditto -c -k --sequesterRsrc --keepParent Payload flut-renamer-ios-unsigned.ipa - name: Upload unsigned iOS IPA uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: flut-renamer-ios-unsigned path: flut-renamer-ios-unsigned.ipa if-no-files-found: error retention-days: 7 upload-release: name: Publish GitHub Release runs-on: ubuntu-24.04 needs: - build-linux - build-android - build-windows - build-macos permissions: contents: write steps: - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 with: path: flut-renamer-release merge-multiple: true - name: Generate Homebrew, Scoop and Winget manifests and checksums env: RELEASE_TAG: ${{ github.ref_name }} run: | python3 packaging/release_metadata.py --assets flut-renamer-release \ --repository "$GITHUB_REPOSITORY" --tag "$RELEASE_TAG" (cd flut-renamer-release && sha256sum --check SHA256SUMS) - name: Publish release assets uses: ncipollo/release-action@339a81892b84b4eeb0f6e744e4574d79d0d9b8dd # v1 with: token: ${{ secrets.GITHUB_TOKEN }} artifactErrorsFailBuild: true allowUpdates: true generateReleaseNotes: true prerelease: ${{ contains(github.ref_name, '-') }} artifacts: flut-renamer-release/*