diff --git a/.github/workflows/release_android.yml b/.github/workflows/release_android.yml new file mode 100644 index 00000000..882dd700 --- /dev/null +++ b/.github/workflows/release_android.yml @@ -0,0 +1,112 @@ +name: Release Android + +on: + release: + types: [published] + +jobs: + release_android: + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Extract version from tag + run: | + TAG="${{ github.event.release.tag_name }}" + VERSION="${TAG#v}" + IFS='.' read -r -a parts <<< "$VERSION" + MAJOR="${parts[0]:-0}" + MINOR="${parts[1]:-0}" + PATCH="${parts[2]:-0}" + VERSION_CODE=$((MAJOR * 10000 + MINOR * 100 + PATCH)) + echo "APP_VERSION=$VERSION" >> $GITHUB_ENV + echo "APP_VERSION_CODE=$VERSION_CODE" >> $GITHUB_ENV + + - name: Install KVM and Android SDK (x86) + run: | + export ANDROID_SDK_ROOT=$HOME/android-sdk + export ANDROID_HOME=$ANDROID_SDK_ROOT + export PATH=$ANDROID_SDK_ROOT/cmdline-tools/latest/bin:$ANDROID_SDK_ROOT/platform-tools:$ANDROID_SDK_ROOT/emulator:$PATH + + mkdir -p $ANDROID_SDK_ROOT/cmdline-tools + + wget -q https://dl.google.com/android/repository/commandlinetools-linux-10406996_latest.zip + unzip -q commandlinetools-linux-*.zip -d $ANDROID_SDK_ROOT/cmdline-tools + mv $ANDROID_SDK_ROOT/cmdline-tools/cmdline-tools $ANDROID_SDK_ROOT/cmdline-tools/latest + chmod +x $ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager + + yes | $ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager --licenses + $ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager "platform-tools" "platforms;android-36" + + echo "ANDROID_SDK_ROOT=$ANDROID_SDK_ROOT" >> $GITHUB_ENV + echo "ANDROID_HOME=$ANDROID_SDK_ROOT" >> $GITHUB_ENV + echo "PATH=$ANDROID_SDK_ROOT/cmdline-tools/latest/bin:$ANDROID_SDK_ROOT/platform-tools:$PATH" >> $GITHUB_ENV + + - name: Install Android Build Tools + run: | + sdkmanager "build-tools;36.0.0" + sdkmanager --update + + - name: Install MAUI workloads + run: | + dotnet workload install maui-android + + - name: Restore packages + run: dotnet restore TransactionProcessor.Mobile.sln --source ${{ secrets.PUBLICFEEDURL }} --source ${{ secrets.PRIVATEFEED_URL }} --source https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet6/nuget/v3/index.json + + - name: Decode Android keystore + run: | + echo "${{ secrets.ANDROID_KEYSTORE }}" | base64 --decode > android_keystore.jks + + - name: Publish Android APK + run: | + dotnet publish TransactionProcessor.Mobile/TransactionProcessor.Mobile.csproj \ + -f net10.0-android \ + -c Release \ + --no-restore \ + /p:ApplicationDisplayVersion=${{ env.APP_VERSION }} \ + /p:ApplicationVersion=${{ env.APP_VERSION_CODE }} \ + /p:AndroidSigningKeyStore=$(pwd)/android_keystore.jks \ + /p:AndroidSigningKeyAlias=${{ secrets.ANDROID_KEY_ALIAS }} \ + /p:AndroidSigningKeyPass=${{ secrets.ANDROID_KEY_PASSWORD }} \ + /p:AndroidSigningStorePass=${{ secrets.ANDROID_KEYSTORE_PASSWORD }} + + - name: Upload APK to release + uses: softprops/action-gh-release@v1 + with: + files: TransactionProcessor.Mobile/bin/Release/net10.0-android/*-Signed.apk + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Upload Android APK artifact + uses: actions/upload-artifact@v4 + with: + name: android-apk + path: TransactionProcessor.Mobile/bin/Release/net10.0-android/*-Signed.apk + + - name: Clean up keystore + if: always() + run: rm -f android_keystore.jks + + deploy_to_staging: + needs: release_android + runs-on: [self-hosted, windows] + permissions: + contents: read + steps: + - name: Download Android APK artifact + uses: actions/download-artifact@v4 + with: + name: android-apk + path: android-apk + + - name: Copy Android APK to AppUpdates + shell: powershell + run: | + $dest = "C:\inetpub\wwwroot\AppUpdates\Android" + New-Item -ItemType Directory -Force -Path $dest | Out-Null + Copy-Item -Path "android-apk\*" -Destination $dest -Recurse -Force + Write-Host "Copied Android APK to $dest" diff --git a/.github/workflows/release_windows.yml b/.github/workflows/release_windows.yml new file mode 100644 index 00000000..4d5e0469 --- /dev/null +++ b/.github/workflows/release_windows.yml @@ -0,0 +1,111 @@ +name: Release Windows + +on: + release: + types: [published] + +jobs: + release_windows: + runs-on: windows-2022 + permissions: + contents: write + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Extract version from tag + shell: powershell + run: | + $tag = "${{ github.event.release.tag_name }}" + $version = $tag.TrimStart('v') + $parts = $version.Split('.') + $major = [int]($parts[0]) + $minor = if ($parts.Length -gt 1) { [int]($parts[1]) } else { 0 } + $patch = if ($parts.Length -gt 2) { [int]($parts[2]) } else { 0 } + $versionCode = $major * 10000 + $minor * 100 + $patch + echo "APP_VERSION=$version" >> $env:GITHUB_ENV + echo "APP_VERSION_CODE=$versionCode" >> $env:GITHUB_ENV + + - name: Setup MSBuild + uses: microsoft/setup-msbuild@v1.1 + with: + vs-prerelease: true + + - name: Install MAUI workloads + run: | + dotnet workload install maui + + - name: Restore packages + run: dotnet restore TransactionProcessor.Mobile.sln --source ${{ secrets.PUBLICFEEDURL }} --source ${{ secrets.PRIVATEFEED_URL }} --source https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet6/nuget/v3/index.json + + - name: Decrypt PFX File + run: | + echo "${{ secrets.WINDOWSSIGNINGCERT }}" > cert.pfx.asc + certutil -decode cert.pfx.asc cert.pfx + + - name: Add Cert to Store + run: certutil -user -q -p ${{ secrets.WINDOWSSIGNINGCERTPWD }} -importpfx cert.pfx NoRoot + + - name: Publish Windows App + run: | + dotnet publish TransactionProcessor.Mobile/TransactionProcessor.Mobile.csproj ` + -c Release ` + -f net10.0-windows10.0.19041.0 ` + --no-restore ` + /p:ApplicationDisplayVersion=${{ env.APP_VERSION }} ` + /p:ApplicationVersion=${{ env.APP_VERSION_CODE }} ` + /p:AppxPackageSigningEnabled=true ` + /p:PackageCertificateThumbprint="${{ secrets.WINDOWSSIGNINGCERTTHUMBPRINT }}" + + - name: Find MSIX package + shell: powershell + run: | + $msix = Get-ChildItem -Path "TransactionProcessor.Mobile/bin/Release/net10.0-windows10.0.19041.0/win-x64/AppPackages" -Recurse -Filter "*.msixbundle" | Select-Object -First 1 + if ($msix -eq $null) { + $msix = Get-ChildItem -Path "TransactionProcessor.Mobile/bin/Release/net10.0-windows10.0.19041.0/win-x64/AppPackages" -Recurse -Filter "*.msix" | Select-Object -First 1 + } + if ($msix -eq $null) { + Write-Error "No .msix or .msixbundle file found in AppPackages directory." + exit 1 + } + echo "MSIX_PATH=$($msix.FullName)" >> $env:GITHUB_ENV + + - name: Upload Windows app packages artifact + uses: actions/upload-artifact@v4 + with: + name: windows-app-packages + path: TransactionProcessor.Mobile/bin/Release/net10.0-windows10.0.19041.0/win-x64/AppPackages/ + + - name: Upload MSIX to release + uses: softprops/action-gh-release@v1 + with: + files: ${{ env.MSIX_PATH }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Clean up certificate + if: always() + run: | + Remove-Item -Force cert.pfx -ErrorAction SilentlyContinue + Remove-Item -Force cert.pfx.asc -ErrorAction SilentlyContinue + shell: powershell + + deploy_to_staging: + needs: release_windows + runs-on: [self-hosted, windows] + permissions: + contents: read + steps: + - name: Download Windows app packages artifact + uses: actions/download-artifact@v4 + with: + name: windows-app-packages + path: windows-app-packages + + - name: Copy Windows packages to AppUpdates + shell: powershell + run: | + $dest = "C:\inetpub\wwwroot\AppUpdates\Windows" + New-Item -ItemType Directory -Force -Path $dest | Out-Null + Copy-Item -Path "windows-app-packages\*" -Destination $dest -Recurse -Force + Write-Host "Copied Windows app packages to $dest"