Bumped version to 2024.10.111 (#3417) #275
This file contains 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 | |
on: | |
push: | |
branches-ignore: | |
- "l10n_master" | |
- "gh-pages" | |
paths-ignore: | |
- ".github/workflows/**" | |
workflow_dispatch: | |
env: | |
main_app_folder_path: src/App | |
main_app_project_path: src/App/App.csproj | |
target-net-version: net8.0 | |
dotnet-version: '8.0.402' | |
maui-workload-version: '8.0.402' | |
jobs: | |
cloc: | |
name: CLOC | |
runs-on: ubuntu-22.04 | |
steps: | |
- name: Checkout repo | |
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 | |
- name: Set up CLOC | |
run: | | |
sudo apt-get update | |
sudo apt-get -y install cloc | |
- name: Print lines of code | |
run: cloc --vcs git --exclude-dir Resources,store,test,Properties --include-lang C#,XAML | |
setup: | |
name: Setup | |
runs-on: ubuntu-22.04 | |
outputs: | |
rc_branch_exists: ${{ steps.branch-check.outputs.rc_branch_exists }} | |
hotfix_branch_exists: ${{ steps.branch-check.outputs.hotfix_branch_exists }} | |
steps: | |
- name: Checkout repo | |
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 | |
with: | |
submodules: 'true' | |
- name: Check if special branches exist | |
id: branch-check | |
run: | | |
if [[ $(git ls-remote --heads origin rc) ]]; then | |
echo "rc_branch_exists=1" >> $GITHUB_OUTPUT | |
else | |
echo "rc_branch_exists=0" >> $GITHUB_OUTPUT | |
fi | |
if [[ $(git ls-remote --heads origin hotfix-rc) ]]; then | |
echo "hotfix_branch_exists=1" >> $GITHUB_OUTPUT | |
else | |
echo "hotfix_branch_exists=0" >> $GITHUB_OUTPUT | |
fi | |
android: | |
name: Android | |
runs-on: windows-2022 | |
needs: setup | |
if: false | |
strategy: | |
fail-fast: false | |
matrix: | |
variant: ["prod", "qa"] | |
env: | |
android_folder_path: src\App\Platforms\Android | |
android_folder_path_bash: src/App/Platforms/Android | |
steps: | |
- name: Checkout repo | |
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 | |
with: | |
fetch-depth: 0 | |
- name: Setup NuGet | |
uses: nuget/setup-nuget@a21f25cd3998bf370fde17e3f1b4c12c175172f9 # v2.0.0 | |
with: | |
nuget-version: 6.4.0 | |
- name: Set up .NET | |
uses: actions/setup-dotnet@6bd8b7f7774af54e05809fcc5431931b3eb1ddee # v4.0.1 | |
with: | |
dotnet-version: ${{ env.dotnet-version }} | |
- name: Install MAUI Workload | |
run: | | |
dotnet workload install maui --version ${{ env.maui-workload-version }} | |
- name: Set up MSBuild | |
uses: microsoft/setup-msbuild@6fb02220983dee41ce7ae257b6f4d8f9bf5ed4ce # v2.0.0 | |
- name: Setup Windows builder | |
run: choco install checksum --no-progress | |
- name: Install Microsoft OpenJDK 11 | |
run: | | |
choco install microsoft-openjdk11 --no-progress | |
Write-Output "JAVA_HOME=$(Get-ChildItem -Path 'C:\Program Files\Microsoft\jdk*' | ` | |
Select -First 1 -ExpandProperty FullName)" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append | |
Write-Output "Java Home: $env:JAVA_HOME" | |
- name: Print environment | |
run: | | |
nuget help | grep Version | |
msbuild -version | |
dotnet --info | |
echo "GitHub ref: $GITHUB_REF" | |
echo "GitHub event: $GITHUB_EVENT" | |
- name: Login to Azure - CI Subscription | |
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 | |
with: | |
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} | |
- name: Download secrets | |
env: | |
ACCOUNT_NAME: bitwardenci | |
CONTAINER_NAME: mobile | |
run: | | |
mkdir -p $HOME/secrets | |
az storage blob download --account-name $ACCOUNT_NAME --container-name $CONTAINER_NAME \ | |
--name app_play-keystore.jks --file ./${{ env.android_folder_path_bash }}/app_play-keystore.jks --output none | |
az storage blob download --account-name $ACCOUNT_NAME --container-name $CONTAINER_NAME \ | |
--name app_upload-keystore.jks --file ./${{ env.android_folder_path_bash }}/app_upload-keystore.jks --output none | |
az storage blob download --account-name $ACCOUNT_NAME --container-name $CONTAINER_NAME \ | |
--name play_creds.json --file $HOME/secrets/play_creds.json --output none | |
shell: bash | |
- name: Download secrets - Google Services | |
if: ${{ matrix.variant == 'prod' }} | |
env: | |
ACCOUNT_NAME: bitwardenci | |
CONTAINER_NAME: mobile | |
run: | | |
az storage blob download --account-name $ACCOUNT_NAME --container-name $CONTAINER_NAME \ | |
--name google-services.json --file ./${{ env.android_folder_path_bash }}/google-services.json --output none | |
shell: bash | |
- name: Increment version | |
run: | | |
BUILD_NUMBER=$((11000 + $GITHUB_RUN_NUMBER)) | |
echo "##### Setting Android Version Code to $BUILD_NUMBER" | tee -a $GITHUB_STEP_SUMMARY | |
sed -i "s/android:versionCode=\"1\"/android:versionCode=\"$BUILD_NUMBER\"/" \ | |
./${{ env.android_folder_path_bash }}/AndroidManifest.xml | |
shell: bash | |
- name: Restore packages | |
run: nuget restore | |
- name: Restore tools | |
run: dotnet tool restore | |
# - name: Run Core tests | |
# run: | | |
# dotnet test test/Core.Test/Core.Test.csproj --logger "trx;LogFileName=test-results.trx" ` | |
# /p:CustomConstants=UT | |
# - name: Report test results | |
# uses: dorny/test-reporter@eaa763f6ffc21c7a37837f56cd5f9737f27fc6c8 # v1.8.0 | |
# if: always() | |
# with: | |
# name: Test Results | |
# path: "**/test-results.trx" | |
# reporter: dotnet-trx | |
# fail-on-error: true | |
- name: Build Play Store publisher | |
if: ${{ matrix.variant == 'prod' }} | |
run: dotnet build .\store\google\Publisher\Publisher.csproj /p:Configuration=Release | |
- name: Setup Android build (${{ matrix.variant }}) | |
run: dotnet cake build.cake --target Android --variant ${{ matrix.variant }} | |
- name: Build & Sign Android | |
env: | |
PLAY_KEYSTORE_PASSWORD: ${{ secrets.PLAY_KEYSTORE_PASSWORD }} | |
UPLOAD_KEYSTORE_PASSWORD: ${{ secrets.UPLOAD_KEYSTORE_PASSWORD }} | |
run: | | |
$projToBuild = "$($env:GITHUB_WORKSPACE)/${{ env.main_app_project_path }}"; | |
$packageName = "com.x8bit.bitwarden"; | |
if ("${{ matrix.variant }}" -ne "prod") | |
{ | |
$packageName = "com.x8bit.bitwarden.${{ matrix.variant }}"; | |
} | |
Write-Output "##### Sign Google Play Bundle Release Configuration" | |
$signingUploadKeyStore = "$($env:GITHUB_WORKSPACE)\${{ env.android_folder_path }}\app_upload-keystore.jks" | |
dotnet publish $projToBuild -c Release -f ${{ env.target-net-version }}-android ` | |
/p:AndroidPackageFormats=aab ` | |
/p:AndroidKeyStore=true ` | |
/p:AndroidSigningKeyStore=$signingUploadKeyStore ` | |
/p:AndroidSigningKeyAlias=upload ` | |
/p:AndroidSigningKeyPass="$($env:UPLOAD_KEYSTORE_PASSWORD)" ` | |
/p:AndroidSigningStorePass="$($env:UPLOAD_KEYSTORE_PASSWORD)" --no-restore | |
Write-Output "##### Copy Google Play Bundle to project root" | |
$signedAabPath = "$($env:GITHUB_WORKSPACE)\${{ env.main_app_folder_path }}\bin\Release\${{ env.target-net-version }}-android\publish\$($packageName)-Signed.aab"; | |
$signedAabDestPath = "$($env:GITHUB_WORKSPACE)\$($packageName).aab"; | |
Copy-Item $signedAabPath $signedAabDestPath | |
Write-Output "##### Sign APK Release Configuration" | |
$signingPlayKeyStore = "$($env:GITHUB_WORKSPACE)\${{ env.android_folder_path }}\app_play-keystore.jks" | |
dotnet publish $projToBuild -c Release -f ${{ env.target-net-version }}-android ` | |
/p:AndroidKeyStore=true ` | |
/p:AndroidSigningKeyStore=$signingPlayKeyStore ` | |
/p:AndroidSigningKeyAlias=bitwarden ` | |
/p:AndroidSigningKeyPass="$($env:PLAY_KEYSTORE_PASSWORD)" ` | |
/p:AndroidSigningStorePass="$($env:PLAY_KEYSTORE_PASSWORD)" --no-restore | |
Write-Output "##### Copy Release APK to project root" | |
$signedApkPath = "$($env:GITHUB_WORKSPACE)\${{ env.main_app_folder_path }}\bin\Release\${{ env.target-net-version }}-android\publish\$($packageName)-Signed.apk"; | |
$signedApkDestPath = "$($env:GITHUB_WORKSPACE)\$($packageName).apk"; | |
Copy-Item $signedApkPath $signedApkDestPath | |
- name: Upload Prod .aab artifact | |
if: ${{ matrix.variant == 'prod' }} | |
uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4 | |
with: | |
name: com.x8bit.bitwarden.aab | |
path: ./com.x8bit.bitwarden.aab | |
if-no-files-found: error | |
- name: Upload Prod .apk artifact | |
if: ${{ matrix.variant == 'prod' }} | |
uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4 | |
with: | |
name: com.x8bit.bitwarden.apk | |
path: ./com.x8bit.bitwarden.apk | |
if-no-files-found: error | |
- name: Upload Other .apk artifact | |
if: ${{ matrix.variant != 'prod' }} | |
uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4 | |
with: | |
name: com.x8bit.bitwarden.${{ matrix.variant }}.apk | |
path: ./com.x8bit.bitwarden.${{ matrix.variant }}.apk | |
if-no-files-found: error | |
- name: Create checksum for Prod .apk artifact | |
if: ${{ matrix.variant == 'prod' }} | |
run: | | |
checksum -f="./com.x8bit.bitwarden.apk" ` | |
-t sha256 | Out-File -Encoding ASCII ./bw-android-apk-sha256.txt | |
- name: Create checksum for Other .apk artifact | |
if: ${{ matrix.variant != 'prod' }} | |
run: | | |
checksum -f="./com.x8bit.bitwarden.${{ matrix.variant }}.apk" ` | |
-t sha256 | Out-File -Encoding ASCII ./bw-android-${{ matrix.variant }}-apk-sha256.txt | |
- name: Upload .apk sha file for prod | |
if: ${{ matrix.variant == 'prod' }} | |
uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4 | |
with: | |
name: bw-android-apk-sha256.txt | |
path: ./bw-android-apk-sha256.txt | |
if-no-files-found: error | |
- name: Upload .apk sha file for other | |
if: ${{ matrix.variant != 'prod' }} | |
uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4 | |
with: | |
name: bw-android-${{ matrix.variant }}-apk-sha256.txt | |
path: ./bw-android-${{ matrix.variant }}-apk-sha256.txt | |
if-no-files-found: error | |
- name: Deploy to Play Store | |
if: ${{ matrix.variant == 'prod' && (( github.ref == 'refs/heads/main' | |
&& needs.setup.outputs.rc_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/hotfix-rc' ) }} | |
run: | | |
$publisherPath = "$($env:GITHUB_WORKSPACE)\store\google\Publisher\bin\Release\net8.0\Publisher.dll" | |
$credsPath = "$($HOME)\secrets\play_creds.json" | |
$aabPath = "$($env:GITHUB_WORKSPACE)\com.x8bit.bitwarden.aab" | |
$track = "internal" | |
dotnet $publisherPath $credsPath $aabPath $track | |
f-droid: | |
name: F-Droid Build | |
runs-on: windows-2022 | |
if: false | |
env: | |
android_folder_path: src\App\Platforms\Android | |
android_folder_path_bash: src/App/Platforms/Android | |
android_manifest_path: src/App/Platforms/Android/AndroidManifest.xml | |
steps: | |
- name: Checkout repo | |
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 | |
with: | |
fetch-depth: 0 | |
- name: Setup NuGet | |
uses: nuget/setup-nuget@a21f25cd3998bf370fde17e3f1b4c12c175172f9 # v2.0.0 | |
with: | |
nuget-version: 6.4.0 | |
- name: Set up .NET | |
uses: actions/setup-dotnet@6bd8b7f7774af54e05809fcc5431931b3eb1ddee # v4.0.1 | |
with: | |
dotnet-version: ${{ env.dotnet-version }} | |
- name: Install MAUI Workload | |
run: | | |
dotnet workload install maui --version ${{ env.maui-workload-version }} | |
- name: Set up MSBuild | |
uses: microsoft/setup-msbuild@6fb02220983dee41ce7ae257b6f4d8f9bf5ed4ce # v2.0.0 | |
- name: Setup Windows builder | |
run: choco install checksum --no-progress | |
- name: Install Microsoft OpenJDK 11 | |
run: | | |
choco install microsoft-openjdk11 --no-progress | |
Write-Output "JAVA_HOME=$(Get-ChildItem -Path 'C:\Program Files\Microsoft\jdk*' | Select -First 1 -ExpandProperty FullName)" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append | |
Write-Output "Java Home: $env:JAVA_HOME" | |
- name: Print environment | |
run: | | |
nuget help | grep Version | |
msbuild -version | |
dotnet --info | |
echo "GitHub ref: $GITHUB_REF" | |
echo "GitHub event: $GITHUB_EVENT" | |
- name: Login to Azure - CI Subscription | |
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 | |
with: | |
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} | |
- name: Download secrets | |
env: | |
ACCOUNT_NAME: bitwardenci | |
CONTAINER_NAME: mobile | |
FILE: app_fdroid-keystore.jks | |
run: | | |
az storage blob download --account-name $ACCOUNT_NAME --container-name $CONTAINER_NAME --name $FILE \ | |
--file ${{ env.android_folder_path_bash }}/$FILE --output none | |
shell: bash | |
- name: Increment version | |
run: | | |
BUILD_NUMBER=$((11000 + $GITHUB_RUN_NUMBER)) | |
echo "##### Setting F-Droid Version Code to $BUILD_NUMBER" | tee -a $GITHUB_STEP_SUMMARY | |
sed -i "s/android:versionCode=\"1\"/android:versionCode=\"$BUILD_NUMBER\"/" \ | |
./${{ env.android_manifest_path }} | |
shell: bash | |
- name: Clean for F-Droid | |
run: | | |
$directoryBuildProps = $($env:GITHUB_WORKSPACE + "/Directory.Build.props"); | |
$androidManifest = $($env:GITHUB_WORKSPACE + "/${{ env.android_manifest_path }}"); | |
Write-Output "##### Back up project files" | |
Copy-Item $androidManifest $($androidManifest + ".original"); | |
Copy-Item $directoryBuildProps $($directoryBuildProps + ".original"); | |
Write-Output "##### Cleanup Android Manifest" | |
$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"); | |
$xml.Save($androidManifest); | |
Write-Output "##### Enabling FDROID constant" | |
(Get-Content $directoryBuildProps).Replace('<!-- <CustomConstants>FDROID</CustomConstants> -->', '<CustomConstants>FDROID</CustomConstants>') | Set-Content $directoryBuildProps | |
- name: Restore packages | |
run: dotnet restore | |
- name: Build & Sign F-Droid | |
env: | |
FDROID_KEYSTORE_PASSWORD: ${{ secrets.FDROID_KEYSTORE_PASSWORD }} | |
run: | | |
$projToBuild = "$($env:GITHUB_WORKSPACE)\${{ env.main_app_project_path }}"; | |
$packageName = "com.x8bit.bitwarden"; | |
Write-Output "##### Sign FDroid" | |
$signingFdroidKeyStore = "$($env:GITHUB_WORKSPACE)\${{ env.android_folder_path }}\app_fdroid-keystore.jks" | |
dotnet build $projToBuild -c Release -f ${{ env.target-net-version }}-android ` | |
/p:AndroidKeyStore=true ` | |
/p:AndroidSigningKeyStore=$signingFdroidKeyStore ` | |
/p:AndroidSigningKeyAlias=bitwarden ` | |
/p:AndroidSigningKeyPass="$($env:FDROID_KEYSTORE_PASSWORD)" ` | |
/p:AndroidSigningStorePass="$($env:FDROID_KEYSTORE_PASSWORD)" ` --no-restore | |
Write-Output "##### Copy FDroid apk to project root" | |
$signedApkPath = "$($env:GITHUB_WORKSPACE)\${{ env.main_app_folder_path }}\bin\Release\${{ env.target-net-version }}-android\$($packageName)-Signed.apk"; | |
$signedApkDestPath = "$($env:GITHUB_WORKSPACE)\com.x8bit.bitwarden-fdroid.apk"; | |
Copy-Item $signedApkPath $signedApkDestPath | |
- name: Upload F-Droid .apk artifact | |
uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4 | |
with: | |
name: com.x8bit.bitwarden-fdroid.apk | |
path: ./com.x8bit.bitwarden-fdroid.apk | |
if-no-files-found: error | |
- name: Create checksum for F-Droid artifact | |
run: | | |
checksum -f="./com.x8bit.bitwarden-fdroid.apk" ` | |
-t sha256 | Out-File -Encoding ASCII ./bw-fdroid-apk-sha256.txt | |
- name: Upload F-Droid sha file | |
uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4 | |
with: | |
name: bw-fdroid-apk-sha256.txt | |
path: ./bw-fdroid-apk-sha256.txt | |
if-no-files-found: error | |
ios: | |
name: Apple iOS | |
runs-on: macos-14 | |
needs: setup | |
env: | |
ios_folder_path: src/App/Platforms/iOS | |
app_output_name: App | |
app_ci_output_filename: App_x64_Debug | |
steps: | |
- name: Checkout repo | |
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 | |
with: | |
submodules: 'true' | |
- name: Set XCode version | |
uses: maxim-lobanov/setup-xcode@60606e260d2fc5762a71e64e74b2174e8ea3c8bd # v1.6.0 | |
with: | |
xcode-version: 15.4 | |
- name: Setup NuGet | |
uses: nuget/setup-nuget@a21f25cd3998bf370fde17e3f1b4c12c175172f9 # v2.0.0 | |
with: | |
nuget-version: 6.4.0 | |
- name: Set up .NET | |
uses: actions/setup-dotnet@6bd8b7f7774af54e05809fcc5431931b3eb1ddee # v4.0.1 | |
with: | |
dotnet-version: ${{ env.dotnet-version }} | |
- name: Install MAUI Workload | |
run: dotnet workload install maui --version ${{ env.maui-workload-version }} | |
- name: Print environment | |
run: | | |
nuget help | grep Version | |
dotnet --info | |
echo "GitHub ref: $GITHUB_REF" | |
echo "GitHub event: $GITHUB_EVENT" | |
- name: Login to Azure - CI Subscription | |
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 | |
with: | |
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} | |
- name: Retrieve secrets | |
id: retrieve-secrets | |
uses: bitwarden/gh-actions/get-keyvault-secrets@main | |
with: | |
keyvault: "bitwarden-ci" | |
secrets: "appcenter-ios-token" | |
- name: Download Provisioning Profiles secrets | |
env: | |
ACCOUNT_NAME: bitwardenci | |
CONTAINER_NAME: profiles | |
run: | | |
mkdir -p $HOME/secrets | |
profiles=( | |
"dist_autofill.mobileprovision" | |
"dist_bitwarden.mobileprovision" | |
"dist_extension.mobileprovision" | |
"dist_share_extension.mobileprovision" | |
"dist_bitwarden_watch_app.mobileprovision" | |
"dist_bitwarden_watch_app_extension.mobileprovision" | |
) | |
for FILE in "${profiles[@]}" | |
do | |
az storage blob download --account-name $ACCOUNT_NAME --container-name $CONTAINER_NAME --name $FILE \ | |
--file $HOME/secrets/$FILE --output none | |
done | |
- name: Download Google Services secret | |
env: | |
ACCOUNT_NAME: bitwardenci | |
CONTAINER_NAME: mobile | |
FILE: GoogleService-Info.plist | |
run: | | |
mkdir -p $HOME/secrets | |
az storage blob download --account-name $ACCOUNT_NAME --container-name $CONTAINER_NAME --name $FILE \ | |
--file src/watchOS/bitwarden/$FILE --output none | |
- name: Increment version | |
run: | | |
BUILD_NUMBER=$((8000 + $GITHUB_RUN_NUMBER)) | |
echo "##### Setting iOS CFBundleVersion to $BUILD_NUMBER" | tee -a $GITHUB_STEP_SUMMARY | |
perl -0777 -pi.bak -e 's/<key>CFBundleVersion<\/key>\s*<string>1<\/string>/<key>CFBundleVersion<\/key>\n\t<string>'"$BUILD_NUMBER"'<\/string>/' ./${{ env.ios_folder_path }}/Info.plist | |
perl -0777 -pi.bak -e 's/<key>CFBundleVersion<\/key>\s*<string>1<\/string>/<key>CFBundleVersion<\/key>\n\t<string>'"$BUILD_NUMBER"'<\/string>/' ./src/iOS.Extension/Info.plist | |
perl -0777 -pi.bak -e 's/<key>CFBundleVersion<\/key>\s*<string>1<\/string>/<key>CFBundleVersion<\/key>\n\t<string>'"$BUILD_NUMBER"'<\/string>/' ./src/iOS.Autofill/Info.plist | |
perl -0777 -pi.bak -e 's/<key>CFBundleVersion<\/key>\s*<string>1<\/string>/<key>CFBundleVersion<\/key>\n\t<string>'"$BUILD_NUMBER"'<\/string>/' ./src/iOS.ShareExtension/Info.plist | |
cd src/watchOS/bitwarden | |
agvtool new-version -all $BUILD_NUMBER | |
- name: Update Entitlements | |
run: | | |
echo "##### Updating Entitlements" | |
perl -0777 -pi.bak -e 's/<key>aps-environment<\/key>\s*<string>development<\/string>/<key>aps-environment<\/key>\n\t<string>production<\/string>/' ./${{ env.ios_folder_path }}/Entitlements.plist | |
- name: Get certificates | |
run: | | |
mkdir -p $HOME/certificates | |
az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/ios-distribution | | |
jq -r .value | base64 -d > $HOME/certificates/ios-distribution.p12 | |
- name: Set up Keychain | |
env: | |
KEYCHAIN_PASSWORD: ${{ secrets.IOS_KEYCHAIN_PASSWORD }} | |
run: | | |
security create-keychain -p $KEYCHAIN_PASSWORD build.keychain | |
security default-keychain -s build.keychain | |
security unlock-keychain -p $KEYCHAIN_PASSWORD build.keychain | |
security set-keychain-settings -lut 1200 build.keychain | |
security import $HOME/certificates/ios-distribution.p12 -k build.keychain -P "" -T /usr/bin/codesign \ | |
-T /usr/bin/security | |
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k $KEYCHAIN_PASSWORD build.keychain | |
- name: Set up provisioning profiles | |
run: | | |
AUTOFILL_PROFILE_PATH=$HOME/secrets/dist_autofill.mobileprovision | |
BITWARDEN_PROFILE_PATH=$HOME/secrets/dist_bitwarden.mobileprovision | |
EXTENSION_PROFILE_PATH=$HOME/secrets/dist_extension.mobileprovision | |
SHARE_EXTENSION_PROFILE_PATH=$HOME/secrets/dist_share_extension.mobileprovision | |
WATCH_APP_PROFILE_PATH=$HOME/secrets/dist_bitwarden_watch_app.mobileprovision | |
WATCH_APP_EXTENSION_PROFILE_PATH=$HOME/secrets/dist_bitwarden_watch_app_extension.mobileprovision | |
PROFILES_DIR_PATH=$HOME/Library/MobileDevice/Provisioning\ Profiles | |
mkdir -p "$PROFILES_DIR_PATH" | |
AUTOFILL_UUID=$(grep UUID -A1 -a $AUTOFILL_PROFILE_PATH | grep -io "[-A-F0-9]\{36\}") | |
cp $AUTOFILL_PROFILE_PATH "$PROFILES_DIR_PATH/$AUTOFILL_UUID.mobileprovision" | |
BITWARDEN_UUID=$(grep UUID -A1 -a $BITWARDEN_PROFILE_PATH | grep -io "[-A-F0-9]\{36\}") | |
cp $BITWARDEN_PROFILE_PATH "$PROFILES_DIR_PATH/$BITWARDEN_UUID.mobileprovision" | |
EXTENSION_UUID=$(grep UUID -A1 -a $EXTENSION_PROFILE_PATH | grep -io "[-A-F0-9]\{36\}") | |
cp $EXTENSION_PROFILE_PATH "$PROFILES_DIR_PATH/$EXTENSION_UUID.mobileprovision" | |
SHARE_EXTENSION_UUID=$(grep UUID -A1 -a $SHARE_EXTENSION_PROFILE_PATH | grep -io "[-A-F0-9]\{36\}") | |
cp $SHARE_EXTENSION_PROFILE_PATH "$PROFILES_DIR_PATH/$SHARE_EXTENSION_UUID.mobileprovision" | |
WATCH_APP_UUID=$(grep UUID -A1 -a $WATCH_APP_PROFILE_PATH | grep -io "[-A-F0-9]\{36\}") | |
cp $WATCH_APP_PROFILE_PATH "$PROFILES_DIR_PATH/$WATCH_APP_UUID.mobileprovision" | |
WATCH_APP_EXTENSION_UUID=$(grep UUID -A1 -a $WATCH_APP_EXTENSION_PROFILE_PATH | grep -io "[-A-F0-9]\{36\}") | |
cp $WATCH_APP_EXTENSION_PROFILE_PATH "$PROFILES_DIR_PATH/$WATCH_APP_EXTENSION_UUID.mobileprovision" | |
- name: Restore packages | |
run: dotnet restore | |
- name: Bulid WatchApp | |
run: | | |
echo "##### Build WatchApp with Release Configuration" | |
xcodebuild archive -workspace ./src/watchOS/bitwarden/bitwarden.xcodeproj/project.xcworkspace -configuration Release -scheme bitwarden\ WatchKit\ App -archivePath ./src/watchOS/bitwarden | |
- name: Archive Build for App Store | |
run: | | |
echo "##### Archive for Release ios-arm64" | |
dotnet publish ${{ env.main_app_project_path }} -c Release -f ${{ env.target-net-version }}-ios /p:RuntimeIdentifier=ios-arm64 /p:ArchiveOnBuild=true /p:MtouchUseLlvm=false | |
- name: Archive Build for Mobile Automation | |
run: | | |
echo "##### Archive Debug for iossimulator-x64" | |
dotnet build ${{ env.main_app_project_path }} -c Debug -f ${{ env.target-net-version }}-ios /p:RuntimeIdentifier=iossimulator-x64 /p:ArchiveOnBuild=true /p:MtouchUseLlvm=false | |
ls $HOME/Library/Developer/Xcode/Archives | |
- name: Export .ipa for App Store | |
env: | |
EXPORT_OPTIONS_PATH: ./.github/resources/export-options-app-store.plist | |
EXPORT_PATH: ./bitwarden-export | |
run: | | |
ARCHIVE_PATH="$HOME/Library/Developer/Xcode/Archives/*/*.xcarchive" | |
xcodebuild -exportArchive -archivePath $ARCHIVE_PATH -exportPath $EXPORT_PATH \ | |
-exportOptionsPlist $EXPORT_OPTIONS_PATH | |
- name: Export .app for Automation CI | |
env: | |
ARCHIVE_PATH: ./${{ env.main_app_folder_path }}/bin/Debug/${{ env.target-net-version }}-ios/iossimulator-x64 | |
EXPORT_PATH: ./bitwarden-export | |
run: | | |
zip -r -q ${{ env.app_ci_output_filename }}.app.zip $ARCHIVE_PATH | |
mv ${{ env.app_ci_output_filename }}.app.zip $EXPORT_PATH | |
- name: Copy all dSYMs files to upload | |
env: | |
EXPORT_PATH: ./bitwarden-export | |
WATCH_ARCHIVE_DSYMS_PATH: ./src/watchOS/bitwarden.xcarchive/dSYMs/ | |
WATCH_DSYMS_EXPORT_PATH: ./bitwarden-export/Watch_dSYMs | |
run: | | |
ARCHIVE_DSYMS_PATH="$HOME/Library/Developer/Xcode/Archives/*/*.xcarchive/dSYMs" | |
cp -r -v $ARCHIVE_DSYMS_PATH $EXPORT_PATH | |
mkdir $WATCH_DSYMS_EXPORT_PATH | |
cp -r -v $WATCH_ARCHIVE_DSYMS_PATH $WATCH_DSYMS_EXPORT_PATH | |
- name: Upload App Store .ipa & dSYMs artifacts | |
uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4 | |
with: | |
name: Bitwarden iOS | |
path: | | |
./bitwarden-export/Bitwarden.ipa | |
./bitwarden-export/dSYMs/*.* | |
if-no-files-found: error | |
- name: Upload .app file for Automation CI | |
uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4 | |
with: | |
name: ${{ env.app_ci_output_filename }}.app.zip | |
path: ./bitwarden-export/${{ env.app_ci_output_filename }}.app.zip | |
if-no-files-found: error | |
- name: Install AppCenter CLI | |
if: | | |
(github.ref == 'refs/heads/main' | |
&& needs.setup.outputs.rc_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/hotfix-rc' | |
run: npm install -g appcenter-cli | |
- name: Upload dSYMs to App Center | |
if: | | |
(github.ref == 'refs/heads/main' | |
&& needs.setup.outputs.rc_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/hotfix-rc' | |
env: | |
APPCENTER_IOS_TOKEN: ${{ steps.retrieve-secrets.outputs.appcenter-ios-token }} | |
run: appcenter crashes upload-symbols -a bitwarden/bitwarden -s "./bitwarden-export/dSYMs" --token $APPCENTER_IOS_TOKEN | |
- name: Upload Watch dSYMs to Firebase Crashlytics | |
if: | | |
(github.ref == 'refs/heads/main' | |
&& needs.setup.outputs.rc_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/hotfix-rc' | |
run: | | |
echo "##### Uploading Watch dSYMs to Firebase" | |
find "$HOME/Library/Developer/XCode/DerivedData" -name "upload-symbols" -exec chmod +x {} \; -exec {} -gsp "./src/watchOS/bitwarden/GoogleService-Info.plist" -p ios "./bitwarden-export/Watch_dSYMs" \; | |
- name: Validate app in App Store | |
if: | | |
(github.ref == 'refs/heads/master' | |
&& needs.setup.outputs.rc_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/hotfix-rc' | |
env: | |
APPLE_ID_USERNAME: ${{ secrets.APPLE_ID_USERNAME }} | |
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }} | |
run: | | |
xcrun altool --validate-app --type ios --file "./bitwarden-export/Bitwarden.ipa" \ | |
--username "$APPLE_ID_USERNAME" --password "$APPLE_ID_PASSWORD" | |
- name: Deploy to App Store | |
if: | | |
(github.ref == 'refs/heads/main' | |
&& needs.setup.outputs.rc_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/hotfix-rc' | |
env: | |
APPLE_ID_USERNAME: ${{ secrets.APPLE_ID_USERNAME }} | |
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }} | |
run: | | |
xcrun altool --upload-app --type ios --file "./bitwarden-export/Bitwarden.ipa" \ | |
--username "$APPLE_ID_USERNAME" --password "$APPLE_ID_PASSWORD" | |
crowdin-push: | |
name: Crowdin Push | |
if: github.ref == 'refs/heads/main' | |
needs: | |
- android | |
- f-droid | |
- ios | |
runs-on: ubuntu-22.04 | |
env: | |
_CROWDIN_PROJECT_ID: "269690" | |
steps: | |
- name: Checkout repo | |
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 | |
- name: Login to Azure - CI Subscription | |
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 | |
with: | |
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} | |
- name: Retrieve secrets | |
id: retrieve-secrets | |
uses: bitwarden/gh-actions/get-keyvault-secrets@main | |
with: | |
keyvault: "bitwarden-ci" | |
secrets: "crowdin-api-token" | |
- name: Upload Sources | |
uses: crowdin/github-action@61ac8b980551f674046220c3e104bddae2916ac5 # v2.0.0 | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
CROWDIN_API_TOKEN: ${{ steps.retrieve-secrets.outputs.crowdin-api-token }} | |
with: | |
config: crowdin.yml | |
crowdin_branch_name: main | |
upload_sources: true | |
upload_translations: false | |
check-failures: | |
name: Check for failures | |
if: always() | |
runs-on: ubuntu-22.04 | |
needs: | |
- cloc | |
- android | |
- f-droid | |
- ios | |
- crowdin-push | |
steps: | |
- name: Check if any job failed | |
if: | | |
(github.ref == 'refs/heads/main' | |
|| github.ref == 'refs/heads/rc' | |
|| github.ref == 'refs/heads/hotfix-rc') | |
&& contains(needs.*.result, 'failure') | |
run: exit 1 | |
- name: Login to Azure - CI Subscription | |
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 | |
if: failure() | |
with: | |
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} | |
- name: Retrieve secrets | |
id: retrieve-secrets | |
uses: bitwarden/gh-actions/get-keyvault-secrets@main | |
if: failure() | |
with: | |
keyvault: "bitwarden-ci" | |
secrets: "devops-alerts-slack-webhook-url" | |
- name: Notify Slack on failure | |
uses: act10ns/slack@44541246747a30eb3102d87f7a4cc5471b0ffb7d # v2.1.0 | |
if: failure() | |
env: | |
SLACK_WEBHOOK_URL: ${{ steps.retrieve-secrets.outputs.devops-alerts-slack-webhook-url }} | |
with: | |
status: ${{ job.status }} |