Skip to content

Commit c94f176

Browse files
AnkaAnka
authored andcommitted
Merge branch 'release/5.219.0'
2 parents 5f11d81 + e07466d commit c94f176

File tree

318 files changed

+9675
-2416
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

318 files changed

+9675
-2416
lines changed

.github/workflows/release_create_tag.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,19 @@ jobs:
2525
uses: actions/checkout@v4
2626
with:
2727
submodules: recursive
28+
token: ${{ secrets.GT_DAXMOBILE }}
2829

2930
- name: Set up ruby env
3031
uses: ruby/setup-ruby@v1
3132
with:
3233
ruby-version: 2.7.2
3334
bundler-cache: true
3435

36+
- name: Set Git permissions
37+
uses: oleksiyrudenko/gha-git-credentials@v2-latest
38+
with:
39+
token: '${{ secrets.GT_DAXMOBILE }}'
40+
3541
- name: Use fastlane lane to create and push tagged release
3642
id: create_git_tag
3743
run: |
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
name: Release - Nightly Release to Internal and Firebase
2+
3+
on:
4+
schedule:
5+
- cron: '0 2 * * *' # run at 3 AM UTC
6+
workflow_dispatch:
7+
8+
env:
9+
ASANA_PAT: ${{ secrets.GH_ASANA_SECRET }}
10+
GOOGLE_APPLICATION_CREDENTIALS: '#{ENV["HOME"]}/jenkins_static/com.duckduckgo.mobile.android/ddg-upload-firebase.json'
11+
12+
jobs:
13+
create-tag:
14+
name: Generate and upload nightly bundle to Play Store Internal track
15+
runs-on: ubuntu-latest
16+
17+
steps:
18+
- name: Checkout repository
19+
uses: actions/checkout@v4
20+
with:
21+
submodules: recursive
22+
token: ${{ secrets.GT_DAXMOBILE }}
23+
24+
- name: Set Git permissions
25+
uses: oleksiyrudenko/gha-git-credentials@v2-latest
26+
with:
27+
token: '${{ secrets.GT_DAXMOBILE }}'
28+
29+
- name: Set up JDK 17
30+
uses: actions/setup-java@v4
31+
with:
32+
java-version: '17'
33+
distribution: 'adopt'
34+
35+
- name: Set up ruby env
36+
uses: ruby/setup-ruby@v1
37+
with:
38+
ruby-version: 2.7.2
39+
bundler-cache: true
40+
41+
- name: Get latest tag
42+
id: get_latest_tag
43+
run: |
44+
git fetch --tags
45+
output=$(git describe --tags `git rev-list --tags --max-count=1`)
46+
echo "Latest tag: $output"
47+
echo "latest_tag=$output" >> $GITHUB_OUTPUT
48+
49+
- name: Decode upload keys
50+
uses: davidSchuppa/base64Secret-toFile-action@199e78f212c854d2284fada7f3cd3aba3e37d208
51+
with:
52+
secret: ${{ secrets.UPLOAD_RELEASE_PROPERTIES }}
53+
fileName: ddg_android_build_upload.properties
54+
destination-path: $HOME/jenkins_static/com.duckduckgo.mobile.android/
55+
56+
- name: Decode key file
57+
uses: davidSchuppa/base64Secret-toFile-action@199e78f212c854d2284fada7f3cd3aba3e37d208
58+
with:
59+
secret: ${{ secrets.UPLOAD_RELEASE_KEY }}
60+
fileName: ddg-upload-keystore.jks
61+
destination-path: $HOME/jenkins_static/com.duckduckgo.mobile.android/
62+
63+
- name: Decode Play Store credentials file
64+
uses: davidSchuppa/base64Secret-toFile-action@199e78f212c854d2284fada7f3cd3aba3e37d208
65+
with:
66+
secret: ${{ secrets.UPLOAD_PLAY_CREDENTIALS }}
67+
fileName: api.json
68+
destination-path: $HOME/jenkins_static/com.duckduckgo.mobile.android/
69+
70+
- name: Decode Firebase credentials file
71+
uses: davidSchuppa/base64Secret-toFile-action@199e78f212c854d2284fada7f3cd3aba3e37d208
72+
with:
73+
secret: ${{ secrets.UPLOAD_FIREBASE_CREDENTIALS }}
74+
fileName: ddg-upload-firebase.json
75+
destination-path: $HOME/jenkins_static/com.duckduckgo.mobile.android/
76+
77+
- name: Clean project
78+
run: |
79+
gradle clean
80+
81+
- name: Assemble the bundle
82+
run: gradle bundleInternalRelease -PversionNameSuffix=-nightly -PuseUploadSigning -PlatestTag=${{ steps.get_latest_tag.outputs.latest_tag }}
83+
84+
- name: Generate nightly version name
85+
id: generate_version_name
86+
run: |
87+
output=$(gradle getBuildVersionName -PversionNameSuffix=-nightly -PlatestTag=${{ steps.get_latest_tag.outputs.latest_tag }} --quiet | tail -n 1)
88+
echo "version=$output" >> $GITHUB_OUTPUT
89+
90+
- name: Capture App Bundle Path
91+
id: capture_output
92+
run: |
93+
output=$(find app/build/outputs/bundle/internalRelease -name "*.aab")
94+
echo "bundle_path=$output" >> $GITHUB_OUTPUT
95+
96+
- name: Upload bundle to Play Store Internal track
97+
id: create_app_bundle
98+
run: |
99+
bundle exec fastlane deploy_dogfood aab_path:${{ steps.capture_output.outputs.bundle_path }}
100+
101+
- name: Tag Nightly release
102+
id: tag_nightly_release
103+
run: |
104+
git tag -a ${{ steps.generate_version_name.outputs.version }} -m "Create tag ${{ steps.generate_version_name.outputs.version }} for nightly release."
105+
git push origin ${{ steps.generate_version_name.outputs.version }}
106+
107+
- name: Upload APK as artifact
108+
uses: actions/upload-artifact@v4
109+
with:
110+
name: duckduckgo-${{ steps.generate_version_name.outputs.version }}.apk
111+
path: duckduckgo.apk
112+
113+
- name: Create Asana task when workflow failed
114+
if: ${{ failure() }}
115+
uses: duckduckgo/[email protected]
116+
with:
117+
asana-pat: ${{ secrets.GH_ASANA_SECRET }}
118+
asana-project: ${{ vars.GH_ANDROID_APP_PROJECT_ID }}
119+
asana-section: ${{ vars.GH_ANDROID_APP_INCOMING_SECTION_ID }}
120+
asana-task-name: GH Workflow Failure - Nightly Release
121+
asana-task-description: The Nightly Release Task workflow has failed. See https://github.com/duckduckgo/Android/actions/runs/${{ github.run_id }}
122+
action: 'create-asana-task'

.github/workflows/release_production.yml

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,23 @@ concurrency:
1616
cancel-in-progress: true
1717

1818
jobs:
19-
create_release_task:
20-
uses: ./.github/workflows/release_create_task.yml
21-
with:
22-
app-version: ${{ github.event.inputs.app-version }}
19+
create_release_task:
20+
uses: ./.github/workflows/release_create_task.yml
21+
with:
22+
app-version: ${{ github.event.inputs.app-version }}
2323

24-
create_release_tag:
25-
needs: create_release_task
26-
uses: ./.github/workflows/release_create_tag.yml
27-
with:
28-
app-version: ${{ github.event.inputs.app-version }}
24+
create_release_tag:
25+
needs: create_release_task
26+
uses: ./.github/workflows/release_create_tag.yml
27+
with:
28+
app-version: ${{ github.event.inputs.app-version }}
2929

30-
launch_release_tests:
31-
needs: create_release_tag
32-
uses: ./.github/workflows/release_tests.yml
33-
with:
34-
app-version: ${{ github.event.inputs.app-version }}
30+
launch_release_tests:
31+
needs: create_release_tag
32+
uses: ./.github/workflows/release_tests.yml
33+
with:
34+
app-version: ${{ github.event.inputs.app-version }}
3535

36-
report_workflow_failed:
37-
if: ${{ failure() }}
38-
uses: ./.github/workflows/release_report_error.yml
36+
report_workflow_failed:
37+
if: ${{ failure() }}
38+
uses: ./.github/workflows/release_report_error.yml
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
name: Release - Update Release Notes in Play Store and Github
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
app-version:
7+
description: 'App Version for Release'
8+
required: true
9+
default: 'PLACEHOLDER'
10+
release-notes:
11+
description: 'Release notes for the version'
12+
required: true
13+
default: 'Bug fixes and other improvements'
14+
15+
env:
16+
ASANA_PAT: ${{ secrets.GH_ASANA_SECRET }}
17+
GH_TOKEN: ${{ secrets.GT_DAXMOBILE }}
18+
19+
jobs:
20+
update-release-notes:
21+
name: Update release notes in Play Store and Github
22+
runs-on: ubuntu-latest
23+
24+
steps:
25+
- name: Checkout repository
26+
uses: actions/checkout@v4
27+
with:
28+
submodules: recursive
29+
token: ${{ secrets.GT_DAXMOBILE }}
30+
31+
- name: Set up ruby env
32+
uses: ruby/setup-ruby@v1
33+
with:
34+
ruby-version: 2.7.2
35+
bundler-cache: true
36+
37+
- name: Decode Play Store credentials file
38+
uses: davidSchuppa/base64Secret-toFile-action@199e78f212c854d2284fada7f3cd3aba3e37d208
39+
with:
40+
secret: ${{ secrets.UPLOAD_PLAY_CREDENTIALS }}
41+
fileName: api.json
42+
destination-path: $HOME/jenkins_static/com.duckduckgo.mobile.android/
43+
44+
- name: Update release notes in Play Store
45+
id: update_play_store_release_notes
46+
run: |
47+
bundle exec fastlane update_release_notes_playstore release_number:${{ github.event.inputs.app-version }} release_notes:"${{ github.event.inputs.release-notes }}"
48+
49+
- name: Update release notes in Github
50+
id: update_gh_release_notes
51+
run: |
52+
bundle exec fastlane update_release_notes_github release_number:${{ github.event.inputs.app-version }} release_notes:"${{ github.event.inputs.release-notes }}"
53+
54+
- name: Create Asana task when workflow failed
55+
if: ${{ failure() }}
56+
id: create-failure-task
57+
uses: duckduckgo/[email protected]
58+
with:
59+
asana-pat: ${{ secrets.GH_ASANA_SECRET }}
60+
asana-project: ${{ vars.GH_ANDROID_APP_PROJECT_ID }}
61+
asana-section: ${{ vars.GH_ANDROID_APP_INCOMING_SECTION_ID }}
62+
asana-task-name: GH Workflow Failure - Update Release Notes
63+
asana-task-description: Update Release Notes in Play Store and Github has failed. See https://github.com/duckduckgo/Android/actions/runs/${{ github.run_id }}
64+
action: 'create-asana-task'

app-tracking-protection/app-tracking-api/src/main/java/com/duckduckgo/mobile/android/app/tracking/AppTrackingProtection.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,12 @@ interface AppTrackingProtection {
4747
* This method will stop the App Tracking Protection feature
4848
*/
4949
fun stop()
50+
51+
/**
52+
* This is a suspend function because the operation can take time.
53+
* You DO NOT need to set any dispatcher to call this suspend function
54+
*
55+
* @return a list of app packages that is excluded from App Tracking Protection
56+
*/
57+
suspend fun getExcludedApps(): List<String>
5058
}

app-tracking-protection/vpn-impl/src/main/java/com/duckduckgo/mobile/android/app/tracking/RealAppTrackingProtection.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import com.duckduckgo.common.utils.DispatcherProvider
2121
import com.duckduckgo.di.scopes.AppScope
2222
import com.duckduckgo.mobile.android.vpn.AppTpVpnFeature
2323
import com.duckduckgo.mobile.android.vpn.VpnFeaturesRegistry
24+
import com.duckduckgo.mobile.android.vpn.apps.TrackingProtectionAppsRepository
2425
import com.duckduckgo.mobile.android.vpn.ui.onboarding.VpnStore
2526
import com.squareup.anvil.annotations.ContributesBinding
2627
import dagger.SingleInstanceIn
@@ -36,6 +37,7 @@ class RealAppTrackingProtection @Inject constructor(
3637
private val vpnFeaturesRegistry: VpnFeaturesRegistry,
3738
@AppCoroutineScope private val coroutineScope: CoroutineScope,
3839
private val dispatcherProvider: DispatcherProvider,
40+
private val trackingProtectionAppsRepository: TrackingProtectionAppsRepository,
3941
) : AppTrackingProtection {
4042
override suspend fun isOnboarded(): Boolean = withContext(dispatcherProvider.io()) {
4143
return@withContext vpnStore.didShowOnboarding()
@@ -60,4 +62,8 @@ class RealAppTrackingProtection @Inject constructor(
6062
vpnFeaturesRegistry.unregisterFeature(AppTpVpnFeature.APPTP_VPN)
6163
}
6264
}
65+
66+
override suspend fun getExcludedApps(): List<String> = withContext(dispatcherProvider.io()) {
67+
trackingProtectionAppsRepository.getExclusionAppsList()
68+
}
6369
}

app-tracking-protection/vpn-impl/src/main/java/com/duckduckgo/mobile/android/vpn/ui/alwayson/AlwaysOnAlertDialogFragment.kt

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import androidx.core.text.HtmlCompat
2525
import com.duckduckgo.anvil.annotations.InjectWith
2626
import com.duckduckgo.appbuildconfig.api.AppBuildConfig
2727
import com.duckduckgo.common.ui.store.AppTheme
28+
import com.duckduckgo.common.utils.extensions.getSerializable
2829
import com.duckduckgo.di.scopes.FragmentScope
2930
import com.duckduckgo.mobile.android.vpn.R
3031
import com.duckduckgo.mobile.android.vpn.databinding.ContentVpnAlwaysOnAlertBinding
@@ -41,7 +42,7 @@ private enum class FragmentType {
4142
}
4243

4344
@InjectWith(FragmentScope::class)
44-
class AlwaysOnAlertDialogFragment private constructor() : BottomSheetDialogFragment() {
45+
class AlwaysOnAlertDialogFragment : BottomSheetDialogFragment() {
4546

4647
@Inject lateinit var appBuildConfig: AppBuildConfig
4748

@@ -56,8 +57,13 @@ class AlwaysOnAlertDialogFragment private constructor() : BottomSheetDialogFragm
5657
super.onAttach(context)
5758
}
5859

59-
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
60+
override fun onCreateView(
61+
inflater: LayoutInflater,
62+
container: ViewGroup?,
63+
savedInstanceState: Bundle?,
64+
): View {
6065
return ContentVpnAlwaysOnAlertBinding.inflate(inflater, container, false).apply {
66+
fragmentType = requireArguments().getSerializable<FragmentType>(ARGUMENT_FRAGMENT_TYPE) ?: FragmentType.ALWAYS_ON
6167
configureViews(this)
6268
}.root
6369
}
@@ -143,16 +149,22 @@ class AlwaysOnAlertDialogFragment private constructor() : BottomSheetDialogFragm
143149
}
144150

145151
companion object {
152+
private const val ARGUMENT_FRAGMENT_TYPE = "fragmentType"
146153
fun newAlwaysOnDialog(listener: Listener): AlwaysOnAlertDialogFragment {
147154
return AlwaysOnAlertDialogFragment().apply {
148155
this.listener = listener
149-
this.fragmentType = FragmentType.ALWAYS_ON
156+
arguments = Bundle().also {
157+
it.putSerializable(ARGUMENT_FRAGMENT_TYPE, FragmentType.ALWAYS_ON)
158+
}
150159
}
151160
}
161+
152162
fun newAlwaysOnLockdownDialog(listener: Listener): AlwaysOnAlertDialogFragment {
153163
return AlwaysOnAlertDialogFragment().apply {
154164
this.listener = listener
155-
this.fragmentType = FragmentType.ALWAYS_ON_LOCKDOWN
165+
arguments = Bundle().also {
166+
it.putSerializable(ARGUMENT_FRAGMENT_TYPE, FragmentType.ALWAYS_ON_LOCKDOWN)
167+
}
156168
}
157169
}
158170
}

app-tracking-protection/vpn-impl/src/main/java/com/duckduckgo/mobile/android/vpn/ui/tracker_activity/DeviceShieldTrackerActivity.kt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ import com.duckduckgo.common.ui.notifyme.NotifyMeView
4040
import com.duckduckgo.common.ui.view.DaxDialogListener
4141
import com.duckduckgo.common.ui.view.DaxSwitch
4242
import com.duckduckgo.common.ui.view.TypewriterDaxDialog
43+
import com.duckduckgo.common.ui.view.button.ButtonType.DESTRUCTIVE
44+
import com.duckduckgo.common.ui.view.button.ButtonType.GHOST_ALT
4345
import com.duckduckgo.common.ui.view.dialog.StackedAlertDialogBuilder
4446
import com.duckduckgo.common.ui.view.dialog.TextAlertDialogBuilder
4547
import com.duckduckgo.common.ui.view.gone
@@ -356,9 +358,8 @@ class DeviceShieldTrackerActivity :
356358
TextAlertDialogBuilder(this)
357359
.setTitle(R.string.atp_RemoveFeatureDialogTitle)
358360
.setMessage(R.string.atp_RemoveFeatureDialogMessage)
359-
.setDestructiveButtons(true)
360-
.setPositiveButton(R.string.atp_RemoveFeatureDialogRemove)
361-
.setNegativeButton(R.string.atp_RemoveFeatureDialogCancel)
361+
.setPositiveButton(R.string.atp_RemoveFeatureDialogRemove, DESTRUCTIVE)
362+
.setNegativeButton(R.string.atp_RemoveFeatureDialogCancel, GHOST_ALT)
362363
.addEventListener(
363364
object : TextAlertDialogBuilder.EventListener() {
364365
override fun onPositiveButtonClicked() {

app/build.gradle

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,9 @@ dependencies {
384384

385385
implementation project(':breakage-reporting-impl')
386386

387+
implementation project(":auth-jwt-api")
388+
implementation project(":auth-jwt-impl")
389+
387390
// Deprecated. TODO: Stop using this artifact.
388391
implementation "androidx.legacy:legacy-support-v4:_"
389392
debugImplementation Square.leakCanary.android

0 commit comments

Comments
 (0)