added theming #245
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 and Release Applications | |
| on: | |
| push: | |
| branches: | |
| - develop | |
| workflow_dispatch: | |
| env: | |
| FLUTTER_VERSION: '3.44.0' | |
| STRAVA_CLIENT_ID: ${{ secrets.STRAVA_CLIENT_ID }} | |
| STRAVA_CLIENT_SECRET: ${{ secrets.STRAVA_CLIENT_SECRET }} | |
| INTERVALS_CLIENT_ID: ${{ secrets.INTERVALS_CLIENT_ID }} | |
| INTERVALS_CLIENT_SECRET: ${{ secrets.INTERVALS_CLIENT_SECRET }} | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| jobs: | |
| prepare: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| version: ${{ steps.set_version.outputs.version }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| # Download and extract latest SmartSpin2k firmware.bin from GitHub release | |
| - name: Download and extract latest SmartSpin2k firmware | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| set -e | |
| mkdir -p assets | |
| # Get latest release info | |
| release_json=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \ | |
| https://api.github.com/repos/doudar/SmartSpin2k/releases/latest) | |
| # Find .bin.zip asset URL | |
| asset_url=$(echo "$release_json" | grep 'browser_download_url' | grep '.bin.zip' | head -n1 | cut -d '"' -f4) | |
| if [ -z "$asset_url" ]; then | |
| echo "No .bin.zip asset found in latest release!" >&2 | |
| exit 1 | |
| fi | |
| echo "Downloading: $asset_url" | |
| curl -L -o /tmp/firmware.zip "$asset_url" | |
| unzip -o /tmp/firmware.zip -d /tmp/firmware_extracted | |
| if [ ! -f /tmp/firmware_extracted/firmware.bin ]; then | |
| echo "firmware.bin not found in zip!" >&2 | |
| exit 1 | |
| fi | |
| mv /tmp/firmware_extracted/firmware.bin assets/firmware.bin | |
| echo "Firmware placed at assets/firmware.bin" | |
| # Extract version tag and write to assets/version.txt | |
| version_tag=$(echo "$release_json" | grep '"tag_name"' | head -n1 | cut -d '"' -f4) | |
| if [ -z "$version_tag" ]; then | |
| echo "No version tag found in release!" >&2 | |
| exit 1 | |
| fi | |
| echo "$version_tag" > assets/version.txt | |
| echo "Version written to assets/version.txt: $version_tag" | |
| # Commit and push firmware.bin and version.txt to the repository | |
| - name: Commit, push, and open PR for updated firmware and version | |
| if: github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/main' | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| set -e | |
| git config --global user.name "github-actions[bot]" | |
| git config --global user.email "github-actions[bot]@users.noreply.github.com" | |
| git fetch origin | |
| git checkout ${{ github.ref_name }} | |
| git add assets/firmware.bin assets/version.txt | |
| if git diff --cached --quiet; then | |
| echo "No changes to commit." | |
| exit 0 | |
| fi | |
| git commit -m "chore: update firmware.bin and version.txt from latest SmartSpin2k release" | |
| # Try to push to the current branch (will fail if protected) | |
| if git push origin HEAD:${{ github.ref_name }}; then | |
| echo "Pushed directly to ${{ github.ref_name }}." | |
| exit 0 | |
| fi | |
| # If push fails, create a new branch and open a PR | |
| update_branch="auto/firmware-update-$(date +%Y%m%d%H%M%S)" | |
| git checkout -b "$update_branch" | |
| git push origin "$update_branch" | |
| echo "Creating pull request to ${{ github.ref_name }}..." | |
| # Install GitHub CLI if not present | |
| if ! command -v gh >/dev/null 2>&1; then | |
| echo "Installing GitHub CLI..." | |
| sudo apt-get update && sudo apt-get install -y gh | |
| fi | |
| # Use GH_TOKEN for authentication (no gh auth login needed in CI) | |
| gh pr create --base "${{ github.ref_name }}" --head "$update_branch" --title "chore: update firmware.bin and version.txt from latest SmartSpin2k release" --body "Automated update of firmware.bin and version.txt from the latest SmartSpin2k release." | |
| - name: Extract version from pubspec.yaml | |
| id: extract_version | |
| run: | | |
| VERSION=$(grep 'version: ' pubspec.yaml | sed 's/version: //' | xargs) | |
| echo "VERSION=${VERSION}" >> $GITHUB_ENV | |
| - name: Check if tag exists | |
| id: check_tag | |
| run: | | |
| TAG_EXISTS=$(git tag -l "$VERSION") | |
| if [[ "$TAG_EXISTS" == "$VERSION" ]]; then | |
| SUFFIX=1 | |
| NEW_TAG="$VERSION-$SUFFIX" | |
| while [[ $(git tag -l "$NEW_TAG") == "$NEW_TAG" ]]; do | |
| SUFFIX=$((SUFFIX+1)) | |
| NEW_TAG="$VERSION-$SUFFIX" | |
| done | |
| echo "NEW_TAG=$NEW_TAG" >> $GITHUB_ENV | |
| else | |
| echo "NEW_TAG=$VERSION" >> $GITHUB_ENV | |
| fi | |
| - name: Set output | |
| id: set_version | |
| run: echo "version=$NEW_TAG" >> "$GITHUB_OUTPUT" | |
| build-android: | |
| needs: prepare | |
| runs-on: ubuntu-latest | |
| env: | |
| GRADLE_OPTS: -Dorg.gradle.vfs.watch=false | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Setup Java | |
| uses: actions/setup-java@v4 | |
| with: | |
| java-version: '21' | |
| distribution: 'temurin' | |
| - name: Setup Flutter | |
| uses: subosito/flutter-action@v2 | |
| with: | |
| flutter-version: ${{ env.FLUTTER_VERSION }} | |
| channel: stable | |
| cache: true | |
| - name: Accept Android SDK licenses | |
| shell: bash | |
| run: | | |
| yes | sdkmanager --licenses || true | |
| sdkmanager --install "platforms;android-36" "build-tools;36.0.0" || true | |
| - name: Create env.local.dart | |
| env: | |
| STRAVA_CLIENT_ID: ${{ secrets.STRAVA_CLIENT_ID }} | |
| STRAVA_CLIENT_SECRET: ${{ secrets.STRAVA_CLIENT_SECRET }} | |
| INTERVALS_CLIENT_ID: ${{ secrets.INTERVALS_CLIENT_ID }} | |
| INTERVALS_CLIENT_SECRET: ${{ secrets.INTERVALS_CLIENT_SECRET }} | |
| run: | | |
| mkdir -p lib/config | |
| umask 077 | |
| cat > lib/config/env.local.dart <<EOL | |
| class Environment { | |
| static const String stravaClientId = '${STRAVA_CLIENT_ID}'; | |
| static const String stravaClientSecret = '${STRAVA_CLIENT_SECRET}'; | |
| static const String intervalsClientId = '${INTERVALS_CLIENT_ID}'; | |
| static const String intervalsClientSecret = '${INTERVALS_CLIENT_SECRET}'; | |
| static bool get hasStravaConfig => | |
| stravaClientId.isNotEmpty && stravaClientSecret.isNotEmpty; | |
| static bool get hasIntervalsConfig => | |
| intervalsClientId.isNotEmpty && intervalsClientSecret.isNotEmpty; | |
| } | |
| EOL | |
| - name: Configure Android signing | |
| env: | |
| SIGNING_KEY: ${{ secrets.SIGNING_KEY }} | |
| KEY_STORE_PASSWORD: ${{ secrets.KEY_STORE_PASSWORD }} | |
| KEY_ALIAS: ${{ secrets.KEY_ALIAS }} | |
| KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }} | |
| run: | | |
| if [ -z "$SIGNING_KEY" ]; then | |
| echo "No signing key provided; using debug signing." | |
| exit 0 | |
| fi | |
| echo "$SIGNING_KEY" | base64 -d > android/app/release.keystore | |
| echo "KEYSTORE_PATH=$PWD/android/app/release.keystore" >> $GITHUB_ENV | |
| echo "KEY_STORE_PASSWORD=$KEY_STORE_PASSWORD" >> $GITHUB_ENV | |
| echo "KEY_ALIAS=$KEY_ALIAS" >> $GITHUB_ENV | |
| echo "KEY_PASSWORD=$KEY_PASSWORD" >> $GITHUB_ENV | |
| - name: Build Android APK | |
| run: flutter build apk | |
| - name: Create artifacts | |
| run: | | |
| mkdir -p artifacts | |
| mv build/app/outputs/flutter-apk/app-release.apk artifacts/ss2kconfigapp-${{ needs.prepare.outputs.version }}.apk | |
| - name: Upload artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: android-artifacts | |
| path: artifacts/ | |
| build-macos: | |
| needs: prepare | |
| runs-on: macos-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Setup Flutter | |
| uses: subosito/flutter-action@v2 | |
| with: | |
| flutter-version: ${{ env.FLUTTER_VERSION }} | |
| channel: stable | |
| cache: true | |
| # Debug environment variables | |
| - name: Debug Environment Variables | |
| run: | | |
| echo "Checking environment variables (secrets will be masked):" | |
| env | grep -i STRAVA || true | |
| - name: Create env.local.dart | |
| env: | |
| STRAVA_CLIENT_ID: ${{ secrets.STRAVA_CLIENT_ID }} | |
| STRAVA_CLIENT_SECRET: ${{ secrets.STRAVA_CLIENT_SECRET }} | |
| INTERVALS_CLIENT_ID: ${{ secrets.INTERVALS_CLIENT_ID }} | |
| INTERVALS_CLIENT_SECRET: ${{ secrets.INTERVALS_CLIENT_SECRET }} | |
| run: | | |
| mkdir -p lib/config | |
| umask 077 | |
| cat > lib/config/env.local.dart <<EOL | |
| class Environment { | |
| static const String stravaClientId = '${STRAVA_CLIENT_ID}'; | |
| static const String stravaClientSecret = '${STRAVA_CLIENT_SECRET}'; | |
| static const String intervalsClientId = '${INTERVALS_CLIENT_ID}'; | |
| static const String intervalsClientSecret = '${INTERVALS_CLIENT_SECRET}'; | |
| static bool get hasStravaConfig => | |
| stravaClientId.isNotEmpty && stravaClientSecret.isNotEmpty; | |
| static bool get hasIntervalsConfig => | |
| intervalsClientId.isNotEmpty && intervalsClientSecret.isNotEmpty; | |
| } | |
| EOL | |
| # Verify file exists but don't show contents | |
| ls -l lib/config/env.local.dart | |
| - name: Build iOS App | |
| run: flutter build ios --release --no-codesign | |
| - name: Build macOS App | |
| run: flutter build macos --release | |
| - name: Create artifacts | |
| run: | | |
| mkdir -p artifacts | |
| zip -r artifacts/ss2kconfigapp-${{ needs.prepare.outputs.version }}.zip build/ios/iphoneos build/macos/Build/Products/Release | |
| # Clean up sensitive files | |
| - name: Clean up env.local.dart | |
| if: always() | |
| run: | | |
| if [ -f lib/config/env.local.dart ]; then | |
| rm lib/config/env.local.dart | |
| echo "Cleaned up env.local.dart" | |
| fi | |
| - name: Upload artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: macos-artifacts | |
| path: artifacts/ | |
| build-linux: | |
| needs: prepare | |
| # Use native runners for each architecture (amd64 & arm64) instead of emulation | |
| runs-on: ${{ matrix.runner }} | |
| strategy: | |
| matrix: | |
| include: | |
| - arch: amd64 | |
| runner: ubuntu-latest | |
| - arch: arm64 | |
| runner: ubuntu-24.04-arm | |
| steps: | |
| - uses: actions/checkout@v4 | |
| # Use official action for amd64 | |
| - name: Setup Flutter (amd64) | |
| if: matrix.arch == 'amd64' | |
| uses: subosito/flutter-action@v2 | |
| with: | |
| flutter-version: ${{ env.FLUTTER_VERSION }} | |
| channel: stable | |
| cache: true | |
| # Manual install for arm64 (action currently fails to resolve some versions on ubuntu-24.04-arm) | |
| - name: Setup Flutter (arm64 manual) | |
| if: matrix.arch == 'arm64' | |
| run: | | |
| set -e | |
| sudo apt-get update | |
| sudo DEBIAN_FRONTEND=noninteractive apt-get install -y git curl unzip xz-utils zip | |
| git clone https://github.com/flutter/flutter.git -b "$FLUTTER_VERSION" --depth 1 $HOME/flutter | |
| echo "$HOME/flutter/bin" >> $GITHUB_PATH | |
| $HOME/flutter/bin/flutter config --no-analytics | |
| $HOME/flutter/bin/flutter doctor -v || true | |
| - name: Create env.local.dart | |
| env: | |
| STRAVA_CLIENT_ID: ${{ secrets.STRAVA_CLIENT_ID }} | |
| STRAVA_CLIENT_SECRET: ${{ secrets.STRAVA_CLIENT_SECRET }} | |
| INTERVALS_CLIENT_ID: ${{ secrets.INTERVALS_CLIENT_ID }} | |
| INTERVALS_CLIENT_SECRET: ${{ secrets.INTERVALS_CLIENT_SECRET }} | |
| run: | | |
| mkdir -p lib/config | |
| umask 077 | |
| cat > lib/config/env.local.dart <<EOL | |
| class Environment { | |
| static const String stravaClientId = '${STRAVA_CLIENT_ID}'; | |
| static const String stravaClientSecret = '${STRAVA_CLIENT_SECRET}'; | |
| static const String intervalsClientId = '${INTERVALS_CLIENT_ID}'; | |
| static const String intervalsClientSecret = '${INTERVALS_CLIENT_SECRET}'; | |
| static bool get hasStravaConfig => | |
| stravaClientId.isNotEmpty && stravaClientSecret.isNotEmpty; | |
| static bool get hasIntervalsConfig => | |
| intervalsClientId.isNotEmpty && intervalsClientSecret.isNotEmpty; | |
| } | |
| EOL | |
| - name: Install Linux dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo DEBIAN_FRONTEND=noninteractive apt-get install -y \ | |
| libgtk-3-dev libx11-dev pkg-config cmake ninja-build \ | |
| libblkid-dev liblzma-dev libsecret-1-dev libjsoncpp-dev \ | |
| libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libunwind-dev | |
| - name: Enable Linux Desktop | |
| run: flutter config --enable-linux-desktop | |
| - name: Build Linux App | |
| run: | | |
| # Install additional build dependencies (clang & runtime libs) | |
| sudo apt-get update | |
| sudo DEBIAN_FRONTEND=noninteractive apt-get install -y \ | |
| clang libstdc++-12-dev libglu1-mesa fontconfig libpulse0 || true | |
| # Handle ALSA time64 transition on Ubuntu 24.04 (libasound2t64) | |
| sudo DEBIAN_FRONTEND=noninteractive apt-get install -y libasound2 || \ | |
| sudo DEBIAN_FRONTEND=noninteractive apt-get install -y libasound2t64 || true | |
| export CXX=clang++ | |
| flutter config --no-analytics | |
| flutter pub get | |
| # Build (native arch) | |
| flutter build linux --release -v | |
| - name: Create Debian Package | |
| run: | | |
| # Create package directory structure | |
| mkdir -p debian/DEBIAN | |
| mkdir -p debian/usr/bin | |
| mkdir -p debian/usr/share/applications | |
| mkdir -p debian/usr/share/icons/hicolor/256x256/apps | |
| # Create control file | |
| cat > debian/DEBIAN/control <<EOL | |
| Package: ss2kconfigapp | |
| Version: ${{ needs.prepare.outputs.version }} | |
| Section: utils | |
| Priority: optional | |
| Architecture: ${{ matrix.arch }} | |
| Maintainer: SmartSpin2k Team | |
| Description: SmartSpin2k Configuration Application | |
| A Flutter application for configuring and controlling SmartSpin2k devices. | |
| EOL | |
| # Copy application files based on architecture | |
| BUILD_PATH="" | |
| if [ "${{ matrix.arch }}" = "arm64" ]; then | |
| BUILD_PATH="build/linux/arm64/release/bundle" | |
| else | |
| BUILD_PATH="build/linux/x64/release/bundle" | |
| fi | |
| # Verify build path exists | |
| if [ ! -d "$BUILD_PATH" ]; then | |
| echo "Error: Build output not found at $BUILD_PATH" | |
| ls -la build/linux/ | |
| exit 1 | |
| fi | |
| # Copy files | |
| echo "Copying files from $BUILD_PATH to debian/usr/bin/" | |
| cp -rv "$BUILD_PATH"/* debian/usr/bin/ | |
| # Copy icon | |
| cp assets/icons/ss2kv3.png debian/usr/share/icons/hicolor/256x256/apps/ss2kconfigapp.png | |
| # Create desktop file | |
| cat > debian/usr/share/applications/ss2kconfigapp.desktop <<EOL | |
| [Desktop Entry] | |
| Name=SmartSpin2k Config App | |
| Exec=/usr/bin/ss2kconfigapp | |
| Icon=ss2kconfigapp | |
| Type=Application | |
| Categories=Utility; | |
| EOL | |
| # Set permissions | |
| chmod 755 debian/usr/bin/ss2kconfigapp | |
| chmod -R 755 debian/DEBIAN | |
| # Build the package with architecture in filename | |
| dpkg-deb --build debian ss2kconfigapp-${{ matrix.arch }}.deb | |
| - name: Create artifacts | |
| run: | | |
| mkdir -p artifacts | |
| mv ss2kconfigapp-${{ matrix.arch }}.deb artifacts/ | |
| - name: Upload artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: linux-artifacts-${{ matrix.arch }} | |
| path: artifacts/ | |
| build-windows: | |
| needs: prepare | |
| runs-on: windows-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Setup Flutter | |
| uses: subosito/flutter-action@v2 | |
| with: | |
| flutter-version: ${{ env.FLUTTER_VERSION }} | |
| channel: stable | |
| cache: true | |
| - name: Install Inno Setup | |
| run: choco install innosetup --no-progress -y | |
| - name: Create env.local.dart | |
| shell: bash | |
| env: | |
| STRAVA_CLIENT_ID: ${{ secrets.STRAVA_CLIENT_ID }} | |
| STRAVA_CLIENT_SECRET: ${{ secrets.STRAVA_CLIENT_SECRET }} | |
| INTERVALS_CLIENT_ID: ${{ secrets.INTERVALS_CLIENT_ID }} | |
| INTERVALS_CLIENT_SECRET: ${{ secrets.INTERVALS_CLIENT_SECRET }} | |
| run: | | |
| mkdir -p lib/config | |
| umask 077 | |
| cat > lib/config/env.local.dart <<EOL | |
| class Environment { | |
| static const String stravaClientId = '${STRAVA_CLIENT_ID}'; | |
| static const String stravaClientSecret = '${STRAVA_CLIENT_SECRET}'; | |
| static const String intervalsClientId = '${INTERVALS_CLIENT_ID}'; | |
| static const String intervalsClientSecret = '${INTERVALS_CLIENT_SECRET}'; | |
| static bool get hasStravaConfig => | |
| stravaClientId.isNotEmpty && stravaClientSecret.isNotEmpty; | |
| static bool get hasIntervalsConfig => | |
| intervalsClientId.isNotEmpty && intervalsClientSecret.isNotEmpty; | |
| } | |
| EOL | |
| - name: Enable Windows Desktop | |
| run: flutter config --enable-windows-desktop | |
| - name: Fetch dependencies | |
| run: flutter pub get | |
| - name: Preload fvp Windows SDK | |
| shell: pwsh | |
| run: | | |
| $ErrorActionPreference = 'Stop' | |
| $deps = Get-Content '.flutter-plugins-dependencies' -Raw | ConvertFrom-Json | |
| $fvp = $deps.plugins.windows | Where-Object { $_.name -eq 'fvp' } | Select-Object -First 1 | |
| if (-not $fvp) { | |
| Write-Host 'fvp is not registered for Windows; skipping SDK preload.' | |
| exit 0 | |
| } | |
| $fvpWindowsDir = Join-Path $fvp.path 'windows' | |
| $sdkMarker = Join-Path $fvpWindowsDir 'mdk-sdk\lib\cmake\FindMDK.cmake' | |
| if (Test-Path $sdkMarker) { | |
| Write-Host "fvp MDK SDK already exists at $fvpWindowsDir" | |
| exit 0 | |
| } | |
| $packageName = 'mdk-sdk-windows-x64.7z' | |
| $baseUrl = if ($env:FVP_DEPS_URL -match '^https?://') { | |
| $env:FVP_DEPS_URL.TrimEnd('/') | |
| } else { | |
| 'https://downloads.sourceforge.net/project/mdk-sdk/nightly' | |
| } | |
| $archivePath = Join-Path $fvpWindowsDir $packageName | |
| $downloadUrl = "$baseUrl/$packageName" | |
| if ($baseUrl -like 'https://sourceforge.net/*') { | |
| $downloadUrl = "$downloadUrl/download" | |
| } | |
| Write-Host "Downloading $packageName from $downloadUrl" | |
| Invoke-WebRequest -Uri $downloadUrl -OutFile $archivePath | |
| [byte[]] $signature = Get-Content -Path $archivePath -AsByteStream -TotalCount 6 | |
| $expectedSignature = @(0x37, 0x7a, 0xbc, 0xaf, 0x27, 0x1c) | |
| $is7zArchive = $signature.Length -eq $expectedSignature.Length | |
| for ($i = 0; $i -lt $expectedSignature.Length -and $is7zArchive; $i++) { | |
| $is7zArchive = $signature[$i] -eq $expectedSignature[$i] | |
| } | |
| if (-not $is7zArchive) { | |
| throw "Downloaded file is not a 7z archive. SourceForge may have returned an HTML page instead of $packageName." | |
| } | |
| # fvp 0.37.2 lets CMake extract through Flutter's .plugin_symlinks path, | |
| # which fails on current Windows runners. Extract in the real pub-cache path. | |
| Push-Location $fvpWindowsDir | |
| try { | |
| cmake -E tar xvf $archivePath | |
| } finally { | |
| Pop-Location | |
| } | |
| if (-not (Test-Path $sdkMarker)) { | |
| throw "Failed to preload fvp MDK SDK into $fvpWindowsDir" | |
| } | |
| - name: Build Windows App | |
| run: flutter build windows --release | |
| - name: Create Inno Setup installer | |
| shell: bash | |
| env: | |
| VERSION: ${{ needs.prepare.outputs.version }} | |
| run: | | |
| mkdir -p artifacts | |
| cat > installer.iss <<'EOL' | |
| [Setup] | |
| AppName=SmartSpin2k Config App | |
| AppVersion={#Version} | |
| AppPublisher=SmartSpin2k LLC | |
| DefaultDirName={pf}\SmartSpin2k Config App | |
| SetupIconFile=windows\\runner\\resources\\app_icon.ico | |
| UninstallDisplayIcon={app}\\ss2kconfigapp.exe | |
| OutputDir=artifacts | |
| OutputBaseFilename=ss2kconfigapp-{#Version}-windows | |
| Compression=lzma2 | |
| SolidCompression=yes | |
| ArchitecturesInstallIn64BitMode=x64 | |
| [Files] | |
| ; Flutter builds Windows x64 into build/windows/x64/runner/Release | |
| Source:"build\\windows\\x64\\runner\\Release\\*"; DestDir:"{app}"; Flags: recursesubdirs createallsubdirs | |
| [Icons] | |
| Name:"{group}\\SmartSpin2k Config App"; Filename:"{app}\\ss2kconfigapp.exe" | |
| Name:"{commondesktop}\\SmartSpin2k Config App"; Filename:"{app}\\ss2kconfigapp.exe"; Tasks: desktopicon | |
| [Tasks] | |
| Name: "desktopicon"; Description: "Create a &desktop icon"; GroupDescription: "Additional shortcuts:"; Flags: unchecked | |
| EOL | |
| # Inject version into installer script | |
| sed -i "s/{#Version}/${VERSION}/g" installer.iss | |
| # Run Inno Setup Compiler | |
| iscc installer.iss | |
| - name: Upload artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: windows-artifacts | |
| path: artifacts/ | |
| create-release: | |
| needs: [prepare, build-android, build-macos, build-linux, build-windows] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Download all artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| path: all-artifacts | |
| - name: Prepare release bundle | |
| run: | | |
| mkdir -p release | |
| cp all-artifacts/android-artifacts/ss2kconfigapp-${{ needs.prepare.outputs.version }}.apk release/ss2kconfigapp-${{ needs.prepare.outputs.version }}.apk | |
| cp all-artifacts/macos-artifacts/ss2kconfigapp-${{ needs.prepare.outputs.version }}.zip release/ss2kconfigapp-${{ needs.prepare.outputs.version }}.zip | |
| cp all-artifacts/linux-artifacts-amd64/ss2kconfigapp-amd64.deb release/ss2kconfigapp-${{ needs.prepare.outputs.version }}-amd64.deb | |
| cp all-artifacts/linux-artifacts-arm64/ss2kconfigapp-arm64.deb release/ss2kconfigapp-${{ needs.prepare.outputs.version }}-arm64.deb | |
| cp all-artifacts/windows-artifacts/ss2kconfigapp-${{ needs.prepare.outputs.version }}-windows.exe release/ss2kconfigapp-${{ needs.prepare.outputs.version }}-windows.exe | |
| - name: Create release | |
| uses: softprops/action-gh-release@v2 | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| with: | |
| tag_name: ${{ needs.prepare.outputs.version }} | |
| name: SmartSpin2kConfigApp ${{ needs.prepare.outputs.version }} | |
| draft: false | |
| prerelease: false | |
| generate_release_notes: true | |
| body: ${{ github.event.head_commit.message }} | |
| files: | | |
| release/ss2kconfigapp-${{ needs.prepare.outputs.version }}.apk | |
| release/ss2kconfigapp-${{ needs.prepare.outputs.version }}.zip | |
| release/ss2kconfigapp-${{ needs.prepare.outputs.version }}-amd64.deb | |
| release/ss2kconfigapp-${{ needs.prepare.outputs.version }}-arm64.deb | |
| release/ss2kconfigapp-${{ needs.prepare.outputs.version }}-windows.exe |