mirror of
https://github.com/bitwarden/mobile.git
synced 2024-11-23 11:45:38 +01:00
[EC-655] Adds build variants to the mobile codebase using a CAKE script (#2161)
* Implemented CAKE build script * cake script now deals with all of iOS's .plists * cake now updates iOS bundleid's / Android packagename in codefiles * iOS Bundle ID / Name should be correctly handled now + refactor * tabs -> spaces * Additional code files are now handled by cake * Additional iOS codefile changes required * Android's Autofill Label is now changed * Removed dash from packagenames / bundleIDs * Fixed CFBundleURLName set * Added google-services.json to cake preprocessing * Add CAKE to build workflow - Android * Add debug * Updated cake's GitVersion.Tool * AndroidManifest manual parsing needs to happen first * Added Android Constants to build.cake * [SG-747] Add Android QA build to mobile build pipeline (#2144) * Add checkout depth * Build and upload QA artifacts * Remove missing .aab * Update build.yml * Update paths * Update var names * Build and upload QA artifacts * Add in matrix to path. * Lets not fail all the jobs if something pukes * Add in some flow logic for QA * We need strings in pwsh * Remove extra quotes * Testing, remove uneeded runs * Test folder items * [SG-747] Added more debug info to find problem * [SG-747] copy signed apk to correct file name for each app variant * [SG-747] try to fix if statement * [SG-747] separate decrypt google services into another step with condition. * [SG-747] fixed typo and line break * [SG-747] added debug to check output path * [SG-747] fix package name * [SG-747] Fixed condition of step execution * [SG-747] test if cases * [SG-747] Code clean up * [SG-747] Added FDroid and iOS steps. * [SG-747] Removed test step * [SG-747] Step name changes * Update condition to be more inclusive Co-authored-by: Álison Fernandes <vvolkgang@users.noreply.github.com> * [SG-747] Expand if condition to allow more build types other than QA * [SG-747] removed execution condition Co-authored-by: mimartin12 <77340197+mimartin12@users.noreply.github.com> * Apply suggestions from code review Linter suggestions Co-authored-by: mimartin12 <77340197+mimartin12@users.noreply.github.com> Co-authored-by: Micaiah Martin <mmartin@bitwarden.com> Co-authored-by: mimartin12 <77340197+mimartin12@users.noreply.github.com> Co-authored-by: Álison Fernandes <vvolkgang@users.noreply.github.com> Co-authored-by: Todd Martin <106564991+trmartin4@users.noreply.github.com> * Base bundle ID refactor and cleaned up TODOs - Added base vars for the bundle IDs - Removed a TODO and explained the remaining ones - Commented a unused var, keeping it in the code as this might be useful later Co-authored-by: Micaiah Martin <mmartin@bitwarden.com> Co-authored-by: Federico Andrés Maccaroni <fedemkr@gmail.com> Co-authored-by: Todd Martin <tmartin@bitwarden.com> Co-authored-by: André Bispo <abispo@bitwarden.com> Co-authored-by: mimartin12 <77340197+mimartin12@users.noreply.github.com> Co-authored-by: Todd Martin <106564991+trmartin4@users.noreply.github.com>
This commit is contained in:
parent
5a4c81bd75
commit
99472d2548
@ -7,6 +7,12 @@
|
|||||||
"commands": [
|
"commands": [
|
||||||
"dotnet-format"
|
"dotnet-format"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"cake.tool": {
|
||||||
|
"version": "2.2.0",
|
||||||
|
"commands": [
|
||||||
|
"dotnet-cake"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
63
.github/workflows/build.yml
vendored
63
.github/workflows/build.yml
vendored
@ -59,6 +59,10 @@ jobs:
|
|||||||
name: Android
|
name: Android
|
||||||
runs-on: windows-2022
|
runs-on: windows-2022
|
||||||
needs: setup
|
needs: setup
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
variant: ['prod', 'qa']
|
||||||
steps:
|
steps:
|
||||||
- name: Setup NuGet
|
- name: Setup NuGet
|
||||||
uses: nuget/setup-nuget@b2bc17b761a1d88cab755a776c7922eb26eefbfa # v1.0.6
|
uses: nuget/setup-nuget@b2bc17b761a1d88cab755a776c7922eb26eefbfa # v1.0.6
|
||||||
@ -87,7 +91,6 @@ jobs:
|
|||||||
Write-Host "components were not installed"
|
Write-Host "components were not installed"
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
- name: Print environment
|
- name: Print environment
|
||||||
run: |
|
run: |
|
||||||
nuget help | grep Version
|
nuget help | grep Version
|
||||||
@ -98,7 +101,8 @@ jobs:
|
|||||||
|
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846
|
uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
- name: Decrypt secrets
|
- name: Decrypt secrets
|
||||||
env:
|
env:
|
||||||
DECRYPT_FILE_PASSWORD: ${{ secrets.DECRYPT_FILE_PASSWORD }}
|
DECRYPT_FILE_PASSWORD: ${{ secrets.DECRYPT_FILE_PASSWORD }}
|
||||||
@ -109,12 +113,17 @@ jobs:
|
|||||||
--output ./src/Android/app_play-keystore.jks ./.github/secrets/app_play-keystore.jks.gpg
|
--output ./src/Android/app_play-keystore.jks ./.github/secrets/app_play-keystore.jks.gpg
|
||||||
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
|
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
|
||||||
--output ./src/Android/app_upload-keystore.jks ./.github/secrets/app_upload-keystore.jks.gpg
|
--output ./src/Android/app_upload-keystore.jks ./.github/secrets/app_upload-keystore.jks.gpg
|
||||||
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
|
|
||||||
--output ./src/Android/google-services.json ./.github/secrets/google-services.json.gpg
|
|
||||||
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
|
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
|
||||||
--output $HOME/secrets/play_creds.json ./.github/secrets/play_creds.json.gpg
|
--output $HOME/secrets/play_creds.json ./.github/secrets/play_creds.json.gpg
|
||||||
shell: bash
|
shell: bash
|
||||||
|
- name: Decrypt secrets - Google Services
|
||||||
|
if: ${{ matrix.variant == 'prod' }}
|
||||||
|
env:
|
||||||
|
DECRYPT_FILE_PASSWORD: ${{ secrets.DECRYPT_FILE_PASSWORD }}
|
||||||
|
run: |
|
||||||
|
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
|
||||||
|
--output ./src/Android/google-services.json ./.github/secrets/google-services.json.gpg
|
||||||
|
shell: bash
|
||||||
- name: Increment version
|
- name: Increment version
|
||||||
run: |
|
run: |
|
||||||
BUILD_NUMBER=$((3000 + $GITHUB_RUN_NUMBER))
|
BUILD_NUMBER=$((3000 + $GITHUB_RUN_NUMBER))
|
||||||
@ -142,26 +151,35 @@ jobs:
|
|||||||
run: dotnet test test/Core.Test/Core.Test.csproj
|
run: dotnet test test/Core.Test/Core.Test.csproj
|
||||||
|
|
||||||
- name: Build Play Store publisher
|
- name: Build Play Store publisher
|
||||||
|
if: ${{ matrix.variant == 'prod' }}
|
||||||
run: dotnet build ./store/google/Publisher/Publisher.csproj -p:Configuration=Release
|
run: dotnet build ./store/google/Publisher/Publisher.csproj -p:Configuration=Release
|
||||||
|
|
||||||
- name: Build for Play Store
|
- name: Setup Android build (${{ matrix.variant }})
|
||||||
|
run: dotnet cake build.cake --target Android --variant ${{ matrix.variant }}
|
||||||
|
|
||||||
|
- name: Build Android
|
||||||
run: |
|
run: |
|
||||||
$configuration = "Release";
|
$configuration = "Release";
|
||||||
|
|
||||||
Write-Output "########################################"
|
Write-Output "########################################"
|
||||||
Write-Output "##### Build $configuration Configuration"
|
Write-Output "##### Build $configuration Configuration"
|
||||||
Write-Output "########################################"
|
Write-Output "########################################"
|
||||||
|
|
||||||
msbuild "$($env:GITHUB_WORKSPACE + "/src/Android/Android.csproj")" "/p:Configuration=$configuration"
|
msbuild "$($env:GITHUB_WORKSPACE + "/src/Android/Android.csproj")" "/p:Configuration=$configuration"
|
||||||
|
|
||||||
shell: pwsh
|
shell: pwsh
|
||||||
|
|
||||||
- name: Sign for Play Store
|
- name: Sign Android Build
|
||||||
env:
|
env:
|
||||||
PLAY_KEYSTORE_PASSWORD: ${{ secrets.PLAY_KEYSTORE_PASSWORD }}
|
PLAY_KEYSTORE_PASSWORD: ${{ secrets.PLAY_KEYSTORE_PASSWORD }}
|
||||||
UPLOAD_KEYSTORE_PASSWORD: ${{ secrets.UPLOAD_KEYSTORE_PASSWORD }}
|
UPLOAD_KEYSTORE_PASSWORD: ${{ secrets.UPLOAD_KEYSTORE_PASSWORD }}
|
||||||
run: |
|
run: |
|
||||||
$androidPath = $($env:GITHUB_WORKSPACE + "/src/Android/Android.csproj");
|
$androidPath = $($env:GITHUB_WORKSPACE + "/src/Android/Android.csproj");
|
||||||
|
$packageName = "com.x8bit.bitwarden";
|
||||||
|
|
||||||
|
if ("${{ matrix.variant }}" -ne "prod")
|
||||||
|
{
|
||||||
|
$packageName = "com.x8bit.bitwarden.${{ matrix.variant }}";
|
||||||
|
}
|
||||||
Write-Output "########################################"
|
Write-Output "########################################"
|
||||||
Write-Output "##### Sign Google Play Bundle Release Configuration"
|
Write-Output "##### Sign Google Play Bundle Release Configuration"
|
||||||
Write-Output "########################################"
|
Write-Output "########################################"
|
||||||
@ -175,9 +193,8 @@ jobs:
|
|||||||
Write-Output "##### Copy Google Play Bundle to project root"
|
Write-Output "##### Copy Google Play Bundle to project root"
|
||||||
Write-Output "########################################"
|
Write-Output "########################################"
|
||||||
|
|
||||||
$signedAabPath = $($env:GITHUB_WORKSPACE + "/src/Android/bin/Release/com.x8bit.bitwarden-Signed.aab");
|
$signedAabPath = $($env:GITHUB_WORKSPACE + "/src/Android/bin/Release/$($packageName)-Signed.aab");
|
||||||
$signedAabDestPath = $($env:GITHUB_WORKSPACE + "/com.x8bit.bitwarden.aab");
|
$signedAabDestPath = $($env:GITHUB_WORKSPACE + "/$($packageName).aab");
|
||||||
|
|
||||||
Copy-Item $signedAabPath $signedAabDestPath
|
Copy-Item $signedAabPath $signedAabDestPath
|
||||||
|
|
||||||
Write-Output "########################################"
|
Write-Output "########################################"
|
||||||
@ -193,33 +210,41 @@ jobs:
|
|||||||
Write-Output "##### Copy Release APK to project root"
|
Write-Output "##### Copy Release APK to project root"
|
||||||
Write-Output "########################################"
|
Write-Output "########################################"
|
||||||
|
|
||||||
$signedApkPath = $($env:GITHUB_WORKSPACE + "/src/Android/bin/Release/com.x8bit.bitwarden-Signed.apk");
|
$signedApkPath = $($env:GITHUB_WORKSPACE + "/src/Android/bin/Release/$($packageName)-Signed.apk");
|
||||||
$signedApkDestPath = $($env:GITHUB_WORKSPACE + "/com.x8bit.bitwarden.apk");
|
$signedApkDestPath = $($env:GITHUB_WORKSPACE + "/$($packageName).apk");
|
||||||
|
|
||||||
Copy-Item $signedApkPath $signedApkDestPath
|
Copy-Item $signedApkPath $signedApkDestPath
|
||||||
shell: pwsh
|
shell: pwsh
|
||||||
|
- name: Upload Prod .aab artifact
|
||||||
- name: Upload Play Store .aab artifact
|
if: ${{ matrix.variant == 'prod' }}
|
||||||
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535
|
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535
|
||||||
with:
|
with:
|
||||||
name: com.x8bit.bitwarden.aab
|
name: com.x8bit.bitwarden.aab
|
||||||
path: ./com.x8bit.bitwarden.aab
|
path: ./com.x8bit.bitwarden.aab
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload Play Store .apk artifact
|
- name: Upload Prod .apk artifact
|
||||||
|
if: ${{ matrix.variant == 'prod' }}
|
||||||
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535
|
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535
|
||||||
with:
|
with:
|
||||||
name: com.x8bit.bitwarden.apk
|
name: com.x8bit.bitwarden.apk
|
||||||
path: ./com.x8bit.bitwarden.apk
|
path: ./com.x8bit.bitwarden.apk
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
|
- name: Upload Other .apk artifact
|
||||||
|
if: ${{ matrix.variant != 'prod' }}
|
||||||
|
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535
|
||||||
|
with:
|
||||||
|
name: com.x8bit.bitwarden.${{ matrix.variant }}.apk
|
||||||
|
path: ./com.x8bit.bitwarden.${{ matrix.variant }}.apk
|
||||||
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Deploy to Play Store
|
- name: Deploy to Play Store
|
||||||
if: |
|
if: ${{ matrix.variant == 'prod' && (( github.ref == 'refs/heads/master'
|
||||||
(github.ref == 'refs/heads/master'
|
|
||||||
&& needs.setup.outputs.rc_branch_exists == 0
|
&& needs.setup.outputs.rc_branch_exists == 0
|
||||||
&& needs.setup.outputs.hotfix_branch_exists == 0)
|
&& needs.setup.outputs.hotfix_branch_exists == 0)
|
||||||
|| (github.ref == 'refs/heads/rc' && needs.setup.outputs.hotfix_branch_exists == 0)
|
|| (github.ref == 'refs/heads/rc' && needs.setup.outputs.hotfix_branch_exists == 0)
|
||||||
|| github.ref == 'refs/heads/hotfix-rc'
|
|| github.ref == 'refs/heads/hotfix-rc' ) }}
|
||||||
run: |
|
run: |
|
||||||
PUBLISHER_PATH="$GITHUB_WORKSPACE/store/google/Publisher/bin/Release/netcoreapp3.1/Publisher.dll"
|
PUBLISHER_PATH="$GITHUB_WORKSPACE/store/google/Publisher/bin/Release/netcoreapp3.1/Publisher.dll"
|
||||||
CREDS_PATH="$HOME/secrets/play_creds.json"
|
CREDS_PATH="$HOME/secrets/play_creds.json"
|
||||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -209,3 +209,4 @@ FakesAssemblies/
|
|||||||
project.lock.json
|
project.lock.json
|
||||||
.DS_Store
|
.DS_Store
|
||||||
src/App/Css
|
src/App/Css
|
||||||
|
tools
|
||||||
|
345
build.cake
Normal file
345
build.cake
Normal file
@ -0,0 +1,345 @@
|
|||||||
|
#addin nuget:?package=Cake.FileHelpers&version=5.0.0
|
||||||
|
#addin nuget:?package=Cake.AndroidAppManifest&version=1.1.2
|
||||||
|
#addin nuget:?package=Cake.Plist&version=0.7.0
|
||||||
|
#addin nuget:?package=Cake.Incubator&version=7.0.0
|
||||||
|
#tool dotnet:?package=GitVersion.Tool&version=5.10.3
|
||||||
|
using Path = System.IO.Path;
|
||||||
|
|
||||||
|
var debugScript = Argument<bool>("debugScript", false);
|
||||||
|
var target = Argument("target", "Default");
|
||||||
|
var configuration = Argument("configuration", "Release");
|
||||||
|
var variant = Argument("variant", "dev");
|
||||||
|
|
||||||
|
abstract record VariantConfig(
|
||||||
|
string AppName,
|
||||||
|
string AndroidPackageName,
|
||||||
|
string iOSBundleId,
|
||||||
|
string ApsEnvironment
|
||||||
|
);
|
||||||
|
|
||||||
|
const string BASE_BUNDLE_ID_DROID = "com.x8bit.bitwarden";
|
||||||
|
const string BASE_BUNDLE_ID_IOS = "com.8bit.bitwarden";
|
||||||
|
|
||||||
|
record Dev(): VariantConfig("Bitwarden Dev", $"{BASE_BUNDLE_ID_DROID}.dev", $"{BASE_BUNDLE_ID_IOS}.dev", "development");
|
||||||
|
record QA(): VariantConfig("Bitwarden QA", $"{BASE_BUNDLE_ID_DROID}.qa", $"{BASE_BUNDLE_ID_IOS}.qa", "development");
|
||||||
|
record Beta(): VariantConfig("Bitwarden Beta", $"{BASE_BUNDLE_ID_DROID}.beta", $"{BASE_BUNDLE_ID_IOS}.beta", "production");
|
||||||
|
record Prod(): VariantConfig("Bitwarden", $"{BASE_BUNDLE_ID_DROID}", $"{BASE_BUNDLE_ID_IOS}", "production");
|
||||||
|
|
||||||
|
VariantConfig GetVariant() => variant.ToLower() switch{
|
||||||
|
"qa" => new QA(),
|
||||||
|
"beta" => new Beta(),
|
||||||
|
"prod" => new Prod(),
|
||||||
|
_ => new Dev()
|
||||||
|
};
|
||||||
|
|
||||||
|
GitVersion _gitVersion; //will be set by GetGitInfo task
|
||||||
|
var _slnPath = Path.Combine(""); //base path used to access files. If build.cake file is moved, just update this
|
||||||
|
string _androidPackageName = string.Empty; //will be set by UpdateAndroidManifest task
|
||||||
|
string CreateFeatureBranch(string prevVersionName, GitVersion git) => $"{prevVersionName}-{git.BranchName.Replace("/","-")}";
|
||||||
|
string GetVersionName(string prevVersionName, VariantConfig buildVariant, GitVersion git) => buildVariant is Prod? prevVersionName : CreateFeatureBranch(prevVersionName, git);
|
||||||
|
int CreateBuildNumber(int previousNumber) => ++previousNumber;
|
||||||
|
|
||||||
|
Task("GetGitInfo")
|
||||||
|
.Does(()=> {
|
||||||
|
_gitVersion = GitVersion(new GitVersionSettings());
|
||||||
|
|
||||||
|
if(debugScript)
|
||||||
|
{
|
||||||
|
Information($"GitVersion Dump:\n{_gitVersion.Dump()}");
|
||||||
|
}
|
||||||
|
|
||||||
|
Information("Git data Load successfully.");
|
||||||
|
});
|
||||||
|
|
||||||
|
#region Android
|
||||||
|
Task("UpdateAndroidAppIcon")
|
||||||
|
.Does(()=>{
|
||||||
|
//TODO we'll implement variant icons later
|
||||||
|
//manifest.ApplicationIcon = "@mipmap/ic_launcher";
|
||||||
|
Information($"Updated Androix App Icon with success");
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
Task("UpdateAndroidManifest")
|
||||||
|
.IsDependentOn("GetGitInfo")
|
||||||
|
.Does(()=>
|
||||||
|
{
|
||||||
|
var buildVariant = GetVariant();
|
||||||
|
var manifestPath = Path.Combine(_slnPath, "src", "Android", "Properties", "AndroidManifest.xml");
|
||||||
|
|
||||||
|
// Cake.AndroidAppManifest doesn't currently enable us to access nested items so, quick (not ideal) fix:
|
||||||
|
var manifestText = FileReadText(manifestPath);
|
||||||
|
manifestText = manifestText.Replace("com.x8bit.bitwarden.", buildVariant.AndroidPackageName + ".");
|
||||||
|
manifestText = manifestText.Replace("android:label=\"Bitwarden\"", $"android:label=\"{buildVariant.AppName}\"");
|
||||||
|
FileWriteText(manifestPath, manifestText);
|
||||||
|
|
||||||
|
var manifest = DeserializeAppManifest(manifestPath);
|
||||||
|
|
||||||
|
var prevVersionCode = manifest.VersionCode;
|
||||||
|
var prevVersionName = manifest.VersionName;
|
||||||
|
_androidPackageName = manifest.PackageName;
|
||||||
|
|
||||||
|
//manifest.VersionCode = CreateBuildNumber(prevVersionCode);
|
||||||
|
manifest.VersionName = GetVersionName(prevVersionName, buildVariant, _gitVersion);
|
||||||
|
manifest.PackageName = buildVariant.AndroidPackageName;
|
||||||
|
manifest.ApplicationLabel = buildVariant.AppName;
|
||||||
|
|
||||||
|
//Information($"AndroidManigest.xml VersionCode from {prevVersionCode} to {manifest.VersionCode}");
|
||||||
|
Information($"AndroidManigest.xml VersionName from {prevVersionName} to {manifest.VersionName}");
|
||||||
|
Information($"AndroidManigest.xml PackageName from {_androidPackageName} to {buildVariant.AndroidPackageName}");
|
||||||
|
Information($"AndroidManigest.xml ApplicationLabel to {buildVariant.AppName}");
|
||||||
|
|
||||||
|
SerializeAppManifest(manifestPath, manifest);
|
||||||
|
|
||||||
|
Information("AndroidManifest updated with success!");
|
||||||
|
});
|
||||||
|
|
||||||
|
void ReplaceInFile(string filePath, string oldtext, string newtext)
|
||||||
|
{
|
||||||
|
var fileText = FileReadText(filePath);
|
||||||
|
|
||||||
|
if(string.IsNullOrEmpty(fileText) || !fileText.Contains(oldtext))
|
||||||
|
{
|
||||||
|
throw new Exception($"Couldn't find {filePath} or it didn't contain: {oldtext}");
|
||||||
|
}
|
||||||
|
|
||||||
|
fileText = fileText.Replace(oldtext, newtext);
|
||||||
|
|
||||||
|
FileWriteText(filePath, fileText);
|
||||||
|
Information($"{filePath} modified successfully.");
|
||||||
|
}
|
||||||
|
|
||||||
|
Task("UpdateAndroidCodeFiles")
|
||||||
|
.IsDependentOn("UpdateAndroidManifest")
|
||||||
|
.Does(()=> {
|
||||||
|
var buildVariant = GetVariant();
|
||||||
|
|
||||||
|
//We're not using _androidPackageName here because the codefile is currently slightly different string than the one in AndroidManifest.xml
|
||||||
|
var keyName = "com.8bit.bitwarden";
|
||||||
|
var fixedPackageName = buildVariant.AndroidPackageName.Replace("x8bit", "8bit");
|
||||||
|
var filePath = Path.Combine(_slnPath, "src", "Android", "Services", "BiometricService.cs");
|
||||||
|
ReplaceInFile(filePath, keyName, fixedPackageName);
|
||||||
|
|
||||||
|
var packageFileList = new string[] {
|
||||||
|
Path.Combine(_slnPath, "src", "Android", "MainActivity.cs"),
|
||||||
|
Path.Combine(_slnPath, "src", "Android", "MainApplication.cs"),
|
||||||
|
Path.Combine(_slnPath, "src", "Android", "Constants.cs"),
|
||||||
|
Path.Combine(_slnPath, "src", "Android", "Accessibility", "AccessibilityService.cs"),
|
||||||
|
Path.Combine(_slnPath, "src", "Android", "Autofill", "AutofillHelpers.cs"),
|
||||||
|
Path.Combine(_slnPath, "src", "Android", "Autofill", "AutofillService.cs"),
|
||||||
|
Path.Combine(_slnPath, "src", "Android", "Receivers", "ClearClipboardAlarmReceiver.cs"),
|
||||||
|
Path.Combine(_slnPath, "src", "Android", "Receivers", "EventUploadReceiver.cs"),
|
||||||
|
Path.Combine(_slnPath, "src", "Android", "Receivers", "PackageReplacedReceiver.cs"),
|
||||||
|
Path.Combine(_slnPath, "src", "Android", "Receivers", "RestrictionsChangedReceiver.cs"),
|
||||||
|
Path.Combine(_slnPath, "src", "Android", "Services", "DeviceActionService.cs"),
|
||||||
|
Path.Combine(_slnPath, "src", "Android", "Tiles", "AutofillTileService.cs"),
|
||||||
|
Path.Combine(_slnPath, "src", "Android", "Tiles", "GeneratorTileService.cs"),
|
||||||
|
Path.Combine(_slnPath, "src", "Android", "Tiles", "MyVaultTileService.cs"),
|
||||||
|
Path.Combine(_slnPath, "src", "Android", "google-services.json"),
|
||||||
|
Path.Combine(_slnPath, "store", "google", "Publisher", "Program.cs"),
|
||||||
|
};
|
||||||
|
|
||||||
|
foreach(string path in packageFileList)
|
||||||
|
{
|
||||||
|
ReplaceInFile(path, "com.x8bit.bitwarden", buildVariant.AndroidPackageName);
|
||||||
|
}
|
||||||
|
|
||||||
|
var labelFileList = new string[] {
|
||||||
|
Path.Combine(_slnPath, "src", "Android", "Autofill", "AutofillService.cs"),
|
||||||
|
};
|
||||||
|
|
||||||
|
foreach(string path in labelFileList)
|
||||||
|
{
|
||||||
|
ReplaceInFile(path, "Bitwarden\"", $"{buildVariant.AppName}\"");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
#endregion Android
|
||||||
|
|
||||||
|
#region iOS
|
||||||
|
enum iOSProjectType
|
||||||
|
{
|
||||||
|
Null,
|
||||||
|
MainApp,
|
||||||
|
Autofill,
|
||||||
|
Extension,
|
||||||
|
ShareExtension
|
||||||
|
}
|
||||||
|
|
||||||
|
string GetiOSBundleId(VariantConfig buildVariant, iOSProjectType projectType) => projectType switch
|
||||||
|
{
|
||||||
|
iOSProjectType.Autofill => $"{buildVariant.iOSBundleId}.autofill",
|
||||||
|
iOSProjectType.Extension => $"{buildVariant.iOSBundleId}.find-login-action-extension",
|
||||||
|
iOSProjectType.ShareExtension => $"{buildVariant.iOSBundleId}.share-extension",
|
||||||
|
_ => buildVariant.iOSBundleId
|
||||||
|
};
|
||||||
|
|
||||||
|
string GetiOSBundleName(VariantConfig buildVariant, iOSProjectType projectType) => projectType switch
|
||||||
|
{
|
||||||
|
iOSProjectType.Autofill => $"{buildVariant.AppName} Autofill",
|
||||||
|
iOSProjectType.Extension => $"{buildVariant.AppName} Extension",
|
||||||
|
iOSProjectType.ShareExtension => $"{buildVariant.AppName} Share Extension",
|
||||||
|
_ => buildVariant.AppName
|
||||||
|
};
|
||||||
|
|
||||||
|
private void UpdateiOSInfoPlist(string plistPath, VariantConfig buildVariant, GitVersion git, iOSProjectType projectType = iOSProjectType.MainApp)
|
||||||
|
{
|
||||||
|
var plistFile = File(plistPath);
|
||||||
|
dynamic plist = DeserializePlist(plistFile);
|
||||||
|
|
||||||
|
var prevVersionName = plist["CFBundleShortVersionString"];
|
||||||
|
var prevVersionString = plist["CFBundleVersion"];
|
||||||
|
var prevVersion = int.Parse(plist["CFBundleVersion"]);
|
||||||
|
var prevBundleId = plist["CFBundleIdentifier"];
|
||||||
|
var prevBundleName = plist["CFBundleName"];
|
||||||
|
//var newVersion = CreateBuildNumber(prevVersion).ToString();
|
||||||
|
var newVersionName = GetVersionName(prevVersionName, buildVariant, git);
|
||||||
|
var newBundleId = GetiOSBundleId(buildVariant, projectType);
|
||||||
|
var newBundleName = GetiOSBundleName(buildVariant, projectType);
|
||||||
|
|
||||||
|
plist["CFBundleName"] = newBundleName;
|
||||||
|
plist["CFBundleDisplayName"] = newBundleName;
|
||||||
|
//plist["CFBundleVersion"] = newVersion;
|
||||||
|
plist["CFBundleShortVersionString"] = newVersionName;
|
||||||
|
plist["CFBundleIdentifier"] = newBundleId;
|
||||||
|
|
||||||
|
if(projectType == iOSProjectType.MainApp)
|
||||||
|
{
|
||||||
|
plist["CFBundleURLTypes"][0]["CFBundleURLName"] = $"{buildVariant.iOSBundleId}.url";
|
||||||
|
}
|
||||||
|
|
||||||
|
if(projectType == iOSProjectType.Extension)
|
||||||
|
{
|
||||||
|
var keyText = plist["NSExtension"]["NSExtensionAttributes"]["NSExtensionActivationRule"];
|
||||||
|
plist["NSExtension"]["NSExtensionAttributes"]["NSExtensionActivationRule"] = keyText.Replace("com.8bit.bitwarden", buildVariant.iOSBundleId);
|
||||||
|
}
|
||||||
|
|
||||||
|
SerializePlist(plistFile, plist);
|
||||||
|
|
||||||
|
Information($"Changed app name from {prevBundleName} to {newBundleName}");
|
||||||
|
//Information($"Changed Bundle Version from {prevVersion} to {newVersion}");
|
||||||
|
Information($"Changed Bundle Short Version name from {prevVersionName} to {newVersionName}");
|
||||||
|
Information($"Changed Bundle Identifier from {prevBundleId} to {newBundleId}");
|
||||||
|
Information($"{plistPath} updated with success!");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateiOSEntitlementsPlist(string entitlementsPath, VariantConfig buildVariant)
|
||||||
|
{
|
||||||
|
var EntitlementlistFile = File(entitlementsPath);
|
||||||
|
dynamic Entitlements = DeserializePlist(EntitlementlistFile);
|
||||||
|
|
||||||
|
Entitlements["aps-environment"] = buildVariant.ApsEnvironment;
|
||||||
|
Entitlements["keychain-access-groups"] = new List<string>() { "$(AppIdentifierPrefix)" + buildVariant.iOSBundleId };
|
||||||
|
Entitlements["com.apple.security.application-groups"] = new List<string>() { $"group.{buildVariant.iOSBundleId}" };;
|
||||||
|
|
||||||
|
Information($"Changed ApsEnvironment name to {buildVariant.ApsEnvironment}");
|
||||||
|
Information($"Changed keychain-access-groups bundleID to {buildVariant.iOSBundleId}");
|
||||||
|
|
||||||
|
SerializePlist(EntitlementlistFile, Entitlements);
|
||||||
|
|
||||||
|
Information($"{entitlementsPath} updated with success!");
|
||||||
|
}
|
||||||
|
|
||||||
|
Task("UpdateiOSIcon")
|
||||||
|
.Does(()=>{
|
||||||
|
//TODO we'll implement variant icons later
|
||||||
|
Information($"Updating IOS App Icon");
|
||||||
|
});
|
||||||
|
|
||||||
|
Task("UpdateiOSPlist")
|
||||||
|
.IsDependentOn("GetGitInfo")
|
||||||
|
.Does(()=> {
|
||||||
|
var buildVariant = GetVariant();
|
||||||
|
var infoPath = Path.Combine(_slnPath, "src", "iOS", "Info.plist");
|
||||||
|
var entitlementsPath = Path.Combine(_slnPath, "src", "iOS", "Entitlements.plist");
|
||||||
|
UpdateiOSInfoPlist(infoPath, buildVariant, _gitVersion, iOSProjectType.MainApp);
|
||||||
|
UpdateiOSEntitlementsPlist(entitlementsPath, buildVariant);
|
||||||
|
});
|
||||||
|
|
||||||
|
Task("UpdateiOSAutofillPlist")
|
||||||
|
.IsDependentOn("GetGitInfo")
|
||||||
|
.IsDependentOn("UpdateiOSPlist")
|
||||||
|
.Does(()=> {
|
||||||
|
var buildVariant = GetVariant();
|
||||||
|
var infoPath = Path.Combine(_slnPath, "src", "iOS.Autofill", "Info.plist");
|
||||||
|
var entitlementsPath = Path.Combine(_slnPath, "src", "iOS.Autofill", "Entitlements.plist");
|
||||||
|
UpdateiOSInfoPlist(infoPath, buildVariant, _gitVersion, iOSProjectType.Autofill);
|
||||||
|
UpdateiOSEntitlementsPlist(entitlementsPath, buildVariant);
|
||||||
|
});
|
||||||
|
|
||||||
|
Task("UpdateiOSExtensionPlist")
|
||||||
|
.IsDependentOn("GetGitInfo")
|
||||||
|
.IsDependentOn("UpdateiOSPlist")
|
||||||
|
.Does(()=> {
|
||||||
|
var buildVariant = GetVariant();
|
||||||
|
var infoPath = Path.Combine(_slnPath, "src", "iOS.Extension", "Info.plist");
|
||||||
|
var entitlementsPath = Path.Combine(_slnPath, "src", "iOS.Extension", "Entitlements.plist");
|
||||||
|
UpdateiOSInfoPlist(infoPath, buildVariant, _gitVersion, iOSProjectType.Extension);
|
||||||
|
UpdateiOSEntitlementsPlist(entitlementsPath, buildVariant);
|
||||||
|
});
|
||||||
|
|
||||||
|
Task("UpdateiOSShareExtensionPlist")
|
||||||
|
.IsDependentOn("GetGitInfo")
|
||||||
|
.IsDependentOn("UpdateiOSPlist")
|
||||||
|
.Does(()=> {
|
||||||
|
var buildVariant = GetVariant();
|
||||||
|
var infoPath = Path.Combine(_slnPath, "src", "iOS.ShareExtension", "Info.plist");
|
||||||
|
var entitlementsPath = Path.Combine(_slnPath, "src", "iOS.ShareExtension", "Entitlements.plist");
|
||||||
|
UpdateiOSInfoPlist(infoPath, buildVariant, _gitVersion, iOSProjectType.ShareExtension);
|
||||||
|
UpdateiOSEntitlementsPlist(entitlementsPath, buildVariant);
|
||||||
|
});
|
||||||
|
|
||||||
|
Task("UpdateiOSCodeFiles")
|
||||||
|
.IsDependentOn("UpdateiOSPlist")
|
||||||
|
.Does(()=> {
|
||||||
|
var buildVariant = GetVariant();
|
||||||
|
var fileList = new string[] {
|
||||||
|
Path.Combine(_slnPath, "src", "iOS.Core", "Utilities", "iOSCoreHelpers.cs"),
|
||||||
|
Path.Combine(_slnPath, "src", "iOS.Core", "Constants.cs"),
|
||||||
|
Path.Combine(".github", "resources", "export-options-ad-hoc.plist"),
|
||||||
|
Path.Combine(".github", "resources", "export-options-app-store.plist"),
|
||||||
|
};
|
||||||
|
|
||||||
|
foreach(string path in fileList)
|
||||||
|
{
|
||||||
|
ReplaceInFile(path, "com.8bit.bitwarden", buildVariant.iOSBundleId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
#endregion iOS
|
||||||
|
|
||||||
|
#region Main Tasks
|
||||||
|
Task("Android")
|
||||||
|
//.IsDependentOn("UpdateAndroidAppIcon")
|
||||||
|
.IsDependentOn("UpdateAndroidManifest")
|
||||||
|
.IsDependentOn("UpdateAndroidCodeFiles")
|
||||||
|
.Does(()=>
|
||||||
|
{
|
||||||
|
Information("Android app updated");
|
||||||
|
});
|
||||||
|
|
||||||
|
Task("iOS")
|
||||||
|
//.IsDependentOn("UpdateiOSIcon")
|
||||||
|
.IsDependentOn("UpdateiOSPlist")
|
||||||
|
.IsDependentOn("UpdateiOSAutofillPlist")
|
||||||
|
.IsDependentOn("UpdateiOSExtensionPlist")
|
||||||
|
.IsDependentOn("UpdateiOSShareExtensionPlist")
|
||||||
|
.IsDependentOn("UpdateiOSCodeFiles")
|
||||||
|
.Does(()=>
|
||||||
|
{
|
||||||
|
Information("iOS app updated");
|
||||||
|
});
|
||||||
|
|
||||||
|
Task("Default")
|
||||||
|
.Does(() => {
|
||||||
|
var usage = @"Missing target.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
dotnet cake build.cake --target (Android | iOS) --variant (dev | qa | beta | prod)
|
||||||
|
|
||||||
|
Options:
|
||||||
|
--debugScript=<bool> Script debug mode.
|
||||||
|
";
|
||||||
|
Information(usage);
|
||||||
|
});
|
||||||
|
#endregion Main Tasks
|
||||||
|
|
||||||
|
RunTarget(target);
|
Loading…
Reference in New Issue
Block a user