Skip to content
Draft
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
7 changes: 4 additions & 3 deletions .buildkite/commands/lint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,18 @@ echo "--- 🧹 Linting"
./gradlew :app:lintRelease
app_lint_exit_code=$?

./gradlew :automotive:lintRelease :wear:lintRelease
automotive_wear_lint_exit_code=$?
./gradlew :automotive:lintRelease :tv:lintRelease :wear:lintRelease
other_apps_lint_exit_code=$?
Comment on lines +20 to +21

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggest --continue here now that three modules share one invocation.

abortOnError = true is set globally (build.gradle.kts:251), so the first module whose lint fails stops the invocation and the remaining lintRelease tasks never run. Their SARIF files are then never generated, and the corresponding upload_sarif_to_github calls at lines 31–32 silently upload nothing β€” so a TV lint error hides the wear report, and an automotive error hides both.

That's exactly the failure mode the comment on line 16 works around for :app:. It existed with two modules, but TV is a new module with a near-empty baseline (tv/lint-baseline.xml is 191 bytes) and it now sits before wear in the task list, so it's more likely to bite.

Suggested change
./gradlew :automotive:lintRelease :tv:lintRelease :wear:lintRelease
other_apps_lint_exit_code=$?
./gradlew --continue :automotive:lintRelease :tv:lintRelease :wear:lintRelease
other_apps_lint_exit_code=$?

--continue still yields a non-zero exit code, so lint_exit_code handling below is unaffected β€” you just get all four reports uploaded on a failing run.

Fix this β†’


if [ $app_lint_exit_code -ne 0 ] || [ $automotive_wear_lint_exit_code -ne 0 ]; then
if [ $app_lint_exit_code -ne 0 ] || [ $other_apps_lint_exit_code -ne 0 ]; then
lint_exit_code=1
else
lint_exit_code=0
fi

upload_sarif_to_github 'app/build/reports/lint-results-release.sarif' 'app'
upload_sarif_to_github 'automotive/build/reports/lint-results-release.sarif' 'automotive'
upload_sarif_to_github 'tv/build/reports/lint-results-release.sarif' 'tv'
upload_sarif_to_github 'wear/build/reports/lint-results-release.sarif' 'wear'

exit $lint_exit_code
10 changes: 8 additions & 2 deletions .buildkite/pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ steps:
artifact_paths:
- "**/build/instrumented-tests/**/*"

- group: "Assemble release APKs"
- group: "Assemble Mobile, Automotive, TV, and Wear release APKs"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: enumerating form factors in the group label means editing it for every new one (and it now says "Mobile" while the step below says "app"). Something like "Assemble release APKs (all form factors)" stays accurate on its own. Non-blocking either way.

steps:
- label: "Assemble app release APK"
command: ".buildkite/commands/assemble-release-apk.sh app"
Expand All @@ -81,6 +81,12 @@ steps:
artifact_paths:
- "**/build/outputs/apk/**/*"

- label: "Assemble TV release APK"
command: ".buildkite/commands/assemble-release-apk.sh tv"
plugins: [ $CI_TOOLKIT ]
artifact_paths:
- "**/build/outputs/apk/**/*"

- label: "Assemble wear release APK"
command: ".buildkite/commands/assemble-release-apk.sh wear"
plugins: [ $CI_TOOLKIT ]
Expand All @@ -90,7 +96,7 @@ steps:
##########
# Optional Prototype Builds
#
# Builds all modules, uploads app to FAD and Wear and Automotive to S3
# Builds all modules, uploads app to FAD and Wear, Automotive, and TV to S3
##########
- group: Prototype Builds
if: "build.pull_request.id != null || build.branch == 'main'"
Expand Down
34 changes: 24 additions & 10 deletions fastlane/Fastfile
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ RELEASE_NOTES_SOURCE_PATH = File.join(PROJECT_ROOT_FOLDER, 'CHANGELOG.md')
EXTRACTED_RELEASE_NOTES_PATH = File.join(ORIGINALS_METADATA_DIR_PATH, 'release_notes.txt')
PLAY_STORE_TRACK_AUTOMOTIVE_BETA = 'automotive:beta'
PLAY_STORE_TRACK_AUTOMOTIVE_PRODUCTION = 'automotive:production'
PLAY_STORE_TRACK_TV_BETA = 'tv:beta'
PLAY_STORE_TRACK_TV_PRODUCTION = 'tv:production'
Comment on lines +22 to +23

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please confirm these track identifiers against the actual Play Console before the next release build.

wear:* and automotive:* are known-good form-factor track names, but I couldn't verify tv:beta / tv:production from here (no network access in this environment). A wrong identifier here is not a soft failure: upload_to_play_store raises, and per the ordering issue above it would abort mid-release with app/automotive already uploaded as drafts.

Two things worth checking:

  1. The exact form-factor prefix Google uses for Android TV in the Publishing API.
  2. That the track actually exists in Play Console for au.com.shiftyjelly.pocketcasts β€” form-factor tracks have to be created there first; the API won't create them on upload.

A quick way to confirm both:

bundle exec fastlane run google_play_track_version_codes \
  package_name:au.com.shiftyjelly.pocketcasts track:tv:beta \
  json_key:google-upload-credentials.json

PLAY_STORE_TRACK_WEAR_BETA = 'wear:beta'
PLAY_STORE_TRACK_WEAR_PRODUCTION = 'wear:production'
PLAY_STORE_TRACK_BETA = 'beta'
Expand Down Expand Up @@ -66,8 +68,9 @@ ENV['SUPPLY_UPLOAD_MAX_RETRIES'] = '5'
GITHUB_REPO = 'automattic/pocket-casts-android'
APPS_APP = 'app'
APPS_AUTOMOTIVE = 'automotive'
APPS_TV = 'tv'
APPS_WEAR = 'wear'
APPS = [APPS_APP, APPS_AUTOMOTIVE, APPS_WEAR].freeze
APPS = [APPS_APP, APPS_AUTOMOTIVE, APPS_TV, APPS_WEAR].freeze

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider putting TV last in APPS rather than third.

build_and_upload_to_play_store iterates APPS with no per-app rescue (unlike update_rollouts, which tolerates missing variants). Every step inside the loop can hard-fail for a brand-new form factor:

  • upload_to_play_store(track: 'tv:beta') β†’ fails if the TV track doesn't exist yet in Play Console
  • download_universal_apk_from_google_play(version_code: <build_code + 150_000>) β†’ fails if Play hasn't produced a universal APK for that TV version code
  • Play's TV-specific listing/asset validation

With TV inserted at index 2, any of those aborts the lane before wear is built or uploaded, and create_gh_release never runs β€” so a TV-only problem regresses two already-shipping form factors and the whole GitHub release. Appending TV keeps the failure at the tail:

Suggested change
APPS = [APPS_APP, APPS_AUTOMOTIVE, APPS_TV, APPS_WEAR].freeze
APPS = [APPS_APP, APPS_AUTOMOTIVE, APPS_WEAR, APPS_TV].freeze

(Order is irrelevant for update_rollouts, so nothing else changes.)


UPLOAD_TO_PLAY_STORE_JSON_KEY = File.join(PROJECT_ROOT_FOLDER, 'google-upload-credentials.json')
UPLOAD_TO_PLAY_STORE_COMMON_OPTIONS = {
Expand Down Expand Up @@ -330,7 +333,8 @@ platform :android do
end
end

# Update the rollout of all 3 variants/form-factors (app, automotive, wear) of the latest builds of the given Google Play track to the given % value
# Update the rollout of all app variants/form factors for the latest builds of the
# given Google Play track to the given % value
#
# @param percent [Float] The rollout percentage, between 0 and 1
# @param track [String] The Google Play track for which to update the rollout of. Must be either `beta` or `production`.
Expand Down Expand Up @@ -369,7 +373,12 @@ platform :android do
not_found_variants.each do |message|
UI.important(message)
end
UI.user_error!('None of the 3 app variants were found in Google Play Console. We expected at least one') if not_found_variants.count == APPS.count
if not_found_variants.count == APPS.count
UI.user_error!(
"None of the #{APPS.count} app variants were found in Google Play Console. " \
'We expected at least one'
)
end
end

# Downloads the latest translations from GlotPress and creates a PR to integrate them into the current `release/*` branch
Expand Down Expand Up @@ -584,7 +593,7 @@ platform :android do
#
# @param version [String] The version to create
# @param build_code [String] The build code to create
# @param app [String] The Android app to build (i.e 'app', 'automotive', or 'wear')
# @param app [String] The Android app to build (i.e. 'app', 'automotive', 'tv', or 'wear')
lane :build_bundle do |app:, version: version_name_current, build_code: build_code_current|
aab_artifact_path = aab_artifact_path(app, version)
build_dir = 'artifacts/'
Expand All @@ -598,6 +607,7 @@ platform :android do
build_type: 'Release',
properties: {
'IS_AUTOMOTIVE_BUILD' => app == APPS_AUTOMOTIVE,
'IS_TV_BUILD' => app == APPS_TV,
'IS_WEAR_BUILD' => app == APPS_WEAR
}
)
Expand Down Expand Up @@ -635,7 +645,7 @@ platform :android do
)
end

# Compiles prototype builds and uploads to FAD (app) and S3 (wear/automotive)
# Compiles prototype builds and uploads to FAD (app) and S3 (wear/automotive/TV)
#
lane :build_and_upload_prototype_build do
firebase_account_key = ENV.fetch('FIREBASE_APP_DISTRIBUTION_ACCOUNT_KEY', nil)
Expand Down Expand Up @@ -684,12 +694,12 @@ platform :android do
)
end

# Build wear/automotive and upload to S3 (PRs only)
# Build wear/automotive/TV and upload to S3 (PRs only)
next unless pr_number

UI.user_error!("'BUILDKITE_ARTIFACTS_S3_BUCKET' must be defined as an environment variable.") unless ENV['BUILDKITE_ARTIFACTS_S3_BUCKET']

other_platforms = %w[wear automotive]
other_platforms = %w[wear automotive tv]

other_apks = []
other_platforms.each do |platform|
Expand Down Expand Up @@ -748,7 +758,7 @@ platform :android do

def get_app_display_name(apk_path:)
key = get_app_key(apk_path: apk_path).to_sym
{ app: 'πŸ“± Mobile', wear: '⌚ Wear', automotive: 'πŸš— Automotive' }.fetch(key, '❔ Unknown')
{ app: 'πŸ“± Mobile', wear: '⌚ Wear', automotive: 'πŸš— Automotive', tv: 'πŸ“Ί TV' }.fetch(key, '❔ Unknown')
end

# Mimics the subset of ActiveSupport's `String#parameterize` we rely on.
Expand Down Expand Up @@ -936,7 +946,7 @@ platform :android do
BUILD_CODE_FORMATTER.build_code(build_code: build_code_next)
end

# Returns the versionCode for a given app, adjusting for offset depending if it's the mobile, automotive or wear app
# Returns the versionCode for a given app, adjusting for offset depending on its form factor
#
# See also `dependencies.gradle.kts` and its `versionCodeDifferenceBetweenAppAnd*` constants where those offsets are defined
#
Expand All @@ -946,14 +956,16 @@ platform :android do
(version_code.to_i + 50_000).to_s
when APPS_WEAR
(version_code.to_i + 100_000).to_s
when APPS_TV
(version_code.to_i + 150_000).to_s
else
version_code
end
end

# Returns the Play Store track for a given app, for Open Testing or Production
#
# @param app [String] The type of app. One of `APPS_APP`, `APPS_AUTOMOTIVE`, `APPS_WEAR`
# @param app [String] The type of app. One of `APPS_APP`, `APPS_AUTOMOTIVE`, `APPS_TV`, `APPS_WEAR`
# @param is_beta [Boolean] If we want the track for Open Testing. Otherwise, returns the track for Production
# @return [String] The Play Store track to use in the `upload_to_play_store(track: …)` action call
#
Expand All @@ -963,6 +975,8 @@ platform :android do
is_beta ? PLAY_STORE_TRACK_AUTOMOTIVE_BETA : PLAY_STORE_TRACK_AUTOMOTIVE_PRODUCTION
when APPS_WEAR
is_beta ? PLAY_STORE_TRACK_WEAR_BETA : PLAY_STORE_TRACK_WEAR_PRODUCTION
when APPS_TV
is_beta ? PLAY_STORE_TRACK_TV_BETA : PLAY_STORE_TRACK_TV_PRODUCTION
else
is_beta ? PLAY_STORE_TRACK_BETA : PLAY_STORE_TRACK_PRODUCTION
end
Expand Down