Compare commits

...

86 Commits

Author SHA1 Message Date
Amy Galles
5dedc37b07 Merge branch 'main' into agalles/automate-android-fastlane-patch 2025-06-04 20:54:16 -07:00
Amy Galles
34354b11e5 restore changelog changes 2025-06-04 20:48:52 -07:00
Amy Galles
3ad1121d01 revert changelog changes 2025-06-03 21:43:19 -07:00
Álison Fernandes
1ac697e84a Remove unused retrieveBuildFromGithub lane 2025-06-02 23:03:16 +01:00
Amy Galles
27e45a0646 add text for debugging 2025-06-02 14:22:02 -07:00
Amy Galles
814e3d3cb9 fix default track name 2025-06-02 14:16:15 -07:00
Álison Fernandes
fc4ec405da Support \n \t \r in changlogs 2025-06-02 15:20:08 +01:00
Álison Fernandes
45ee744ace Add fastlane patch 2025-06-02 14:12:49 +01:00
Álison Fernandes
99dfd53747 Passing track inputs to fastlane 2025-06-02 14:10:20 +01:00
Álison Fernandes
12afc04e92 Update run-as 2025-06-02 14:06:49 +01:00
Álison Fernandes
f73014f39e Add track inputs for testing 2025-06-02 14:04:51 +01:00
Álison Fernandes
0cce938248 Fix track_promote_release_status 2025-06-02 13:53:04 +01:00
Álison Fernandes
e7e94e9a81 Update tracks for testing 2025-06-02 13:52:06 +01:00
Amy Galles
21d8b24522 resolve merge conflict 2025-05-30 11:50:41 -07:00
Amy Galles
1128680ff2 Missing comma 2025-05-30 11:47:46 -07:00
Amy Galles
21a810303c Fix track name 2025-05-30 11:45:29 -07:00
Amy Galles
a08210414c Merge branch 'main' into agalles/automate-android 2025-05-30 11:40:05 -07:00
Amy Galles
90fcb747e5 add newline 2025-05-30 11:35:23 -07:00
Amy Galles
bbade469c1 remove optional release notes 2025-05-29 13:49:15 -07:00
Amy Galles
738f502a36 remove optional release notes 2025-05-29 13:48:55 -07:00
Amy Galles
3f33f03459 update percentage leaving notes intact 2025-05-29 13:44:15 -07:00
Amy Galles
f954e1637d fix string with to_f 2025-05-29 13:29:23 -07:00
Amy Galles
64fb2ab341 digit not a string 2025-05-29 13:21:02 -07:00
Amy Galles
08a04cf419 missing comma 2025-05-29 13:18:21 -07:00
Amy Galles
d770f43b82 redoing percentage to decimal 2025-05-29 13:16:26 -07:00
Amy Galles
ef18b502b8 switching to test mode 2025-05-29 13:00:32 -07:00
Amy Galles
aefee591e1 streamline rollout percentage options 2025-05-29 09:24:36 -07:00
Amy Galles
4d2f130f0a updating locales for pw manager vs auth 2025-05-29 09:06:35 -07:00
Amy Galles
669fcc3448 temporarily removing languages 2025-05-29 08:58:18 -07:00
Amy Galles
47aaa79dc3 changing track name for Production 2025-05-29 08:41:55 -07:00
Amy Galles
9249bed287 staging to production 2025-05-29 08:32:52 -07:00
Amy Galles
441da4e3f2 trying to format release notes again 2025-05-28 17:26:01 -07:00
Amy Galles
ffee7d6c8e move back to changelog directories 2025-05-28 17:12:44 -07:00
Amy Galles
b9e000e2ae try release notes directly 2025-05-28 17:09:06 -07:00
Amy Galles
f4bfeb5220 test change metadata directory 2025-05-28 16:56:51 -07:00
Amy Galles
3dcacee3f4 rename test track 2025-05-28 16:46:13 -07:00
Amy Galles
0156309b79 include metadata 2025-05-28 16:31:13 -07:00
Amy Galles
9210d63775 implementing suggestions from Álison 2025-05-28 16:25:53 -07:00
Amy Galles
7b385bb178 renamed track 2025-05-28 12:47:42 -07:00
Amy Galles
03b83b6e68 trying with a different release 2025-05-28 12:46:06 -07:00
Amy Galles
934d32d6ec typo in release_status? 2025-05-28 12:43:35 -07:00
Amy Galles
6fd9fa9d23 first deploy can't be staged 2025-05-28 12:41:40 -07:00
Amy Galles
b8a3d078f3 reenable publish 2025-05-28 12:38:31 -07:00
Amy Galles
3e3743f77e fix version names 2025-05-28 10:12:43 -07:00
Amy Galles
af15eca966 just get version codes again 2025-05-28 10:10:29 -07:00
Amy Galles
592c548fcb add back publish lanes 2025-05-28 10:01:43 -07:00
Amy Galles
fd647d88c8 adding version code 2025-05-28 10:00:32 -07:00
Amy Galles
c6be79d909 fix syntax error 2025-05-28 09:53:02 -07:00
Amy Galles
5717d5fe15 comment out other supply lanes 2025-05-28 09:50:34 -07:00
Amy Galles
3420efc3c3 run [09:44:46]: Could not find service account json file at path '/Users/amygalles/code/android/secrets/play_creds.json' to setup supply 2025-05-28 09:44:46 -07:00
Amy Galles
d2ce39b42e add product from input 2025-05-28 09:41:49 -07:00
Amy Galles
80f74e9aa3 fix syntax error 2025-05-28 09:37:13 -07:00
Amy Galles
a66c996143 just get package names 2025-05-28 09:34:11 -07:00
Amy Galles
b08b7c0b84 pointing at closed testing track 2025-05-28 08:53:02 -07:00
Amy Galles
26fb8ebf6e update track name 2025-05-27 18:23:11 -07:00
Amy Galles
b541599248 update fastfile 2025-05-27 18:18:27 -07:00
Amy Galles
03907f8e36 remove space 2025-05-27 18:15:55 -07:00
Amy Galles
563cd732b8 enabling promotion 2025-05-27 18:12:45 -07:00
Amy Galles
0823bfecc6 try fix parenthesis 2025-05-27 15:51:39 -07:00
Amy Galles
042e59fa5b try formatting release notes 2025-05-27 15:49:54 -07:00
Amy Galles
b45d03ac22 try formatting release notes 2025-05-27 15:46:27 -07:00
Amy Galles
28f4eb854f removing space 2025-05-27 15:31:03 -07:00
Amy Galles
3a0744a047 remove example text 2025-05-27 15:27:35 -07:00
Amy Galles
3f54e1180b trying changelog with example text 2025-05-27 15:25:16 -07:00
Amy Galles
10299848c6 trying changelog with interpolation 2025-05-27 15:21:29 -07:00
Amy Galles
d005f98008 add in release notes and version code 2025-05-27 15:12:32 -07:00
Amy Galles
4acfb56df7 Remove promote to production lane 2025-05-27 14:57:41 -07:00
Amy Galles
246c3e1768 test entry of release notes 2025-05-27 14:55:16 -07:00
Amy Galles
d400b4fcc2 remove reference to beta directory 2025-05-23 15:19:03 -07:00
Amy Galles
7434114d09 adding debugging text 2025-05-23 15:15:12 -07:00
Amy Galles
25cfc6d06f add trigger for updateReleaseNotes lane 2025-05-23 15:06:30 -07:00
Amy Galles
9de23fa205 adding back default credentials 2025-05-23 15:00:19 -07:00
Amy Galles
0c077cb3fb removing redundant check 2025-05-23 14:56:03 -07:00
Amy Galles
3702dcad42 add checkout repo 2025-05-23 13:33:32 -07:00
Amy Galles
3e4c227b13 adding release notes 2025-05-23 13:29:50 -07:00
Amy Galles
f9e822b03d testing a random change 2025-05-23 13:20:11 -07:00
Amy Galles
ba3b7f7135 removing run from fastlane command 2025-05-23 11:03:32 -07:00
Amy Galles
9fd6578083 refactoring redundant code 2025-05-23 08:51:17 -07:00
Amy Galles
f04bc7e2c3 fix formatting 2025-05-23 08:45:49 -07:00
Amy Galles
8f7c98574f removing unnecessary brackets 2025-05-23 08:41:21 -07:00
Amy Galles
ad6b0bb560 clarify some option text 2025-05-23 08:38:28 -07:00
Amy Galles
7fe29198a2 remove whitespace 2025-05-23 08:35:09 -07:00
Amy Galles
b1ce52596f move original release notes lane back 2025-05-23 08:34:31 -07:00
Amy Galles
9e7cddd24f add workflow for publishing to production 2025-05-23 08:32:04 -07:00
Amy Galles
c05f6219a9 add lane for updating notes and promoting to prod 2025-05-23 08:31:51 -07:00
Amy Galles
9deb39d745 adding release notes to Fastlane 2025-05-22 14:12:04 -07:00
4 changed files with 292 additions and 4 deletions

View File

@@ -1,14 +1,142 @@
name: Publish
run-name: "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-code:
description: "Build number to promote to production."
required: true
type: number
rollout-percentage:
description: "Percentage of users who will receive this version update."
required: true
type: choice
options:
- 10%
- 30%
- 50%
- 100%
release-notes:
description: "Change notes to be included with this release."
type: string
required: true
track-from:
description: "Track to promote from."
type: string
required: true
default: "internal"
track-target:
description: "Track to promote to."
type: string
required: true
default: "Fastlane Automation Testing Source"
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
jobs:
publish:
promote:
runs-on: ubuntu-24.04
name: Promote build to Production in Play Store
steps:
- name: TEST STEP
run: exit 0
- name: Display Options
run: |
echo "product: ${{ inputs.product }}"
echo "version-code: ${{ inputs.version-code }}"
echo "rollout-percentage: ${{ inputs.rollout-percentage }}"
echo "release-notes: ${{ inputs.release-notes }}"
echo "track-from: ${{ inputs.track-from }}"
echo "track-target: ${{ inputs.track-target }}"
- name: Check out repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Configure Ruby
uses: ruby/setup-ruby@ca041f971d66735f3e5ff1e21cc13e2d51e7e535 # v1.233.0
with:
bundler-cache: true
- name: Install Fastlane
run: |
gem install bundler:2.2.27
bundle config path vendor/bundle
bundle install --jobs 4 --retry 3
- name: Log in to Azure
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
with:
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
- 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 app_play-keystore.jks --file ${{ github.workspace }}/keystores/app_play-keystore.jks --output none
az storage blob download --account-name $ACCOUNT_NAME --container-name $CONTAINER_NAME \
--name app_upload-keystore.jks --file ${{ github.workspace }}/keystores/app_upload-keystore.jks --output none
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 app_beta_play-keystore.jks --file ${{ github.workspace }}/keystores/app_beta_play-keystore.jks --output none
az storage blob download --account-name $ACCOUNT_NAME --container-name $CONTAINER_NAME \
--name app_beta_upload-keystore.jks --file ${{ github.workspace }}/keystores/app_beta_upload-keystore.jks --output none
az storage blob download --account-name $ACCOUNT_NAME --container-name $CONTAINER_NAME \
--name google-services.json --file ${{ github.workspace }}/app/src/standardRelease/google-services.json --output none
- name: Format Release Notes
run: |
FORMATTED_MESSAGE="$( "${{ inputs.release-notes }}" | sed 's/ /\n/g')"
echo "RELEASE_NOTES<<EOF" >> $GITHUB_ENV
echo "$FORMATTED_MESSAGE" >> $GITHUB_ENV
echo "EOF" >> $GITHUB_ENV
- name: Promote Play Store version to production
env:
PLAY_KEYSTORE_PASSWORD: ${{ secrets.PLAY_BETA_KEYSTORE_PASSWORD }}
PLAY_KEY_PASSWORD: ${{ secrets.PLAY_BETA_KEY_PASSWORD }}
VERSION_CODE: ${{ inputs.version-code }}
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
decimal=$(echo "scale=2; ${ROLLOUT_PERCENTAGE/\%/} / 100" | bc)
bundle exec fastlane updateReleaseNotes \
releaseNotes:"$RELEASE_NOTES" \
versionCode:"$VERSION_CODE"
bundle exec fastlane promoteToProduction \
versionCode:"$VERSION_CODE" \
rolloutPercentage:$decimal \
packageName:"$PACKAGE_NAME"\
releaseNotes:"$RELEASE_NOTES"\
track:"$TRACK_FROM"\
trackPromoteTo:"$TRACK_TARGET"

View File

@@ -13,6 +13,9 @@
# Uncomment the line if you want fastlane to automatically update itself
# update_fastlane
require_relative 'patches/supply_custom_promote_config'
require_relative 'patches/supply_custom_promote'
default_platform(:android)
platform :android do
@@ -384,4 +387,48 @@ platform :android do
mapping: "authenticator/build/outputs/mapping/release/mapping.txt",
)
end
desc "Update release notes for all locales."
lane :updateReleaseNotes do |options|
changelog = options[:releaseNotes]
version_code = options[:versionCode]
changelog = "\"#{changelog}\"".undump # Replaces literal \n and \t with actual newlines and tabs
UI.message("Changelog: #{changelog}")
auth_locales = ["en-US"]
pw_manager_locales = ["ca", "cs-CZ", "da-DK", "de-DE", "en-US", "es-ES", "et", "fr-FR", "hr", "hu-HU", "id", "it-IT", "iw-IL", "ja-JP", "nl-NL", "pl-PL", "pt-BR", "pt-PT", "ro", "ru-RU", "sk", "sv-SE", "tr-TR", "uk", "vi", "zh-CN", "zh-TW"]
if options[:packageName] == "com.bitwarden.authenticator"
locales = auth_locales
else
locales = pw_manager_locales
end
locales.each do |locale|
dir = "metadata/android/#{locale}/changelogs"
FileUtils.mkdir_p(dir)
File.write("#{dir}/#{version_code}.txt", changelog)
end
end
desc "Promote to production."
lane :promoteToProduction do |options|
supply_options = {
package_name: options[:packageName],
version_code: options[:versionCode],
track: options[:track],
track_promote_to: options[:trackPromoteTo],
skip_release_verification: true,
skip_upload_apk: true,
skip_upload_aab: true,
skip_upload_metadata: false
}
if options[:rolloutPercentage].to_f < 1
supply_options[:track_promote_release_status] = "inProgress"
supply_options[:rollout] = options[:rolloutPercentage]
else
supply_options[:track_promote_release_status] = "completed"
end
supply(supply_options)
end
end

View File

@@ -0,0 +1,83 @@
module Supply
class Uploader
alias_method :original_promote_track, :promote_track
def promote_track
if Supply.config[:skip_release_verification]
custom_promote_track
else
original_promote_track
end
end
def custom_promote_track
UI.message("Using custom promotion logic")
track_from = client.tracks(Supply.config[:track]).first
unless track_from
UI.user_error!("Cannot promote from track '#{Supply.config[:track]}' - track doesn't exist")
end
releases = track_from.releases
version_code = Supply.config[:version_code].to_s
if !Supply.config[:skip_release_verification]
if version_code != ""
releases = releases.select do |release|
release.version_codes.include?(version_code)
end
else
releases = releases.select do |release|
release.status == Supply.config[:release_status]
end
end
if releases.size == 0
if version_code != ""
UI.user_error!("Cannot find release with version code '#{version_code}' to promote in track '#{Supply.config[:track]}'")
else
UI.user_error!("Track '#{Supply.config[:track]}' doesn't have any releases")
end
elsif releases.size > 1
UI.user_error!("Track '#{Supply.config[:track]}' has more than one release - use :version_code to filter the release to promote")
end
else
UI.message("Skipping release verification as per configuration.")
if version_code == ""
UI.user_error!("Must provide a version code when release verification is skipped.")
end
release = AndroidPublisher::TrackRelease.new(
version_codes: [version_code],
status: Supply.config[:track_promote_release_status] || Supply::ReleaseStatus::COMPLETED
)
end
release = releases.first unless Supply.config[:skip_release_verification]
track_to = client.tracks(Supply.config[:track_promote_to]).first || AndroidPublisher::Track.new(
track: Supply.config[:track_promote_to],
releases: []
)
rollout = (Supply.config[:rollout] || 0).to_f
if rollout > 0 && rollout < 1
release.status = Supply::ReleaseStatus::IN_PROGRESS
release.user_fraction = rollout
else
release.status = Supply.config[:track_promote_release_status]
release.user_fraction = nil
end
if track_to
# Its okay to set releases to an array containing the newest release
# Google Play will keep previous releases there this release is a partial rollout
track_to.releases = [release]
else
track_to = AndroidPublisher::Track.new(
track: Supply.config[:track_promote_to],
releases: [release]
)
end
client.update_track(Supply.config[:track_promote_to], track_to)
end
end
end

View File

@@ -0,0 +1,30 @@
module Supply
class Options
class << self
alias_method :original_available_options, :available_options
def available_options
original_options = original_available_options
custom_options = [
FastlaneCore::ConfigItem.new(
key: :skip_release_verification,
env_name: "SUPPLY_SKIP_RELEASE_VERIFICATION",
description: "If set to true, skips checking if the version code exists in the track before promoting",
type: Boolean,
default_value: false,
optional: true
)
]
# Only add custom options if they aren't already present
custom_options.each do |custom_option|
unless original_options.any? { |option| option.key == custom_option.key }
original_options << custom_option
end
end
original_options
end
end
end
end