Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
19 changes: 15 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,10 +110,21 @@ the APK on the GitHub release. That is what keeps a version on a single commit -
the `v*` tag names and F-Droid builds.

Internal is the only track it uploads to. Anything wider - closed, open, production -
is a promotion in the Play Console, which moves the same bundle and version code that
was tested onto the wider track instead of uploading a second one. It is also where the
review that a production release waits on actually happens, so the workflow finishing is
not the same as the release being out.
is a promotion, which moves the same bundle and version code that was tested onto the
wider track instead of uploading a second one. A version code is spent the moment it
goes up, so there is one upload per release and every track after it is an assignment
of what is already there.

`fastlane android openTestingPro` and `openTestingLite` promote to open testing, given
the version whose code should move:

```sh
fastlane android openTestingLite version:v4.17.0
```

Closed testing and production are still the Play Console. Play reviews a promotion like
any other release - only the internal track is immediate - so neither the workflow
finishing nor the promotion running is the same as the release being out.

The listing goes up in its own job, behind the bundle: the title, both descriptions, the
release notes of that version, the screenshots and the feature graphic, in all fifteen
Expand Down
51 changes: 51 additions & 0 deletions fastlane/Fastfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ PACKAGE_NAMES = {

DEFAULT_TRACK = "internal".freeze

# what the console calls open testing. Supply kept the older track names, so the
# one a promotion has to name is not the one the console shows.
OPEN_TESTING_TRACK = "beta".freeze

# absolute, because a lane and an action do not agree on what the working directory
# is, and every path below is handed to something else
ROOT = File.expand_path("..", __dir__).freeze
Expand Down Expand Up @@ -174,6 +178,16 @@ platform :android do
uploadListing(flavor: "Lite", track: options[:track], version: options[:version])
end

desc "Move the Pro version already on the internal track to open testing"
lane :openTestingPro do |options|
promoteBundle(flavor: "Pro", version: options[:version])
end

desc "Move the Lite version already on the internal track to open testing"
lane :openTestingLite do |options|
promoteBundle(flavor: "Lite", version: options[:version])
end

lane :tests do
gradle(task: "connectedAndroidTest")
end
Expand Down Expand Up @@ -252,6 +266,43 @@ platform :android do
)
end

# A promotion, not a second upload: the bundle is already in the artifact library
# and a version code is spent the moment it goes up, so the wider track is handed
# the build the narrower one tested rather than one built again beside it.
#
# Play reviews this like any other release - what the lane saves is the console,
# not the wait. The source track keeps serving the release it is promoted from.
private_lane :promoteBundle do |options|
flavor = options[:flavor]
version = require_version(options[:version])

upload_to_play_store(
track: DEFAULT_TRACK,
track_promote_to: OPEN_TESTING_TRACK,
# spelled out rather than left to the default: a promotion that lands as a
# draft, or at a percent of the testers, is the failure that looks like success
track_promote_release_status: "completed",
package_name: PACKAGE_NAMES.fetch(flavor),
json_key: ENV["ODR_PLAY_JSON_KEY"] ||
CredentialsManager::AppfileConfig.try_fetch_value(:json_key_file),
# which release moves, and there is no bundle to read it off as uploadBundle
# has. It is a filter, not a label: supply keeps the source track's release
# carrying this code and errors when none does, so a version that never
# reached internal fails the lane rather than promoting what it is serving.
version_code: version_code(version),
# nothing new goes up here - the listing and its notes are already against
# this version code, and resending them is uploadListing's job. Skipping both
# binaries is what puts supply on the promotion path at all: hand it one to
# upload and it updates the source track and never reads track_promote_to.
skip_upload_aab: true,
skip_upload_apk: true,
skip_upload_metadata: true,
skip_upload_changelogs: true,
skip_upload_images: true,
skip_upload_screenshots: true
)
end

desc "Take the play store screenshots of one device, in every locale the listing is written in"
lane :screenshots do
device = screenshot_device
Expand Down
Loading