name: Publish to Google Play run-name: > ${{ inputs.dry-run && ' (Dry Run)' || '' }}Promoting ${{ inputs.product }} ${{ inputs.version-code }} from ${{ inputs.track-from }} to ${{ inputs.track-target }} on: workflow_dispatch: inputs: product: description: "Which app is being released." type: choice options: - Password Manager - Authenticator version-name: description: "Version name to promote to production ex 2025.1.1" type: string version-code: description: "Build number to promote to production." required: true type: string rollout-percentage: description: "Percentage of users who will receive this version update." required: true type: choice options: - 10% - 30% - 50% - 100% default: 10% release-notes: description: "Change notes to be included with this release." type: string default: "Bug fixes." required: true track-from: description: "Track to promote from." type: choice options: - internal - Fastlane Automation Source required: true default: "internal" track-target: description: "Track to promote to." type: choice options: - production - Fastlane Automation Target required: true dry-run: description: "Dry-Run, Run the workflow without publishing to the store" type: boolean default: false env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_ACTION_RUN_URL: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" permissions: contents: read packages: read id-token: write actions: write jobs: promote: runs-on: ubuntu-24.04 name: Promote build to Production in Play Store steps: - name: Log inputs to job summary uses: bitwarden/android/.github/actions/log-inputs@main with: inputs: "${{ toJson(inputs) }}" - name: Check out repo uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: Configure Ruby uses: ruby/setup-ruby@6aaa311d81eba98ae12eaffbcb63296ace0efcde # v1.307.0 with: bundler-cache: true - name: Install Fastlane run: | bundle config path vendor/bundle bundle install --jobs 4 --retry 3 - name: Log in to Azure uses: bitwarden/gh-actions/azure-login@main with: subscription_id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} tenant_id: ${{ secrets.AZURE_TENANT_ID }} client_id: ${{ secrets.AZURE_CLIENT_ID }} - name: Get Azure Key Vault secrets id: get-kv-secrets uses: bitwarden/gh-actions/get-keyvault-secrets@main with: keyvault: gh-android secrets: "PLAY-BETA-KEYSTORE-PASSWORD,PLAY-BETA-KEY-PASSWORD" - name: Retrieve secrets env: ACCOUNT_NAME: bitwardenci CONTAINER_NAME: mobile run: | mkdir -p ${{ github.workspace }}/secrets mkdir -p ${{ github.workspace }}/app/src/standardRelease az storage blob download --account-name "$ACCOUNT_NAME" --container-name "$CONTAINER_NAME" \ --name play_creds.json --file ${{ github.workspace }}/secrets/play_creds.json --output none az storage blob download --account-name "$ACCOUNT_NAME" --container-name "$CONTAINER_NAME" \ --name authenticator_play_store-creds.json --file ${{ github.workspace }}/secrets/authenticator_play_store-creds.json --output none - name: Log out from Azure uses: bitwarden/gh-actions/azure-logout@main - name: Format Release Notes env: RELEASE_NOTES: ${{ inputs.release-notes }} run: | FORMATTED_MESSAGE="$(echo "$RELEASE_NOTES" | sed 's/ /\n/g')" { echo "RELEASE_NOTES<> "$GITHUB_ENV" - name: Promote Play Store version to production env: PLAY_KEYSTORE_PASSWORD: ${{ steps.get-kv-secrets.outputs.PLAY-BETA-KEYSTORE-PASSWORD }} PLAY_KEY_PASSWORD: ${{ steps.get-kv-secrets.outputs.PLAY-BETA-KEY-PASSWORD }} VERSION_CODE_INPUT: ${{ inputs.version-code }} VERSION_NAME: ${{inputs.version-name}} ROLLOUT_PERCENTAGE: ${{ inputs.rollout-percentage }} PRODUCT: ${{ inputs.product }} TRACK_FROM: ${{ inputs.track-from }} TRACK_TARGET: ${{ inputs.track-target }} run: | if [ "$PRODUCT" = "Password Manager" ]; then PACKAGE_NAME="com.x8bit.bitwarden" elif [ "$PRODUCT" = "Authenticator" ]; then PACKAGE_NAME="com.bitwarden.authenticator" else echo "Unsupported product: $PRODUCT" exit 1 fi VERSION_CODE=$(echo "${VERSION_CODE_INPUT}" | tr -d ',') decimal=$(echo "scale=2; ${ROLLOUT_PERCENTAGE/\%/} / 100" | bc) bundle exec fastlane updateReleaseNotes \ releaseNotes:"$RELEASE_NOTES" \ versionCode:"$VERSION_CODE" \ packageName:"$PACKAGE_NAME" bundle exec fastlane promoteToProduction \ versionCode:"$VERSION_CODE" \ versionName:"$VERSION_NAME" \ rolloutPercentage:"$decimal" \ packageName:"$PACKAGE_NAME" \ releaseNotes:"$RELEASE_NOTES" \ track:"$TRACK_FROM" \ trackPromoteTo:"$TRACK_TARGET" - name: Enable Publish Github Release Workflow env: PRODUCT: ${{ inputs.product }} DRY_RUN: ${{ inputs.dry-run }} run: | if $DRY_RUN ; then gh workflow view publish-github-release-bwpm.yml exit 0 fi if [ "$PRODUCT" = "Password Manager" ]; then gh workflow enable publish-github-release-bwpm.yml elif [ "$PRODUCT" = "Authenticator" ]; then gh workflow enable publish-github-release-bwa.yml fi