mirror of
https://github.com/bitwarden/ios.git
synced 2025-12-10 00:42:29 -06:00
This commit is contained in:
parent
3aacd2538f
commit
9e3a1ca9b7
262
.github/workflows/_build-any.yml
vendored
262
.github/workflows/_build-any.yml
vendored
@ -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 "placeholder"
|
||||
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: |
|
||||
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
.github/workflows/_version.yml
vendored
31
.github/workflows/_version.yml
vendored
@ -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 }}
|
||||
@ -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: |
|
||||
|
||||
9
.github/workflows/build.yml
vendored
9
.github/workflows/build.yml
vendored
@ -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: |
|
||||
|
||||
71
.github/workflows/ci-bwa.yml
vendored
71
.github/workflows/ci-bwa.yml
vendored
@ -1,15 +1,80 @@
|
||||
name: CI / Authenticator
|
||||
run-name: ${{ github.event_name == 'workflow_dispatch' && format('Manual - Authenticator ({0})', inputs.build-mode) || 'CI - Authenticator' }}
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
build-mode:
|
||||
description: "Build Mode"
|
||||
required: true
|
||||
default: "Device"
|
||||
type: choice
|
||||
options:
|
||||
- Device
|
||||
- Simulator
|
||||
version-name:
|
||||
description: "Version Name Override - e.g. '2024.8.1'"
|
||||
type: string
|
||||
version-number:
|
||||
description: "Version Number Override - e.g. '1021'"
|
||||
type: string
|
||||
compiler-flags:
|
||||
description: "Compiler Flags - e.g. 'DEBUG_MENU FEATURE2'"
|
||||
type: string
|
||||
patch_version:
|
||||
description: "Order 999 - Overrides Patch version"
|
||||
type: boolean
|
||||
distribute:
|
||||
description: "Distribute to TestFlight"
|
||||
type: boolean
|
||||
default: true
|
||||
xcode-version:
|
||||
description: "Xcode Version Override - e.g. '15.2'"
|
||||
type: string
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
version:
|
||||
name: Calculate Version Name and Number
|
||||
uses: bitwarden/ios/.github/workflows/_version.yml@main
|
||||
with:
|
||||
base_version_number: 10
|
||||
version_name: ${{ inputs.version-name }}
|
||||
version_number: ${{ inputs.version-number }}
|
||||
patch_version: ${{ inputs.patch_version && '999' || '' }}
|
||||
secrets: inherit
|
||||
|
||||
build-manual:
|
||||
name: Build Manual
|
||||
name: Build Manual - ${{ inputs.build-mode }}
|
||||
needs: version
|
||||
if: ${{ github.event_name == 'workflow_dispatch' }}
|
||||
uses: bitwarden/ios/.github/workflows/_build-any.yml@main
|
||||
with:
|
||||
bw-env: bwa_prod
|
||||
build-mode: ${{ inputs.build-mode }}
|
||||
version-name: ${{ needs.version.outputs.version_name }}
|
||||
version-number: ${{ needs.version.outputs.version_number }} #TODO: refactor all inputs to be consistent with - or _
|
||||
compiler-flags: ${{ inputs.compiler-flags }}
|
||||
distribute: ${{ inputs.distribute }}
|
||||
secrets: inherit
|
||||
|
||||
build-public:
|
||||
name: Build CI
|
||||
needs: version
|
||||
if: ${{ github.event_name == 'push' }}
|
||||
uses: bitwarden/ios/.github/workflows/_build-any.yml@main
|
||||
strategy:
|
||||
matrix:
|
||||
env: [bwa_prod]
|
||||
include:
|
||||
- bw-env: bwa_prod
|
||||
build-mode: Device
|
||||
- bw-env: bwa_prod
|
||||
build-mode: Simulator
|
||||
with:
|
||||
environment: ${{ matrix.env }}
|
||||
bw-env: ${{ matrix.bw-env }}
|
||||
build-mode: ${{ matrix.build-mode }}
|
||||
version-name: ${{ needs.version.outputs.version_name }}
|
||||
version-number: ${{ needs.version.outputs.version_number }}
|
||||
secrets: inherit
|
||||
|
||||
83
.github/workflows/ci-bwpm.yml
vendored
83
.github/workflows/ci-bwpm.yml
vendored
@ -1,15 +1,92 @@
|
||||
name: CI / Password Manager
|
||||
run-name: ${{ github.event_name == 'workflow_dispatch' && format('Manual - Password Manager {0} ({1})', inputs.build-variant, inputs.build-mode) || 'CI - Password Manager' }}
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
build-variant:
|
||||
description: "Build Variant"
|
||||
required: true
|
||||
default: "Beta"
|
||||
type: choice
|
||||
options:
|
||||
- Beta
|
||||
- Production
|
||||
build-mode:
|
||||
description: "Build Mode"
|
||||
required: true
|
||||
default: "Device"
|
||||
type: choice
|
||||
options:
|
||||
- Device
|
||||
- Simulator
|
||||
version-name:
|
||||
description: "Version Name Override - e.g. '2024.8.1'"
|
||||
type: string
|
||||
version-number:
|
||||
description: "Version Number Override - e.g. '1021'"
|
||||
type: string
|
||||
compiler-flags:
|
||||
description: "Compiler Flags - e.g. 'DEBUG_MENU FEATURE2'"
|
||||
type: string
|
||||
patch_version:
|
||||
description: "Order 999 - Overrides Patch version"
|
||||
type: boolean
|
||||
distribute:
|
||||
description: "Distribute to TestFlight"
|
||||
type: boolean
|
||||
default: true
|
||||
xcode-version:
|
||||
description: "Xcode Version Override - e.g. '15.2'"
|
||||
type: string
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
version:
|
||||
name: Calculate Version Name and Number
|
||||
uses: bitwarden/ios/.github/workflows/_version.yml@main
|
||||
with:
|
||||
base_version_number: 2100
|
||||
version_name: ${{ inputs.version-name }}
|
||||
version_number: ${{ inputs.version-number }}
|
||||
patch_version: ${{ inputs.patch_version && '999' || '' }}
|
||||
secrets: inherit
|
||||
|
||||
build-manual:
|
||||
name: Build Manual
|
||||
name: Build Manual - ${{ inputs.build-variant }} (${{ inputs.build-mode }})
|
||||
needs: version
|
||||
if: ${{ github.event_name == 'workflow_dispatch' }}
|
||||
uses: bitwarden/ios/.github/workflows/_build-any.yml@main
|
||||
with:
|
||||
bw-env: ${{ (inputs.build-variant == 'Production') && 'bwpm_prod' || 'bwpm_beta' }}
|
||||
build-mode: ${{ inputs.build-mode }}
|
||||
version-name: ${{ needs.version.outputs.version_name }}
|
||||
version-number: ${{ needs.version.outputs.version_number }} #TODO: refactor all inputs to be consistent with - or _
|
||||
compiler-flags: ${{ inputs.compiler-flags }}
|
||||
distribute: ${{ inputs.distribute }}
|
||||
secrets: inherit
|
||||
|
||||
build-public:
|
||||
name: Build CI
|
||||
needs: version
|
||||
if: ${{ github.event_name == 'push' }}
|
||||
uses: bitwarden/ios/.github/workflows/_build-any.yml@main
|
||||
strategy:
|
||||
matrix:
|
||||
env: [bwpm_prod]
|
||||
include:
|
||||
- bw-env: bwpm_prod
|
||||
build-mode: Device
|
||||
- bw-env: bwpm_prod
|
||||
build-mode: Simulator
|
||||
- bw-env: bwpm_beta
|
||||
build-mode: Device
|
||||
compiler-flags: DEBUG_MENU
|
||||
with:
|
||||
environment: ${{ matrix.env }}
|
||||
bw-env: ${{ matrix.bw-env }}
|
||||
build-mode: ${{ matrix.build-mode }}
|
||||
version-name: ${{ needs.version.outputs.version_name }}
|
||||
version-number: ${{ needs.version.outputs.version_number }}
|
||||
compiler-flags: ${{ matrix.compiler-flags }}
|
||||
secrets: inherit
|
||||
|
||||
@ -1 +1 @@
|
||||
3.2.2
|
||||
3.4.2
|
||||
|
||||
14
Gemfile
14
Gemfile
@ -1,3 +1,17 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
source "https://rubygems.org"
|
||||
|
||||
ruby file: '.ruby-version'
|
||||
|
||||
gem 'dotenv', groups: [:bwpm_prod, :bwpm_beta, :bwa_prod]
|
||||
gem 'fastlane'
|
||||
|
||||
# Since ruby 3.4.0 these are not included in the standard library
|
||||
gem 'abbrev'
|
||||
gem 'logger'
|
||||
gem 'mutex_m'
|
||||
gem 'csv'
|
||||
|
||||
# Starting with Ruby 3.5.0, these are not included in the standard library
|
||||
gem 'ostruct'
|
||||
|
||||
239
Gemfile.lock
Normal file
239
Gemfile.lock
Normal file
@ -0,0 +1,239 @@
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
CFPropertyList (3.0.7)
|
||||
base64
|
||||
nkf
|
||||
rexml
|
||||
abbrev (0.1.2)
|
||||
addressable (2.8.7)
|
||||
public_suffix (>= 2.0.2, < 7.0)
|
||||
artifactory (3.0.17)
|
||||
atomos (0.1.3)
|
||||
aws-eventstream (1.3.2)
|
||||
aws-partitions (1.1088.0)
|
||||
aws-sdk-core (3.222.2)
|
||||
aws-eventstream (~> 1, >= 1.3.0)
|
||||
aws-partitions (~> 1, >= 1.992.0)
|
||||
aws-sigv4 (~> 1.9)
|
||||
base64
|
||||
jmespath (~> 1, >= 1.6.1)
|
||||
logger
|
||||
aws-sdk-kms (1.99.0)
|
||||
aws-sdk-core (~> 3, >= 3.216.0)
|
||||
aws-sigv4 (~> 1.5)
|
||||
aws-sdk-s3 (1.183.0)
|
||||
aws-sdk-core (~> 3, >= 3.216.0)
|
||||
aws-sdk-kms (~> 1)
|
||||
aws-sigv4 (~> 1.5)
|
||||
aws-sigv4 (1.11.0)
|
||||
aws-eventstream (~> 1, >= 1.0.2)
|
||||
babosa (1.0.4)
|
||||
base64 (0.2.0)
|
||||
claide (1.1.0)
|
||||
colored (1.2)
|
||||
colored2 (3.1.2)
|
||||
commander (4.6.0)
|
||||
highline (~> 2.0.0)
|
||||
csv (3.3.4)
|
||||
declarative (0.0.20)
|
||||
digest-crc (0.7.0)
|
||||
rake (>= 12.0.0, < 14.0.0)
|
||||
domain_name (0.6.20240107)
|
||||
dotenv (2.8.1)
|
||||
emoji_regex (3.2.3)
|
||||
excon (0.112.0)
|
||||
faraday (1.10.4)
|
||||
faraday-em_http (~> 1.0)
|
||||
faraday-em_synchrony (~> 1.0)
|
||||
faraday-excon (~> 1.1)
|
||||
faraday-httpclient (~> 1.0)
|
||||
faraday-multipart (~> 1.0)
|
||||
faraday-net_http (~> 1.0)
|
||||
faraday-net_http_persistent (~> 1.0)
|
||||
faraday-patron (~> 1.0)
|
||||
faraday-rack (~> 1.0)
|
||||
faraday-retry (~> 1.0)
|
||||
ruby2_keywords (>= 0.0.4)
|
||||
faraday-cookie_jar (0.0.7)
|
||||
faraday (>= 0.8.0)
|
||||
http-cookie (~> 1.0.0)
|
||||
faraday-em_http (1.0.0)
|
||||
faraday-em_synchrony (1.0.0)
|
||||
faraday-excon (1.1.0)
|
||||
faraday-httpclient (1.0.1)
|
||||
faraday-multipart (1.1.0)
|
||||
multipart-post (~> 2.0)
|
||||
faraday-net_http (1.0.2)
|
||||
faraday-net_http_persistent (1.2.0)
|
||||
faraday-patron (1.0.0)
|
||||
faraday-rack (1.0.0)
|
||||
faraday-retry (1.0.3)
|
||||
faraday_middleware (1.2.1)
|
||||
faraday (~> 1.0)
|
||||
fastimage (2.4.0)
|
||||
fastlane (2.227.1)
|
||||
CFPropertyList (>= 2.3, < 4.0.0)
|
||||
addressable (>= 2.8, < 3.0.0)
|
||||
artifactory (~> 3.0)
|
||||
aws-sdk-s3 (~> 1.0)
|
||||
babosa (>= 1.0.3, < 2.0.0)
|
||||
bundler (>= 1.12.0, < 3.0.0)
|
||||
colored (~> 1.2)
|
||||
commander (~> 4.6)
|
||||
dotenv (>= 2.1.1, < 3.0.0)
|
||||
emoji_regex (>= 0.1, < 4.0)
|
||||
excon (>= 0.71.0, < 1.0.0)
|
||||
faraday (~> 1.0)
|
||||
faraday-cookie_jar (~> 0.0.6)
|
||||
faraday_middleware (~> 1.0)
|
||||
fastimage (>= 2.1.0, < 3.0.0)
|
||||
fastlane-sirp (>= 1.0.0)
|
||||
gh_inspector (>= 1.1.2, < 2.0.0)
|
||||
google-apis-androidpublisher_v3 (~> 0.3)
|
||||
google-apis-playcustomapp_v1 (~> 0.1)
|
||||
google-cloud-env (>= 1.6.0, < 2.0.0)
|
||||
google-cloud-storage (~> 1.31)
|
||||
highline (~> 2.0)
|
||||
http-cookie (~> 1.0.5)
|
||||
json (< 3.0.0)
|
||||
jwt (>= 2.1.0, < 3)
|
||||
mini_magick (>= 4.9.4, < 5.0.0)
|
||||
multipart-post (>= 2.0.0, < 3.0.0)
|
||||
naturally (~> 2.2)
|
||||
optparse (>= 0.1.1, < 1.0.0)
|
||||
plist (>= 3.1.0, < 4.0.0)
|
||||
rubyzip (>= 2.0.0, < 3.0.0)
|
||||
security (= 0.1.5)
|
||||
simctl (~> 1.6.3)
|
||||
terminal-notifier (>= 2.0.0, < 3.0.0)
|
||||
terminal-table (~> 3)
|
||||
tty-screen (>= 0.6.3, < 1.0.0)
|
||||
tty-spinner (>= 0.8.0, < 1.0.0)
|
||||
word_wrap (~> 1.0.0)
|
||||
xcodeproj (>= 1.13.0, < 2.0.0)
|
||||
xcpretty (~> 0.4.1)
|
||||
xcpretty-travis-formatter (>= 0.0.3, < 2.0.0)
|
||||
fastlane-sirp (1.0.0)
|
||||
sysrandom (~> 1.0)
|
||||
gh_inspector (1.1.3)
|
||||
google-apis-androidpublisher_v3 (0.54.0)
|
||||
google-apis-core (>= 0.11.0, < 2.a)
|
||||
google-apis-core (0.11.3)
|
||||
addressable (~> 2.5, >= 2.5.1)
|
||||
googleauth (>= 0.16.2, < 2.a)
|
||||
httpclient (>= 2.8.1, < 3.a)
|
||||
mini_mime (~> 1.0)
|
||||
representable (~> 3.0)
|
||||
retriable (>= 2.0, < 4.a)
|
||||
rexml
|
||||
google-apis-iamcredentials_v1 (0.17.0)
|
||||
google-apis-core (>= 0.11.0, < 2.a)
|
||||
google-apis-playcustomapp_v1 (0.13.0)
|
||||
google-apis-core (>= 0.11.0, < 2.a)
|
||||
google-apis-storage_v1 (0.31.0)
|
||||
google-apis-core (>= 0.11.0, < 2.a)
|
||||
google-cloud-core (1.8.0)
|
||||
google-cloud-env (>= 1.0, < 3.a)
|
||||
google-cloud-errors (~> 1.0)
|
||||
google-cloud-env (1.6.0)
|
||||
faraday (>= 0.17.3, < 3.0)
|
||||
google-cloud-errors (1.5.0)
|
||||
google-cloud-storage (1.47.0)
|
||||
addressable (~> 2.8)
|
||||
digest-crc (~> 0.4)
|
||||
google-apis-iamcredentials_v1 (~> 0.1)
|
||||
google-apis-storage_v1 (~> 0.31.0)
|
||||
google-cloud-core (~> 1.6)
|
||||
googleauth (>= 0.16.2, < 2.a)
|
||||
mini_mime (~> 1.0)
|
||||
googleauth (1.8.1)
|
||||
faraday (>= 0.17.3, < 3.a)
|
||||
jwt (>= 1.4, < 3.0)
|
||||
multi_json (~> 1.11)
|
||||
os (>= 0.9, < 2.0)
|
||||
signet (>= 0.16, < 2.a)
|
||||
highline (2.0.3)
|
||||
http-cookie (1.0.8)
|
||||
domain_name (~> 0.5)
|
||||
httpclient (2.9.0)
|
||||
mutex_m
|
||||
jmespath (1.6.2)
|
||||
json (2.10.2)
|
||||
jwt (2.10.1)
|
||||
base64
|
||||
logger (1.7.0)
|
||||
mini_magick (4.13.2)
|
||||
mini_mime (1.1.5)
|
||||
multi_json (1.15.0)
|
||||
multipart-post (2.4.1)
|
||||
mutex_m (0.3.0)
|
||||
nanaimo (0.4.0)
|
||||
naturally (2.2.1)
|
||||
nkf (0.2.0)
|
||||
optparse (0.6.0)
|
||||
os (1.1.4)
|
||||
ostruct (0.6.1)
|
||||
plist (3.7.2)
|
||||
public_suffix (6.0.1)
|
||||
rake (13.2.1)
|
||||
representable (3.2.0)
|
||||
declarative (< 0.1.0)
|
||||
trailblazer-option (>= 0.1.1, < 0.2.0)
|
||||
uber (< 0.2.0)
|
||||
retriable (3.1.2)
|
||||
rexml (3.4.1)
|
||||
rouge (3.28.0)
|
||||
ruby2_keywords (0.0.5)
|
||||
rubyzip (2.4.1)
|
||||
security (0.1.5)
|
||||
signet (0.19.0)
|
||||
addressable (~> 2.8)
|
||||
faraday (>= 0.17.5, < 3.a)
|
||||
jwt (>= 1.5, < 3.0)
|
||||
multi_json (~> 1.10)
|
||||
simctl (1.6.10)
|
||||
CFPropertyList
|
||||
naturally
|
||||
sysrandom (1.0.5)
|
||||
terminal-notifier (2.0.0)
|
||||
terminal-table (3.0.2)
|
||||
unicode-display_width (>= 1.1.1, < 3)
|
||||
trailblazer-option (0.1.2)
|
||||
tty-cursor (0.7.1)
|
||||
tty-screen (0.8.2)
|
||||
tty-spinner (0.9.3)
|
||||
tty-cursor (~> 0.7)
|
||||
uber (0.1.0)
|
||||
unicode-display_width (2.6.0)
|
||||
word_wrap (1.0.0)
|
||||
xcodeproj (1.27.0)
|
||||
CFPropertyList (>= 2.3.3, < 4.0)
|
||||
atomos (~> 0.1.3)
|
||||
claide (>= 1.0.2, < 2.0)
|
||||
colored2 (~> 3.1)
|
||||
nanaimo (~> 0.4.0)
|
||||
rexml (>= 3.3.6, < 4.0)
|
||||
xcpretty (0.4.1)
|
||||
rouge (~> 3.28.0)
|
||||
xcpretty-travis-formatter (1.0.1)
|
||||
xcpretty (~> 0.2, >= 0.0.7)
|
||||
|
||||
PLATFORMS
|
||||
arm64-darwin-24
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
abbrev
|
||||
csv
|
||||
dotenv
|
||||
fastlane
|
||||
logger
|
||||
mutex_m
|
||||
ostruct
|
||||
|
||||
RUBY VERSION
|
||||
ruby 3.4.2p28
|
||||
|
||||
BUNDLED WITH
|
||||
2.6.8
|
||||
17
fastlane/.env.bwa_prod
Normal file
17
fastlane/.env.bwa_prod
Normal file
@ -0,0 +1,17 @@
|
||||
_APP="authenticator"
|
||||
_BUILD_VARIANT=Production
|
||||
_BUILD_SCHEME=Authenticator
|
||||
_BUILD_PROJECT_PATH=project-bwa.yml
|
||||
_PROVISIONING_PROFILES="
|
||||
dist_authenticator.mobileprovision,
|
||||
"
|
||||
_PROVISIONING_PROFILE_PREFIX="Dist:"
|
||||
_AZ_CRASHLYTICS_FILE_NAME=GoogleService-Info.plist
|
||||
_CRASHLYTICS_PATH=Authenticator/Application/Support/GoogleService-Info.plist
|
||||
_PLIST_EXPORT_COMPLIANCE_CODE=ecf076d3-4824-4d7b-b716-2a9a47d7d296
|
||||
_BUNDLE_ID=com.bitwarden.authenticator
|
||||
_GROUP_ID=group.com.bitwarden.bitwarden-authenticator
|
||||
_APP_ICON=AppIcon
|
||||
_APS_ENVIRONMENT_DEVICE=production
|
||||
_APS_ENVIRONMENT_SIMULATOR=development
|
||||
_LOCAL_XCCONFIG_PATH=Configs/Local-bwa.xcconfig
|
||||
23
fastlane/.env.bwpm_beta
Normal file
23
fastlane/.env.bwpm_beta
Normal file
@ -0,0 +1,23 @@
|
||||
_APP="password_manager"
|
||||
_BUILD_VARIANT=Beta
|
||||
_BUILD_SCHEME=Bitwarden
|
||||
_BUILD_PROJECT_PATH=project-pm.yml
|
||||
_PROVISIONING_PROFILES="
|
||||
dist_beta_autofill.mobileprovision,
|
||||
dist_beta_bitwarden.mobileprovision,
|
||||
dist_beta_extension.mobileprovision,
|
||||
dist_beta_share_extension.mobileprovision,
|
||||
dist_beta_bitwarden_watch_app.mobileprovision,
|
||||
dist_beta_bitwarden_watch_app_extension.mobileprovision,
|
||||
dist_beta_bitwarden_watch_widget_extension.mobileprovision
|
||||
"
|
||||
_PROVISIONING_PROFILE_PREFIX="Dist: Beta"
|
||||
_AZ_CRASHLYTICS_FILE_NAME=GoogleService-Info-ios-pm-beta.plist
|
||||
_CRASHLYTICS_PATH=Bitwarden/Application/Support/GoogleService-Info.plist
|
||||
_PLIST_EXPORT_COMPLIANCE_CODE=3dd3e32f-efa6-4d99-b410-28aa28b1cb77
|
||||
_BUNDLE_ID=com.8bit.bitwarden.beta
|
||||
_GROUP_ID=group.com.bitwarden.bitwarden-authenticator.beta
|
||||
_APP_ICON=AppIcon-Beta
|
||||
_APS_ENVIRONMENT_DEVICE=production
|
||||
_APS_ENVIRONMENT_SIMULATOR=development
|
||||
_LOCAL_XCCONFIG_PATH=Configs/Local-bwpm.xcconfig
|
||||
23
fastlane/.env.bwpm_prod
Normal file
23
fastlane/.env.bwpm_prod
Normal file
@ -0,0 +1,23 @@
|
||||
_APP="password_manager"
|
||||
_BUILD_VARIANT=Production
|
||||
_BUILD_SCHEME=Bitwarden
|
||||
_BUILD_PROJECT_PATH=project-pm.yml
|
||||
_PROVISIONING_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,
|
||||
dist_bitwarden_watch_widget_extension.mobileprovision
|
||||
"
|
||||
_PROVISIONING_PROFILE_PREFIX="Dist:"
|
||||
_AZ_CRASHLYTICS_FILE_NAME=GoogleService-Info.plist
|
||||
_CRASHLYTICS_PATH=Bitwarden/Application/Support/GoogleService-Info.plist
|
||||
_PLIST_EXPORT_COMPLIANCE_CODE=ecf076d3-4824-4d7b-b716-2a9a47d7d296
|
||||
_BUNDLE_ID=com.8bit.bitwarden
|
||||
_GROUP_ID=group.com.bitwarden.bitwarden-authenticator
|
||||
_APP_ICON=AppIcon
|
||||
_APS_ENVIRONMENT_DEVICE=production
|
||||
_APS_ENVIRONMENT_SIMULATOR=development
|
||||
_LOCAL_XCCONFIG_PATH=Configs/Local-bwpm.xcconfig
|
||||
@ -1 +1 @@
|
||||
app_identifier "com.8bit.bitwarden"
|
||||
app_identifier ENV["BUNDLE_ID"] || "com.8bit.bitwarden"
|
||||
|
||||
@ -10,25 +10,416 @@
|
||||
# https://docs.fastlane.tools/plugins/available-plugins
|
||||
#
|
||||
|
||||
# Uncomment the line if you want fastlane to automatically update itself
|
||||
# update_fastlane
|
||||
|
||||
default_platform(:ios)
|
||||
|
||||
APP_CONFIG_MAP = {
|
||||
"password_manager" => {
|
||||
project_filepath: "project-pm.yml",
|
||||
build_ipa_path: "build/Bitwarden/Bitwarden.ipa",
|
||||
build_dsyms_path: "build/Bitwarden.xcarchive/dSYMs",
|
||||
build_app_path: "build/DerivedData/Build/Products/Debug-iphonesimulator/Bitwarden.app",
|
||||
ci_build_info_filepath: "BitwardenShared/Core/Platform/Utilities/CIBuildInfo.swift",
|
||||
},
|
||||
"authenticator" => {
|
||||
project_filepath: "project-bwa.yml",
|
||||
build_ipa_path: "build/Authenticator/Authenticator.ipa",
|
||||
build_dsyms_path: "build/Authenticator.xcarchive/dSYMs",
|
||||
build_app_path: "build/DerivedData/Build/Products/Debug-iphonesimulator/Authenticator.app",
|
||||
ci_build_info_filepath: "AuthenticatorShared/Core/Platform/Utilities/CIBuildInfo.swift",
|
||||
},
|
||||
}
|
||||
|
||||
ARTIFACT_EXTENSION = {
|
||||
"simulator" => "app",
|
||||
"device" => "ipa",
|
||||
}
|
||||
|
||||
platform :ios do |options|
|
||||
before_all do
|
||||
ensure_env_vars(
|
||||
env_vars: ['_APP']
|
||||
)
|
||||
app = ENV["_APP"]
|
||||
lane_context[:APP] = app
|
||||
lane_context[:APP_CONFIG] = APP_CONFIG_MAP[app]
|
||||
end
|
||||
|
||||
lane :setup_code_files do |options|
|
||||
if(lane_context[:APP] == 'password_manager')
|
||||
update_plists options
|
||||
end
|
||||
create_config_files options
|
||||
update_version_info options
|
||||
end
|
||||
|
||||
lane :post_build do |options|
|
||||
prepare_artifacts options
|
||||
end
|
||||
|
||||
lane :get_artifact_name do |options|
|
||||
required_options = [
|
||||
:build_mode,
|
||||
:version_name,
|
||||
:version_number,
|
||||
:xcode_version,
|
||||
:export_path,
|
||||
]
|
||||
ensure_required_options(options, required_options)
|
||||
|
||||
ensure_env_vars(
|
||||
env_vars: ['_BUNDLE_ID', '_BUILD_SCHEME']
|
||||
)
|
||||
|
||||
build_mode = ensure_build_mode(options[:build_mode])
|
||||
version_name = options[:version_name]
|
||||
version_number = options[:version_number]
|
||||
xcode_version = options[:xcode_version]
|
||||
export_path = options[:export_path]
|
||||
|
||||
bundle_id = ENV["_BUNDLE_ID"]
|
||||
build_scheme = ENV["_BUILD_SCHEME"]
|
||||
ext = ARTIFACT_EXTENSION[build_mode]
|
||||
app_config = lane_context[:APP_CONFIG]
|
||||
UI.message "artifact_filename: #{bundle_id}-#{version_name}(#{version_number})-#{xcode_version}.#{ext}"
|
||||
UI.message "export_filepath: #{export_path}/#{build_scheme}.#{ext}"
|
||||
end
|
||||
|
||||
desc "Load .env variables (underscore prefixed) to GITHUB_ENV"
|
||||
lane :load_dotenv_file do |options|
|
||||
envfile = Dotenv.parse(".env.#{lane_context[:ENVIRONMENT]}")
|
||||
|
||||
envfile.each do |key, value|
|
||||
value_cleaned = Shellwords.shellescape(value.to_s.delete(" \t\r\n"))
|
||||
sh "echo #{key}='#{value_cleaned}' >> $GITHUB_ENV"
|
||||
end
|
||||
end
|
||||
|
||||
desc "Update CI build info"
|
||||
lane :update_ci_build_info do |options|
|
||||
required_options = [
|
||||
:repository,
|
||||
:branch,
|
||||
:commit_hash,
|
||||
:ci_run_number,
|
||||
:ci_run_attempt,
|
||||
]
|
||||
|
||||
ensure_required_options(options, required_options)
|
||||
|
||||
repository = options[:repository]
|
||||
branch = options[:branch]
|
||||
commit_hash = options[:commit_hash]
|
||||
ci_run_number = options[:ci_run_number]
|
||||
ci_run_attempt = options[:ci_run_attempt]
|
||||
compiler_flags = options[:compiler_flags]
|
||||
|
||||
app_config = lane_context[:APP_CONFIG]
|
||||
ci_build_info_filepath = app_config[:ci_build_info_filepath]
|
||||
|
||||
git_source = "#{repository}/#{branch}@#{commit_hash}"
|
||||
ci_run_source = "#{repository}/actions/runs/#{ci_run_number}/attempts/#{ci_run_attempt}"
|
||||
|
||||
UI.message("🧱 Updating app CI Build info with:")
|
||||
UI.message("🧱 commit: #{git_source}")
|
||||
UI.message("💻 build source: #{ci_run_source}")
|
||||
UI.message("🛠️ compiler flags: #{compiler_flags}")
|
||||
|
||||
Dir.chdir("..") do
|
||||
FileUtils.mkdir_p(File.dirname(ci_build_info_filepath))
|
||||
File.write(ci_build_info_filepath, <<~CONTENT)
|
||||
enum CIBuildInfo {
|
||||
static let info: KeyValuePairs<String, String> = [
|
||||
"🧱 commit:": "#{git_source}",
|
||||
"💻 build source:": "#{ci_run_source}",
|
||||
"🛠️ compiler flags:": "#{compiler_flags}",
|
||||
]
|
||||
}
|
||||
CONTENT
|
||||
end
|
||||
|
||||
UI.success("🧱 Successfully updated app CI Build info")
|
||||
end
|
||||
|
||||
desc "Push a new build to TestFlight"
|
||||
lane :upload_build do |options|
|
||||
upload_to_testflight(
|
||||
skip_submission: false,
|
||||
changelog: options[:changelog],
|
||||
skip_waiting_for_build_processing: false,
|
||||
api_key_path: options[:api_key_path],
|
||||
ipa: options[:ipa_path],
|
||||
localized_build_info: {
|
||||
"default": {
|
||||
whats_new: options[:changelog],
|
||||
upload_to_testflight(
|
||||
skip_submission: false,
|
||||
changelog: options[:changelog],
|
||||
skip_waiting_for_build_processing: false,
|
||||
api_key_path: options[:api_key_path],
|
||||
ipa: options[:ipa_path],
|
||||
localized_build_info: {
|
||||
"default": {
|
||||
whats_new: options[:changelog],
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
desc "Update plists for Password Manager"
|
||||
private_lane :update_plists do |options|
|
||||
required_options = [
|
||||
:build_mode
|
||||
]
|
||||
ensure_required_options(options, required_options)
|
||||
|
||||
ensure_env_vars(
|
||||
env_vars: ['_BUNDLE_ID', '_PLIST_EXPORT_COMPLIANCE_CODE', '_APS_ENVIRONMENT_DEVICE', '_APS_ENVIRONMENT_SIMULATOR']
|
||||
)
|
||||
|
||||
build_mode = ensure_build_mode(options[:build_mode])
|
||||
|
||||
update_plist(
|
||||
plist_path: "Bitwarden/Application/Support/Info.plist",
|
||||
block: proc do |plist|
|
||||
plist["ITSEncryptionExportComplianceCode"] = ENV['_PLIST_EXPORT_COMPLIANCE_CODE']
|
||||
end
|
||||
)
|
||||
UI.message("✅ Updated Info.plist with ITSEncryptionExportComplianceCode: #{ENV['_PLIST_EXPORT_COMPLIANCE_CODE']}")
|
||||
|
||||
aps_env = if(build_mode == 'device')
|
||||
ENV['_APS_ENVIRONMENT_DEVICE']
|
||||
else
|
||||
ENV['_APS_ENVIRONMENT_SIMULATOR']
|
||||
end
|
||||
update_plist(
|
||||
plist_path: "Bitwarden/Application/Support/Bitwarden.entitlements",
|
||||
block: proc do |plist|
|
||||
plist["aps-environment"] = aps_env
|
||||
end
|
||||
)
|
||||
UI.message("✅ Updated Bitwarden.entitlements with aps-environment: #{aps_env}")
|
||||
|
||||
update_plist(
|
||||
plist_path: "BitwardenWatchApp/GoogleService-Info.plist",
|
||||
block: proc do |plist|
|
||||
plist["BUNDLE_ID"] = ENV["_BUNDLE_ID"] + ".watchkitapp"
|
||||
end
|
||||
)
|
||||
UI.message("✅ Updated GoogleService-Info.plist with BUNDLE_ID: #{ENV['_BUNDLE_ID']}.watchkitapp")
|
||||
end
|
||||
|
||||
desc "Update version info in project yaml file"
|
||||
private_lane :update_version_info do |options|
|
||||
#require 'yaml'
|
||||
|
||||
required_options = [
|
||||
:version_name,
|
||||
:version_number,
|
||||
]
|
||||
|
||||
ensure_required_options(options, required_options)
|
||||
|
||||
app_config = lane_context[:APP_CONFIG]
|
||||
project_filepath = app_config[:project_filepath]
|
||||
|
||||
version_name = options[:version_name]
|
||||
version_number = options[:version_number]
|
||||
|
||||
UI.message("Updating #{project_filepath} with version name: #{version_name} and version number: #{version_number}")
|
||||
|
||||
update_version_yq(project_filepath, version_name, version_number)
|
||||
|
||||
UI.success("Updated #{project_filepath} version to #{version_name}(#{version_number})")
|
||||
end
|
||||
|
||||
desc "Create config files with build variant and compiler flags"
|
||||
private_lane :create_config_files do |options|
|
||||
compiler_flags = options[:compiler_flags] || ''
|
||||
|
||||
ensure_env_vars(
|
||||
env_vars: ['_BUNDLE_ID', '_GROUP_ID', '_PROVISIONING_PROFILE_PREFIX', '_APP_ICON', '_LOCAL_XCCONFIG_PATH']
|
||||
)
|
||||
|
||||
export_options_file = "Configs/export_options.plist"
|
||||
|
||||
local_xcconfig_file = ENV["_LOCAL_XCCONFIG_PATH"]
|
||||
bundle_id = ENV["_BUNDLE_ID"]
|
||||
shared_app_group_id = ENV["_GROUP_ID"]
|
||||
profile_prefix = ENV["_PROVISIONING_PROFILE_PREFIX"]
|
||||
app_icon = ENV["_APP_ICON"]
|
||||
|
||||
xcconfig_content = generate_xcconfig(lane_context[:APP], bundle_id, shared_app_group_id, app_icon, profile_prefix, compiler_flags)
|
||||
export_options_plist_content = generate_export_options_plist(lane_context[:APP], bundle_id, profile_prefix)
|
||||
|
||||
Dir.chdir("..") do
|
||||
FileUtils.mkdir_p(File.dirname(local_xcconfig_file))
|
||||
FileUtils.mkdir_p(File.dirname(export_options_file))
|
||||
File.write(local_xcconfig_file, xcconfig_content.map { |key, value| "#{key} = #{value}" }.join("\n"))
|
||||
File.write(export_options_file, export_options_plist_content)
|
||||
end
|
||||
|
||||
if compiler_flags.include?("SUPPORTS_CXP")
|
||||
sh("./Scripts/alpha_update_cxp_infoplist.sh")
|
||||
end
|
||||
|
||||
UI.success("Successfully created config files for #{bundle_id}")
|
||||
end
|
||||
|
||||
def generate_xcconfig(app, bundle_id, shared_app_group_id, app_icon, profile_prefix, compiler_flags)
|
||||
case app
|
||||
when "password_manager"
|
||||
generate_xcconfig_content_bwpm(bundle_id, shared_app_group_id, app_icon, profile_prefix, compiler_flags)
|
||||
when "authenticator"
|
||||
generate_xcconfig_content_bwa(bundle_id, shared_app_group_id, app_icon, profile_prefix, compiler_flags)
|
||||
end
|
||||
end
|
||||
|
||||
def generate_export_options_plist(app, bundle_id, profile_prefix)
|
||||
case app
|
||||
when "password_manager"
|
||||
generate_export_options_plist_content_bwpm(bundle_id, profile_prefix)
|
||||
when "authenticator"
|
||||
generate_export_options_plist_content_bwa(bundle_id, profile_prefix)
|
||||
end
|
||||
end
|
||||
|
||||
def generate_xcconfig_content_bwpm(bundle_id, shared_app_group_id, app_icon, profile_prefix, compiler_flags)
|
||||
{
|
||||
"CODE_SIGN_STYLE" => "Manual",
|
||||
"CODE_SIGN_IDENTITY" => "Apple Distribution",
|
||||
"DEVELOPMENT_TEAM" => "LTZ2PFU5D6",
|
||||
"ORGANIZATION_IDENTIFIER" => "com.8bit",
|
||||
"BASE_BUNDLE_ID" => bundle_id,
|
||||
"SHARED_APP_GROUP_IDENTIFIER" => shared_app_group_id,
|
||||
"APPICON_NAME" => app_icon,
|
||||
"PROVISIONING_PROFILE_SPECIFIER" => "#{profile_prefix} Bitwarden",
|
||||
"PROVISIONING_PROFILE_SPECIFIER_ACTION_EXTENSION" => "#{profile_prefix} Extension",
|
||||
"PROVISIONING_PROFILE_SPECIFIER_AUTOFILL_EXTENSION" => "#{profile_prefix} Autofill",
|
||||
"PROVISIONING_PROFILE_SPECIFIER_SHARE_EXTENSION" => "#{profile_prefix} Share Extension",
|
||||
"PROVISIONING_PROFILE_SPECIFIER_WATCH_APP" => "#{profile_prefix} Bitwarden Watch App",
|
||||
"PROVISIONING_PROFILE_SPECIFIER_WATCH_WIDGET_EXTENSION" => "#{profile_prefix} Bitwarden Watch Widget Extension",
|
||||
"SWIFT_ACTIVE_COMPILATION_CONDITIONS" => "$(inherited) #{compiler_flags}"
|
||||
}
|
||||
end
|
||||
|
||||
def generate_export_options_plist_content_bwpm(bundle_id, profile_prefix)
|
||||
<<~PLIST
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>method</key>
|
||||
<string>app-store-connect</string>
|
||||
<key>provisioningProfiles</key>
|
||||
<dict>
|
||||
<key>#{bundle_id}</key>
|
||||
<string>#{profile_prefix} Bitwarden</string>
|
||||
<key>#{bundle_id}.find-login-action-extension</key>
|
||||
<string>#{profile_prefix} Extension</string>
|
||||
<key>#{bundle_id}.autofill</key>
|
||||
<string>#{profile_prefix} Autofill</string>
|
||||
<key>#{bundle_id}.share-extension</key>
|
||||
<string>#{profile_prefix} Share Extension</string>
|
||||
<key>#{bundle_id}.watchkitapp</key>
|
||||
<string>#{profile_prefix} Bitwarden Watch App</string>
|
||||
<key>#{bundle_id}.watchkitapp.widget-extension</key>
|
||||
<string>#{profile_prefix} Bitwarden Watch Widget Extension</string>
|
||||
</dict>
|
||||
<key>manageAppVersionAndBuildNumber</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</plist>
|
||||
PLIST
|
||||
end
|
||||
|
||||
def generate_xcconfig_content_bwa(bundle_id, shared_app_group_id, app_icon, profile_prefix, compiler_flags = "")
|
||||
{
|
||||
"CODE_SIGN_STYLE" => "Manual",
|
||||
"CODE_SIGN_IDENTITY" => "Apple Distribution",
|
||||
"DEVELOPMENT_TEAM" => "LTZ2PFU5D6",
|
||||
"ORGANIZATION_IDENTIFIER" => "com.8bit",
|
||||
"BASE_BUNDLE_ID" => bundle_id,
|
||||
"SHARED_APP_GROUP_IDENTIFIER" => shared_app_group_id,
|
||||
"APPICON_NAME" => app_icon,
|
||||
"PROVISIONING_PROFILE_SPECIFIER" => "#{profile_prefix} Bitwarden Authenticator",
|
||||
"SWIFT_ACTIVE_COMPILATION_CONDITIONS" => "$(inherited) #{compiler_flags}"
|
||||
}
|
||||
end
|
||||
|
||||
def generate_export_options_plist_content_bwa(bundle_id, profile_prefix)
|
||||
<<~PLIST
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>method</key>
|
||||
<string>app-store-connect</string>
|
||||
<key>provisioningProfiles</key>
|
||||
<dict>
|
||||
<key>#{bundle_id}</key>
|
||||
<string>#{profile_prefix} Bitwarden Authenticator</string>
|
||||
</dict>
|
||||
<key>manageAppVersionAndBuildNumber</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</plist>
|
||||
PLIST
|
||||
end
|
||||
|
||||
desc "Prepare artifacts for upload to GitHub"
|
||||
private_lane :prepare_artifacts do |options|
|
||||
required_options = [
|
||||
:build_mode,
|
||||
:export_path
|
||||
]
|
||||
ensure_required_options(options, required_options)
|
||||
|
||||
build_mode = ensure_build_mode(options[:build_mode])
|
||||
export_path = options[:export_path]
|
||||
app_config = lane_context[:APP_CONFIG]
|
||||
build_ipa_path = app_config[:build_ipa_path]
|
||||
build_dsyms_path = app_config[:build_dsyms_path]
|
||||
build_app_path = app_config[:build_app_path]
|
||||
|
||||
Dir.chdir("..") do
|
||||
case build_mode
|
||||
when 'simulator'
|
||||
sh("cp -r #{build_app_path} #{export_path}")
|
||||
when 'device'
|
||||
sh("cp #{build_ipa_path} #{export_path}")
|
||||
sh("cp -r #{build_dsyms_path}/*dSYM #{export_path}/dSYMs")
|
||||
else
|
||||
UI.user_error!("Invalid build mode: #{build_mode}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def ensure_required_options(options, required_options)
|
||||
missing_options = required_options.select { |option| options[option].nil? || options[option].empty? }
|
||||
|
||||
unless missing_options.empty?
|
||||
UI.user_error!("Missing required options: #{missing_options.join(', ')}")
|
||||
end
|
||||
end
|
||||
|
||||
def ensure_build_mode(build_mode)
|
||||
build_mode_lower = build_mode.downcase()
|
||||
unless build_mode_lower == 'simulator' || build_mode_lower == 'device'
|
||||
UI.user_error!("Invalid build mode: #{build_mode}")
|
||||
end
|
||||
return build_mode_lower
|
||||
end
|
||||
|
||||
def parse_env_list(env_value)
|
||||
env_value.to_s.delete(" \t\r\n").split(',')
|
||||
end
|
||||
|
||||
def update_version_yq(project_filepath, version_name, version_number)
|
||||
Dir.chdir("..") do
|
||||
sh("yq -i '.settings.MARKETING_VERSION = \"#{version_name}\"' '#{project_filepath}'")
|
||||
sh("yq -i '.settings.CURRENT_PROJECT_VERSION = \"#{version_number}\"' '#{project_filepath}'")
|
||||
end
|
||||
end
|
||||
|
||||
def update_version_yaml(project_filepath, version_name, version_number)
|
||||
project_yaml = YAML.load_file(project_filepath)
|
||||
|
||||
project_yaml['settings']['MARKETING_VERSION'] = version_name
|
||||
project_yaml['settings']['CURRENT_PROJECT_VERSION'] = version_number
|
||||
|
||||
File.open(project_filepath, 'w') do |file|
|
||||
file.write(project_yaml.to_yaml)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user