Skip to content

[PM-18414] CI restructuring #6 - New build workflows, build-all, ci-bwpm and ci-bwa #1589

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weโ€™ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 57 commits into from
May 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
1c2c175
Drafting _build-any.yml
vvolkgang Mar 31, 2025
ddcc46d
Add yq and swift-protobuf to brew
vvolkgang Apr 8, 2025
64f6df0
Update .ruby-version
vvolkgang Apr 17, 2025
7476a98
Gemfile improvements - set ruby version from .ruby-version file; add โ€ฆ
vvolkgang Apr 17, 2025
a225072
.env refactor + add bwa_prod
vvolkgang Apr 17, 2025
5411c66
Update _version.yml to support workflow_call and provide outputs
vvolkgang Apr 17, 2025
8b9d970
Update Fastfile
vvolkgang Apr 17, 2025
704d81b
Cleanup _build-any.yml
vvolkgang Apr 17, 2025
d6f51a7
Add draft ci-bwpm.yml
vvolkgang Apr 17, 2025
875f69a
cleanup build_utils.rb
vvolkgang Apr 17, 2025
184f855
Setup Brewfile with version pinning
vvolkgang Apr 17, 2025
a865c07
fix ci-bwpm.yml
vvolkgang Apr 17, 2025
4e41733
Rename .env var
vvolkgang Apr 21, 2025
e618fe5
Load .env file vars to GitHub ENV
vvolkgang Apr 21, 2025
58c6b72
Workflow now downloads secrets with bash based on ENV vars instead ofโ€ฆ
vvolkgang Apr 22, 2025
5335d1d
downcase build mode for artifact name
vvolkgang Apr 23, 2025
4aab9c9
fastfile - only run update_plists for BWPM, BWA doesn't need it for now
vvolkgang Apr 23, 2025
4d0e9a7
Fastfile - Add support for BWA xcconfig files.
vvolkgang Apr 23, 2025
2e01e36
Fastfile - Support Local*.xcconfig per app
vvolkgang Apr 24, 2025
616200b
Updated build step ahead of the consolidation changes in #1526
vvolkgang Apr 24, 2025
164a003
Prefix env vars with underscore
vvolkgang Apr 24, 2025
65ab642
fastfile - move yaml file update to helper methods
vvolkgang Apr 24, 2025
5950490
Cleanup ci-bwpm
vvolkgang May 2, 2025
b613b34
ci-bwpm - set environment based on build-variant input
vvolkgang May 2, 2025
aea6f3d
Change branch for workflow testing
vvolkgang May 2, 2025
a9ceee7
ci-bwpm - Use outputs from _version
vvolkgang May 2, 2025
a0afa89
_build-any - Update workflow name
vvolkgang May 2, 2025
ed8414f
Debug _build-any
vvolkgang May 2, 2025
b01eeac
Rename _ENV to _BW_ENV
vvolkgang May 2, 2025
4e341cc
Fix az container bug
vvolkgang May 2, 2025
ba47805
Refactor
vvolkgang May 2, 2025
86e3d90
Logs refactor
vvolkgang May 2, 2025
2e7d508
Fix provisioning profiles install
vvolkgang May 2, 2025
781848c
Fix build warning: [MT] IDEDistribution: Command line name "app-storeโ€ฆ
vvolkgang May 2, 2025
8515843
Fix artifact copy
vvolkgang May 2, 2025
55145f3
ci-bwpm - restructure matrix based on include; add missing inputs
vvolkgang May 3, 2025
d6b21a7
Fix get artifact name
vvolkgang May 3, 2025
d39cc82
Fastfile - Fix updating ITSEncryptionExportComplianceCode
vvolkgang May 5, 2025
d2c3d1f
Fastfile - Restrict build_mode values
vvolkgang May 5, 2025
ed39290
ci-bwpm - Revert test code
vvolkgang May 5, 2025
5b69d40
Transition Patch Version to Boolean
vvolkgang May 5, 2025
1b0dc7d
Implement ci-bwa.yml
vvolkgang May 5, 2025
6576538
build-any.yml - Support different filenames in AppStoreConnect / Testโ€ฆ
vvolkgang May 6, 2025
a9d9e77
Test BWA CI
vvolkgang May 6, 2025
0ea1900
Move uploading dSYM files to build workflows; adds support for Authenโ€ฆ
vvolkgang May 7, 2025
b71bf08
Fix firebase upload path
vvolkgang May 7, 2025
e5733e4
Restrict dsym upload to BWPM, BWA will be added in a future PR
vvolkgang May 8, 2025
348d86b
Removed TODO - Created PM-21337 to followup
vvolkgang May 8, 2025
46382a1
Removed xcode-select TODO - Created PM-21338 to followup
vvolkgang May 8, 2025
0085fe7
Merge branch 'main' into monorepo/new-build
vvolkgang May 15, 2025
269aa43
Revert testing changes
vvolkgang May 15, 2025
84e15d4
Update workflow run names
vvolkgang May 15, 2025
5c21638
Merge branch 'main' into monorepo/new-build
vvolkgang May 19, 2025
bc3314e
Set workflow permissions
vvolkgang May 20, 2025
23d91f0
Merge branch 'main' into monorepo/new-build
vvolkgang May 21, 2025
06cf1d9
Merge branch 'main' into monorepo/new-build
vvolkgang May 22, 2025
7ea8f5f
Removed testing placeholders from ci-bwa.yml
vvolkgang May 27, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
262 changes: 257 additions & 5 deletions .github/workflows/_build-any.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,268 @@ name: Build App
on:
workflow_call:
inputs:
environment:
description: "Environment"
bw-env:
description: "BW Environment"
type: string
build-mode:
description: "Build Mode"
type: string
version-name:
description: "Version Name Override - e.g. '2024.8.1'"
type: string
version-number:
description: "Version Number Override - e.g. '1021'"
type: string
xcode-version:
description: "Xcode Version Override - e.g. '15.2'"
type: string
compiler-flags:
description: "Compiler Flags - e.g. 'DEBUG_MENU FEATURE2'"
type: string
distribute:
description: "Distribute to TestFlight"
type: boolean
env:
_BW_ENV: ${{ inputs.bw-env || 'bwpm-prod' }}
_BUILD_VARIANT: ${{ inputs.bw-env == 'bwpm-prod' && 'Production' || 'Beta' }}
_BUILD_MODE: ${{ inputs.build-mode || 'Device' }}
_XCODE_VERSION: ${{ inputs.xcode-version }}
_VERSION_NAME: ${{ inputs.version-name }}
_VERSION_NUMBER: ${{ inputs.version-number }}
_COMPILER_FLAGS: ${{ inputs.compiler-flags }}
_GITHUB_ACTION_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}/attempts/${{ github.run_attempt }}
_EXPORT_PATH: 'export'

jobs:
build:
name: Build ${{ inputs.environment }}
name: Build ${{ inputs.bw-env }}
runs-on: macos-15
permissions:
contents: read
env:
MINT_PATH: .mint/lib
MINT_LINK_PATH: .mint/bin
steps:
- name: Echo
- name: Log inputs to job summary
run: |
echo "<details><summary>Job Inputs</summary>" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo '```json' >> $GITHUB_STEP_SUMMARY
echo '${{ toJson(inputs) }}' >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
echo "</details>" >> $GITHUB_STEP_SUMMARY

- name: Check out repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2

- name: Read Xcode version from file if not provided
run: |
if [ -z "$_XCODE_VERSION" ]; then
echo "_XCODE_VERSION=$(cat .xcode-version | tr -d '\n')" >> "$GITHUB_ENV"
fi

- name: Set Xcode version
uses: maxim-lobanov/setup-xcode@60606e260d2fc5762a71e64e74b2174e8ea3c8bd # v1.6.0
with:
xcode-version: ${{ env._XCODE_VERSION }}

- name: Configure Ruby
uses: ruby/setup-ruby@354a1ad156761f5ee2b7b13fa8e09943a5e8d252 # v1.229.0
with:
bundler-cache: true

- name: Install Homebrew Dependencies and load environment variables
run: |
brew update
brew bundle
bundle exec fastlane load_dotenv_file --env $_BW_ENV

- name: Log in to Azure
if: env._BUILD_MODE == 'Device'
uses: Azure/login@cb79c773a3cfa27f31f25eb3f677781210c9ce3d # v1.6.1
with:
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}

- name: Setup secrets
if: env._BUILD_MODE == 'Device'
run: |
az_download() {
local container_name=$1
local az_filename=$2
local local_filename=$3

az storage blob download --account-name bitwardenci --container-name $container_name --name $az_filename --file $local_filename --output none --only-show-errors --no-progress
}

mkdir -p $HOME/secrets

profiles_dir_path="$HOME/Library/MobileDevice/Provisioning Profiles"
mkdir -p "$profiles_dir_path"

IFS=',' read -ra profiles <<< "$_PROVISIONING_PROFILES"
for FILE in "${profiles[@]}"
do
echo "โŒ›๏ธ Downloading provisioning profile $FILE..."
local_profile_path=$HOME/secrets/$FILE

az_download profiles $FILE $local_profile_path

profile_uuid=$(grep UUID -A1 -a $local_profile_path | grep -io "[-A-F0-9]\{36\}")
cp $local_profile_path "$profiles_dir_path/$profile_uuid.mobileprovision"
done

echo "โŒ›๏ธ Downloading Google-Services.plist..."
az_download mobile $_AZ_CRASHLYTICS_FILE_NAME $_CRASHLYTICS_PATH

if [[ "$_APP" == "password_manager" ]]; then
echo "โŒ›๏ธ Downloading Google-Services.plist for watchOS..."
az_download mobile $_AZ_CRASHLYTICS_FILE_NAME "BitwardenWatchApp/GoogleService-Info.plist"
plutil -replace BUNDLE_ID -string '$BUNDLE_ID.watchkitapp' BitwardenWatchApp/GoogleService-Info.plist
fi

echo "โŒ›๏ธ Downloading fastlane credentials..."
az_download mobile appstoreconnect-fastlane.json $HOME/secrets/appstoreconnect-fastlane.json

echo "โŒ›๏ธ Downloading distribution certificate..."
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

echo "โœ… All secrets downloaded!"

- name: Configure Keychain Access
if: env._BUILD_MODE == 'Device'
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: Setup code files
run: |
bundle exec fastlane setup_code_files \
--env $_BW_ENV \
build_mode:$_BUILD_MODE \
version_name:$_VERSION_NAME \
version_number:$_VERSION_NUMBER \

bundle exec fastlane update_ci_build_info \
--env $_BW_ENV \
repository:$GITHUB_REPOSITORY \
branch:$GITHUB_REF_NAME \
commit_hash:$GITHUB_SHA \
ci_run_number:$GITHUB_RUN_ID \
ci_run_attempt:$GITHUB_RUN_ATTEMPT \
compiler_flags:"$_COMPILER_FLAGS"

- name: Cache Mint packages
id: mint-cache
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with:
path: .mint
key: ${{ runner.os }}-mint-${{ hashFiles('**/Mintfile') }}
restore-keys: |
${{ runner.os }}-mint-

- name: Install Mint packages
if: steps.mint-cache.outputs.cache-hit != 'true'
run: |
mint bootstrap

- name: Build ${{ inputs.bw-env }}
run: |
./Scripts/build.sh $_BUILD_PROJECT_PATH $_BUILD_SCHEME $_BUILD_MODE

- name: Prepare artifacts for upload to GitHub
run: |
mkdir -p $_EXPORT_PATH
mkdir -p $_EXPORT_PATH/dSYMs

bundle exec fastlane post_build \
--env $_BW_ENV \
build_mode:$_BUILD_MODE \
export_path:$_EXPORT_PATH

- name: Get artifact name
id: get_file_paths
run: |
OUTPUT=$(bundle exec fastlane get_artifact_name \
--env $_BW_ENV \
build_mode:$_BUILD_MODE \
version_name:$_VERSION_NAME \
version_number:$_VERSION_NUMBER \
xcode_version:$_XCODE_VERSION \
export_path:$_EXPORT_PATH)

ARTIFACT_NAME=$(echo "$OUTPUT" | grep "artifact_filename: " | cut -d' ' -f3)
EXPORT_FILEPATH=$(echo "$OUTPUT" | grep "export_filepath: " | cut -d' ' -f3)

if [ -z "$ARTIFACT_NAME" ]; then
echo "::error::Failed to get artifact name"
exit 1
fi

if [ -z "$EXPORT_FILEPATH" ]; then
echo "::error::Failed to get export filepath"
exit 1
fi

echo "artifact_filename=$ARTIFACT_NAME" >> $GITHUB_OUTPUT
echo "export_filepath=$EXPORT_FILEPATH" >> $GITHUB_OUTPUT

- name: Upload artifacts to GitHub
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: ${{ steps.get_file_paths.outputs.artifact_filename }}
path: ${{ env._EXPORT_PATH }}
if-no-files-found: error

- name: Set up private auth key
if: env._BUILD_MODE == 'Device'
run: |
mkdir ~/private_keys
cat << EOF > ~/private_keys/AuthKey_J46C83CB96.p8
${{ secrets.APP_STORE_CONNECT_AUTH_KEY }}
EOF

- name: Validate app with App Store Connect
if: env._BUILD_MODE == 'Device'
env:
_EXPORT_FILEPATH: ${{ steps.get_file_paths.outputs.export_filepath }}
run: |
xcrun altool --validate-app \
--type ios \
--file "$_EXPORT_FILEPATH" \
--apiKey "J46C83CB96" \
--apiIssuer "${{ secrets.APP_STORE_CONNECT_TEAM_ISSUER }}"

- name: Upload dSYM files to Crashlytics
if: ${{ env._BUILD_MODE == 'Device' && startsWith(env._BW_ENV, 'bwpm') }}
continue-on-error: true
run: |
find $_EXPORT_PATH/dSYMs -name "*.dSYM" \
-exec "build/DerivedData/SourcePackages/checkouts/firebase-ios-sdk/Crashlytics/upload-symbols" \
-gsp $_CRASHLYTICS_PATH \
-p ios -- {} +

- name: Upload app to TestFlight with Fastlane
if: ${{ inputs.distribute && env._BUILD_MODE == 'Device' }}
env:
_EXPORT_FILEPATH: ${{ steps.get_file_paths.outputs.export_filepath }}
run: |
echo "placeholder"
CHANGELOG="$(git show -s --format=%s)
$GITHUB_REPOSITORY/$GITHUB_REF_NAME @ $GITHUB_SHA
Xcode $_XCODE_VERSION
Compiler Flags: $_COMPILER_FLAGS
$_GITHUB_ACTION_RUN_URL"

fastlane upload_build \
api_key_path:"$HOME/secrets/appstoreconnect-fastlane.json" \
changelog:"$CHANGELOG" \
ipa_path:"$_EXPORT_FILEPATH"
31 changes: 31 additions & 0 deletions .github/workflows/_version.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,34 @@ on:
skip_checkout:
description: "Skip checking out the repository"
type: boolean
workflow_call:
inputs:
base_version_number:
description: "Base Version Number - Will be added to the calculated version number"
type: number
default: 0
version_name:
description: "Version Name Override - e.g. '2024.8.1'"
type: string
version_number:
description: "Version Number Override - e.g. '1021'"
type: string
patch_version:
description: "Patch Version Override - e.g. '999'"
type: string
distinct_id:
description: "Unique ID for this dispatch, used by dispatch-and-download.yml"
type: string
skip_checkout:
description: "Skip checking out the repository"
type: boolean
outputs:
version_name:
description: "Version Name"
value: ${{ jobs.calculate-version.outputs.version_name }}
version_number:
description: "Version Number"
value: ${{ jobs.calculate-version.outputs.version_number }}

env:
BASE_VERSION_NUMBER: ${{ inputs.base_version_number || 0 }}
Expand All @@ -29,6 +57,9 @@ jobs:
runs-on: ubuntu-22.04
permissions:
contents: read
outputs:
version_name: ${{ steps.calc-version-name.outputs.version_name }}
version_number: ${{ steps.calc-version-number.outputs.version_number }}
steps:
- name: Log inputs to job summary
run: |
Expand Down
9 changes: 9 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,15 @@ jobs:
--apiKey "J46C83CB96" \
--apiIssuer "${{ secrets.APP_STORE_CONNECT_TEAM_ISSUER }}"

- name: Upload dSYM files to Crashlytics
if: ${{ env._BUILD_MODE == 'Device' }}
continue-on-error: true
run: |
find export/dSYMs -name "*.dSYM" \
-exec "build/SourcePackages/checkouts/firebase-ios-sdk/Crashlytics/upload-symbols" \
-gsp Bitwarden/Application/Support/GoogleService-Info.plist \
-p ios -- {} +

- name: Upload app to TestFlight with Fastlane
if: ${{ inputs.distribute && env._BUILD_MODE == 'Device' }}
run: |
Expand Down
Loading