diff --git a/.github/scripts/android/build-fdroid.ps1 b/.github/scripts/android/build-fdroid.ps1 new file mode 100644 index 000000000..0d57f2772 --- /dev/null +++ b/.github/scripts/android/build-fdroid.ps1 @@ -0,0 +1,109 @@ +$rootPath = $env:GITHUB_WORKSPACE; + +$androidPath = $($rootPath + "\src\Android\Android.csproj"); +$appPath = $($rootPath + "\src\App\App.csproj"); + +$appKeystoreFdroidFilename = "app_fdroid-keystore.jks"; + +Write-Output "########################################" +Write-Output "##### Clean Android and App" +Write-Output "########################################" + +msbuild "$($androidPath)" "/t:Clean" "/p:Configuration=FDroid" +msbuild "$($appPath)" "/t:Clean" "/p:Configuration=FDroid" + +Write-Output "########################################" +Write-Output "##### Backup project files" +Write-Output "########################################" + +Copy-Item $androidManifest $($androidManifest + ".original"); +Copy-Item $androidPath $($androidPath + ".original"); +Copy-Item $appPath $($appPath + ".original"); + +Write-Output "########################################" +Write-Output "##### Cleanup Android Manifest" +Write-Output "########################################" + +$xml=New-Object XML; +$xml.Load($androidManifest); + +$nsAndroid=New-Object System.Xml.XmlNamespaceManager($xml.NameTable); +$nsAndroid.AddNamespace("android", "http://schemas.android.com/apk/res/android"); + +$firebaseReceiver1=$xml.SelectSingleNode(` + "/manifest/application/receiver[@android:name='com.google.firebase.iid.FirebaseInstanceIdInternalReceiver']", ` + $nsAndroid); +$firebaseReceiver1.ParentNode.RemoveChild($firebaseReceiver1); + +$firebaseReceiver2=$xml.SelectSingleNode(` + "/manifest/application/receiver[@android:name='com.google.firebase.iid.FirebaseInstanceIdReceiver']", ` + $nsAndroid); +$firebaseReceiver2.ParentNode.RemoveChild($firebaseReceiver2); + +$xml.Save($androidManifest); + +Write-Output "########################################" +Write-Output "##### Uninstall from Android.csproj" +Write-Output "########################################" + +$xml=New-Object XML; +$xml.Load($androidPath); + +$ns=New-Object System.Xml.XmlNamespaceManager($xml.NameTable); +$ns.AddNamespace("ns", $xml.DocumentElement.NamespaceURI); + +$firebaseNode=$xml.SelectSingleNode(` + "/ns:Project/ns:ItemGroup/ns:PackageReference[@Include='Xamarin.Firebase.Messaging']", $ns); +$firebaseNode.ParentNode.RemoveChild($firebaseNode); + +$safetyNetNode=$xml.SelectSingleNode(` + "/ns:Project/ns:ItemGroup/ns:PackageReference[@Include='Xamarin.GooglePlayServices.SafetyNet']", $ns); +$safetyNetNode.ParentNode.RemoveChild($safetyNetNode); + +$xml.Save($androidPath); + +Write-Output "########################################" +Write-Output "##### Uninstall from App.csproj" +Write-Output "########################################" + +$xml=New-Object XML; +$xml.Load($appPath); + +$appCenterNode=$xml.SelectSingleNode("/Project/ItemGroup/PackageReference[@Include='Microsoft.AppCenter.Crashes']"); +$appCenterNode.ParentNode.RemoveChild($appCenterNode); + +$xml.Save($appPath); + +Write-Output "########################################" +Write-Output "##### Restore NuGet" +Write-Output "########################################" + +Invoke-Expression "& nuget restore" + +Write-Output "########################################" +Write-Output "##### Build FDroid Configuration" +Write-Output "########################################" + +msbuild "$($androidPath)" "/p:Configuration=FDroid" + +Write-Output "########################################" +Write-Output "##### Sign FDroid Configuration" +Write-Output "########################################" + +msbuild "$($androidPath)" "/t:SignAndroidPackage" "/p:Configuration=FDroid" "/p:AndroidKeyStore=true" ` + "/p:AndroidSigningKeyAlias=bitwarden" "/p:AndroidSigningKeyPass=$($env:FDROID_KEYSTORE_PASSWORD)" ` + "/p:AndroidSigningKeyStore=$($appKeystoreFdroidFilename)" ` + "/p:AndroidSigningStorePass=$($env:FDROID_KEYSTORE_PASSWORD)" "/v:quiet" + +Write-Output "########################################" +Write-Output "##### Copy FDroid apk to project root" +Write-Output "########################################" + +$signedApkPath = $($rootPath + "\src\Android\bin\FDroid\com.x8bit.bitwarden-Signed.apk"); +$signedApkDestPath = $($rootPath + "\com.x8bit.bitwarden-fdroid.apk"); + +Copy-Item $signedApkPath $signedApkDestPath + +Write-Output "########################################" +Write-Output "##### Done" +Write-Output "########################################" diff --git a/.github/scripts/android/build-play.ps1 b/.github/scripts/android/build-play.ps1 new file mode 100644 index 000000000..d96ee4a35 --- /dev/null +++ b/.github/scripts/android/build-play.ps1 @@ -0,0 +1,52 @@ +$rootPath = $env:GITHUB_WORKSPACE; + +$androidPath = $($rootPath + "\src\Android\Android.csproj"); + +$appKeystorePlayFilename = "app_play-keystore.jks"; +$appKeystoreUploadFilename = "app_upload-keystore.jks"; + +Write-Output "########################################" +Write-Output "##### Build Release Configuration" +Write-Output "########################################" + +msbuild "$($androidPath)" "/p:Configuration=Release" + +Write-Output "########################################" +Write-Output "##### Sign Google Play Bundle Release Configuration" +Write-Output "########################################" + +msbuild "$($androidPath)" "/t:SignAndroidPackage" "/p:Configuration=Release" "/p:AndroidKeyStore=true" ` + "/p:AndroidSigningKeyAlias=upload" "/p:AndroidSigningKeyPass=$($env:UPLOAD_KEYSTORE_PASSWORD)" ` + "/p:AndroidSigningKeyStore=$($appKeystoreUploadFilename)" ` + "/p:AndroidSigningStorePass=$($env:UPLOAD_KEYSTORE_PASSWORD)" "/p:AndroidPackageFormat=aab" "/v:quiet" + +Write-Output "########################################" +Write-Output "##### Copy Google Play Bundle to project root" +Write-Output "########################################" + +$signedAabPath = $($rootPath + "\src\Android\bin\Release\com.x8bit.bitwarden-Signed.aab"); +$signedAabDestPath = $($rootPath + "\com.x8bit.bitwarden.aab"); + +Copy-Item $signedAabPath $signedAabDestPath + +Write-Output "########################################" +Write-Output "##### Sign APK Release Configuration" +Write-Output "########################################" + +msbuild "$($androidPath)" "/t:SignAndroidPackage" "/p:Configuration=Release" "/p:AndroidKeyStore=true" ` + "/p:AndroidSigningKeyAlias=bitwarden" "/p:AndroidSigningKeyPass=$($env:PLAY_KEYSTORE_PASSWORD)" ` + "/p:AndroidSigningKeyStore=$($appKeystorePlayFilename)" ` + "/p:AndroidSigningStorePass=$($env:PLAY_KEYSTORE_PASSWORD)" "/v:quiet" + +Write-Output "########################################" +Write-Output "##### Copy Release APK to project root" +Write-Output "########################################" + +$signedApkPath = $($rootPath + "\src\Android\bin\Release\com.x8bit.bitwarden-Signed.apk"); +$signedApkDestPath = $($rootPath + "\com.x8bit.bitwarden.apk"); + +Copy-Item $signedApkPath $signedApkDestPath + +Write-Output "########################################" +Write-Output "##### Done" +Write-Output "########################################" diff --git a/.github/scripts/android/decrypt-secrets.ps1 b/.github/scripts/android/decrypt-secrets.ps1 new file mode 100644 index 000000000..68748e166 --- /dev/null +++ b/.github/scripts/android/decrypt-secrets.ps1 @@ -0,0 +1,19 @@ +$rootPath = $env:GITHUB_WORKSPACE; + +$appKeystorePlayFilename = "app_play-keystore.jks"; +$appKeystorePlayPath = $($rootPath + "\src\Android\$appKeystorePlayFilename"); +$appKeystoreUploadFilename = "app_upload-keystore.jks"; +$appKeystoreUploadPath = $($rootPath + "\src\Android\$appKeystoreUploadFilename"); +$appKeystoreFdroidFilename = "app_fdroid-keystore.jks"; +$appKeystoreFdroidPath = $($rootPath + "\src\Android\$appKeystoreFdroidFilename"); +$googleServicesFilename = "google-services.json"; +$googleServicesPath = $($rootPath + "\src\Android\$googleServicesFilename"); + +Invoke-Expression ` + "& `"$decryptSecretPath`" -filename $($appKeystorePlayFilename + ".gpg") -output $($appKeystorePlayPath)" +Invoke-Expression ` + "& `"$decryptSecretPath`" -filename $($appKeystoreUploadFilename + ".gpg") -output $($appKeystoreUploadPath)" +Invoke-Expression ` + "& `"$decryptSecretPath`" -filename $($appKeystoreFdroidFilename + ".gpg") -output $($appKeystoreFdroidPath)" +Invoke-Expression ` + "& `"$decryptSecretPath`" -filename $($googleServicesFilename + ".gpg") -output $($googleServicesPath)" diff --git a/.github/scripts/android/increment-version.ps1 b/.github/scripts/android/increment-version.ps1 new file mode 100644 index 000000000..e6372aef3 --- /dev/null +++ b/.github/scripts/android/increment-version.ps1 @@ -0,0 +1,12 @@ +$rootPath = $env:GITHUB_WORKSPACE; +$buildNumber = 3000 + [int]$env:GITHUB_RUN_NUMBER; + +$androidManifest = $($rootPath + "\src\Android\Properties\AndroidManifest.xml"); + +$xml=New-Object XML; +$xml.Load($androidManifest); + +$node=$xml.SelectNodes("/manifest"); +$node.SetAttribute("android:versionCode", [string]$buildNumber); + +$xml.Save($androidManifest); diff --git a/.github/scripts/decrypt-secret.ps1 b/.github/scripts/decrypt-secret.ps1 new file mode 100644 index 000000000..0104a11b2 --- /dev/null +++ b/.github/scripts/decrypt-secret.ps1 @@ -0,0 +1,29 @@ +param ( + [Parameter(Mandatory=$true)] + [string] $filename, + [string] $output +) + +$homePath = $env:HOME +$rootPath = $env:GITHUB_WORKSPACE + +$secretInputPath = $rootPath + "/.github/secrets" +$input = $secretInputPath + $filename + +$passphrase = $env:DECRYPT_FILE_PASSWORD + +if ([string]::IsNullOrEmpty($output)) { + $secretOutputPath = $homePath + "/secrets/" + if($filename.EndsWith(".gpg")) { + $output = $secretOutputPath + $filename.TrimEnd(".gpg") + } else { + $output = $secretOutputPath + $filename + ".plaintext" + } +} + +if(!(Test-Path -Path $secretPath)) +{ + New-Item -ItemType Directory -Path $secretPath +} + +gpg --quiet --batch --yes --decrypt --passphrase="$passphrase" --output $output $input diff --git a/src/Android/fdroid-keystore.jks.gpg b/.github/secrets/app_fdroid-keystore.jks.gpg similarity index 100% rename from src/Android/fdroid-keystore.jks.gpg rename to .github/secrets/app_fdroid-keystore.jks.gpg diff --git a/src/Android/8bit.keystore.gpg b/.github/secrets/app_play-keystore.jks.gpg similarity index 100% rename from src/Android/8bit.keystore.gpg rename to .github/secrets/app_play-keystore.jks.gpg diff --git a/src/Android/upload-keystore.jks.gpg b/.github/secrets/app_upload-keystore.jks.gpg similarity index 100% rename from src/Android/upload-keystore.jks.gpg rename to .github/secrets/app_upload-keystore.jks.gpg diff --git a/src/Android/google-services.json.gpg b/.github/secrets/google-services.json.gpg similarity index 100% rename from src/Android/google-services.json.gpg rename to .github/secrets/google-services.json.gpg diff --git a/store/google/Publisher/play_creds.json.gpg b/.github/secrets/play_creds.json.gpg similarity index 100% rename from store/google/Publisher/play_creds.json.gpg rename to .github/secrets/play_creds.json.gpg diff --git a/store/fdroid/keystore.jks.gpg b/.github/secrets/store_fdroid-keystore.jks.gpg similarity index 100% rename from store/fdroid/keystore.jks.gpg rename to .github/secrets/store_fdroid-keystore.jks.gpg diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 59b6f27b5..a3b2af887 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,11 +1,14 @@ name: Build -on: push +on: + push: + branches: + - '!l10n_master' + - '!gh-pages' jobs: android: - runs-on: windows-latest steps: @@ -25,14 +28,47 @@ jobs: - name: Checkout repo uses: actions/checkout@v2 + - name: Decrypt secrets + run: ./github/scripts/android/decrypt-secrets.ps1 + env: + DECRYPT_FILE_PASSWORD: ${{ secrets.DECRYPT_FILE_PASSWORD }} + + - name: Increment version + run: ./github/scripts/android/increment-version.ps1 + - name: Restore packages run: nuget restore - - name: Build app - run: msbuild ./src/Android/Android.csproj /p:Configuration=Debug + - name: Build for Play Store + run: ./github/scripts/android/build-play.ps1 + env: + PLAY_KEYSTORE_PASSWORD: ${{ secrets.PLAY_KEYSTORE_PASSWORD }} + UPLOAD_KEYSTORE_PASSWORD: ${{ secrets.UPLOAD_KEYSTORE_PASSWORD }} + + - name: Upload Plat Store .aab + uses: actions/upload-artifact@v2 + with: + name: com.x8bit.bitwarden.aab + path: ./com.x8bit.bitwarden.aab + + - name: Upload Play Store .apk + uses: actions/upload-artifact@v2 + with: + name: com.x8bit.bitwarden.apk + path: ./com.x8bit.bitwarden.apk + + - name: Build for F-Droid Store + run: ./github/scripts/android/build-fdroid.ps1 + env: + FDROID_KEYSTORE_PASSWORD: ${{ secrets.FDROID_KEYSTORE_PASSWORD }} + + - name: Upload F-Droid .apk + uses: actions/upload-artifact@v2 + with: + name: com.x8bit.bitwarden-fdroid.apk + path: ./com.x8bit.bitwarden-fdroid.apk ios: - runs-on: macos-latest steps: