Skip to content

Commit

Permalink
Merge branch 'develop' into remove-gradle
Browse files Browse the repository at this point in the history
  • Loading branch information
BenHenning authored Feb 20, 2025
2 parents 6f064dc + 6e349bc commit f3b0a0e
Show file tree
Hide file tree
Showing 136 changed files with 2,569 additions and 1,142 deletions.
3 changes: 3 additions & 0 deletions .bazelrc
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,6 @@ build:ignore_build_warnings --//tools/kotlin:warn_mode=warning

# Show all test output by default (for better debugging).
test --test_output=all

# Always start the app by default when using mobile-install.
mobile-install --start_app
3 changes: 0 additions & 3 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -257,9 +257,6 @@ WORKSPACE @oppia/android-app-infrastructure-reviewers
# Proguard configurations for Bazel builds.
/config/proguard/ @oppia/android-dev-workflow-reviewers

# Configuration for KitKat-specific curated builds.
/config/kitkat_main_dex_class_list.txt @oppia/android-dev-workflow-reviewers

# Specific manifest files specifically required for Bazel builds.
/app/src/main/AppAndroidManifest.xml @oppia/android-dev-workflow-reviewers
/app/src/main/DatabindingAdaptersManifest.xml @oppia/android-dev-workflow-reviewers
Expand Down
349 changes: 8 additions & 341 deletions .github/workflows/build_tests.yml

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions .github/workflows/static_checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,13 @@ jobs:
run: |
bazel run //scripts:xml_syntax_check -- $(pwd)
- name: TextView Style Validation Check
# The expression if: ${{ !cancelled() }} runs a job or step regardless of its success or failure while responding to cancellations,
# serving as a cancellation-compliant alternative to if: ${{ always() }} in concurrent workflows.
if: ${{ !cancelled() }}
run: |
bazel run //scripts:check_textview_styles -- $(pwd)
- name: Testfile Presence Check
# The expression if: ${{ !cancelled() }} runs a job or step regardless of its success or failure while responding to cancellations,
# serving as a cancellation-compliant alternative to if: ${{ always() }} in concurrent workflows.
Expand Down
79 changes: 3 additions & 76 deletions .github/workflows/unit_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,6 @@ jobs:
max-parallel: 10
matrix: ${{ fromJson(needs.bazel_compute_affected_targets.outputs.matrix) }}
env:
ENABLE_CACHING: false
CACHE_DIRECTORY: ~/.bazel_cache
steps:
- uses: actions/checkout@v2
Expand Down Expand Up @@ -206,57 +205,7 @@ jobs:
echo "build --disk_cache=$EXPANDED_BAZEL_CACHE_PATH" >> $HOME/.bazelrc
shell: bash

# See explanation in bazel_build_app for how this is installed.
- name: Install git-secret (non-fork only)
if: ${{ env.ENABLE_CACHING == 'true' && ((github.ref == 'refs/heads/develop' && github.event_name == 'push') || (github.event.pull_request.head.repo.full_name == 'oppia/oppia-android')) }}
shell: bash
run: |
cd $HOME
mkdir -p $HOME/gitsecret
git clone https://github.com/sobolevn/git-secret.git git-secret
cd git-secret && make build
PREFIX="$HOME/gitsecret" make install
echo "$HOME/gitsecret" >> $GITHUB_PATH
echo "$HOME/gitsecret/bin" >> $GITHUB_PATH
- name: Decrypt secrets (non-fork only)
if: ${{ env.ENABLE_CACHING == 'true' && ((github.ref == 'refs/heads/develop' && github.event_name == 'push') || (github.event.pull_request.head.repo.full_name == 'oppia/oppia-android')) }}
env:
GIT_SECRET_GPG_PRIVATE_KEY: ${{ secrets.GIT_SECRET_GPG_PRIVATE_KEY }}
run: |
cd $HOME
# NOTE TO DEVELOPERS: Make sure to never print this key directly to stdout!
echo $GIT_SECRET_GPG_PRIVATE_KEY | base64 --decode > ./git_secret_private_key.gpg
gpg --import ./git_secret_private_key.gpg
cd $GITHUB_WORKSPACE
git secret reveal
# See https://www.cyberciti.biz/faq/unix-for-loop-1-to-10/ for for-loop reference.
- name: Build Oppia Tests (with caching, non-fork only)
if: ${{ env.ENABLE_CACHING == 'true' && ((github.ref == 'refs/heads/develop' && github.event_name == 'push') || (github.event.pull_request.head.repo.full_name == 'oppia/oppia-android')) }}
env:
BAZEL_REMOTE_CACHE_URL: ${{ secrets.BAZEL_REMOTE_CACHE_URL }}
BAZEL_TEST_TARGETS: ${{ env.BAZEL_TEST_TARGETS }}
run: |
# Attempt to build 5 times in case there are flaky builds.
# TODO(#3759): Remove this once there are no longer app test build failures.
i=0
# Disable exit-on-first-failure.
set +e
while [ $i -ne 5 ]; do
i=$(( $i+1 ))
echo "Attempt $i/5 to build test targets"
bazel build --keep_going --remote_http_cache=$BAZEL_REMOTE_CACHE_URL --google_credentials=./config/oppia-dev-workflow-remote-cache-credentials.json -- $BAZEL_TEST_TARGETS
done
# Capture the error code of the final command run (which should be a success if there isn't a real build failure).
last_error_code=$?
# Reenable exit-on-first-failure.
set -e
# Exit only if the most recent exit was a failure (by using a subshell).
(exit $last_error_code)
- name: Build Oppia Tests (without caching, or on a fork)
if: ${{ env.ENABLE_CACHING == 'false' || ((github.ref != 'refs/heads/develop' || github.event_name != 'push') && (github.event.pull_request.head.repo.full_name != 'oppia/oppia-android')) }}
- name: Build Oppia Tests
env:
BAZEL_TEST_TARGETS: ${{ env.BAZEL_TEST_TARGETS }}
run: |
Expand All @@ -276,30 +225,8 @@ jobs:
set -e
# Exit only if the most recent exit was a failure (by using a subshell).
(exit $last_error_code)
- name: Run Oppia Tests (with caching, non-fork only)
if: ${{ env.ENABLE_CACHING == 'true' && ((github.ref == 'refs/heads/develop' && github.event_name == 'push') || (github.event.pull_request.head.repo.full_name == 'oppia/oppia-android')) }}
env:
BAZEL_REMOTE_CACHE_URL: ${{ secrets.BAZEL_REMOTE_CACHE_URL }}
BAZEL_TEST_TARGETS: ${{ env.BAZEL_TEST_TARGETS }}
run: |
# Attempt to build 5 times in case there are flaky builds.
# TODO(#3970): Remove this once there are no longer app test build failures.
i=0
# Disable exit-on-first-failure.
set +e
while [ $i -ne 5 ]; do
i=$(( $i+1 ))
echo "Attempt $i/5 to run test targets"
bazel test --keep_going --remote_http_cache=$BAZEL_REMOTE_CACHE_URL --google_credentials=./config/oppia-dev-workflow-remote-cache-credentials.json -- $BAZEL_TEST_TARGETS
done
# Capture the error code of the final command run (which should be a success if there isn't a real build failure).
last_error_code=$?
# Reenable exit-on-first-failure.
set -e
# Exit only if the most recent exit was a failure (by using a subshell).
(exit $last_error_code)
- name: Run Oppia Tests (without caching, or on a fork)
if: ${{ env.ENABLE_CACHING == 'false' || ((github.ref != 'refs/heads/develop' || github.event_name != 'push') && (github.event.pull_request.head.repo.full_name != 'oppia/oppia-android')) }}
- name: Run Oppia Tests
env:
BAZEL_TEST_TARGETS: ${{ env.BAZEL_TEST_TARGETS }}
run: |
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/wiki.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
name: Deploy to Wiki

on:
workflow_dispatch:
pull_request:
paths:
- 'wiki/**'
Expand Down Expand Up @@ -36,6 +37,8 @@ jobs:
bazel run //scripts:wiki_table_of_contents_check -- ${GITHUB_WORKSPACE}
wiki-deploy:
permissions:
contents: write
runs-on: ${{ matrix.os }}
strategy:
matrix:
Expand Down
70 changes: 4 additions & 66 deletions BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
load("@dagger//:workspace_defs.bzl", "dagger_rules")
load("//:build_flavors.bzl", "AVAILABLE_FLAVORS", "define_oppia_aab_binary_flavor", "transform_android_manifest")
load("//:version.bzl", "MAJOR_VERSION", "MINOR_VERSION", "OPPIA_DEV_KITKAT_VERSION_CODE", "OPPIA_DEV_VERSION_CODE")

# This is exported here since config/ isn't a Bazel package.
exports_files(["config/kitkat_main_dex_class_list.txt"])
load("//:build_flavors.bzl", "AVAILABLE_FLAVORS", "define_oppia_aab_binary_flavor")

# TODO(#1607): Ensure app module libraries don't require directly depending on AndroidManifest.xml.
exports_files(["AndroidManifest.xml"])
Expand Down Expand Up @@ -73,67 +69,9 @@ package_group(
],
)

[
transform_android_manifest(
name = "oppia_apk_%s_transformed_manifest" % apk_flavor_metadata["flavor"],
application_relative_qualified_class = ".app.application.dev.DeveloperOppiaApplication",
build_flavor = apk_flavor_metadata["flavor"],
input_file = "AndroidManifest.xml",
major_version = MAJOR_VERSION,
minor_version = MINOR_VERSION,
output_file = "AndroidManifest_transformed_%s.xml" % apk_flavor_metadata["flavor"],
version_code = apk_flavor_metadata["version_code"],
)
for apk_flavor_metadata in [
{
"flavor": "oppia",
"version_code": OPPIA_DEV_VERSION_CODE,
},
{
"flavor": "oppia_kitkat",
"version_code": OPPIA_DEV_KITKAT_VERSION_CODE,
},
]
]

[
android_binary(
name = apk_flavor_metadata["flavor"],
custom_package = "org.oppia.android",
enable_data_binding = True,
main_dex_list = apk_flavor_metadata.get("main_dex_list"),
manifest = "oppia_apk_%s_transformed_manifest" % apk_flavor_metadata["flavor"],
manifest_values = {
"applicationId": "org.oppia.android",
"minSdkVersion": "%d" % apk_flavor_metadata["min_sdk_version"],
"targetSdkVersion": "%d" % apk_flavor_metadata["target_sdk_version"],
},
multidex = apk_flavor_metadata["multidex"],
deps = [
"//app/src/main/java/org/oppia/android/app/application/dev:developer_application",
"//config/src/java/org/oppia/android/config:all_languages_config",
],
)
for apk_flavor_metadata in [
{
"flavor": "oppia",
"min_sdk_version": 21,
"multidex": "native",
"target_sdk_version": 34,
},
{
"flavor": "oppia_kitkat",
"main_dex_list": "//:config/kitkat_main_dex_class_list.txt",
"min_sdk_version": 21,
"multidex": "manual_main_dex",
"target_sdk_version": 34,
},
]
]

# Define all binary flavors that can be built. Note that these are AABs, not APKs, and can be
# be installed on a local device or emulator using a 'bazel run' command like so:
# bazel run //:install_oppia_dev
# Define all binary flavors that can be built. Note that these are AABs and thus cannot be installed
# directly. However, their binaries can be installed using mobile-install like so:
# bazel mobile-install //:oppia_dev_binary
[
define_oppia_aab_binary_flavor(flavor = flavor)
for flavor in AVAILABLE_FLAVORS
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/AppAndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.oppia.android.app.ui">
<uses-sdk android:minSdkVersion="19"
<uses-sdk android:minSdkVersion="21"
android:targetSdkVersion="34" />
</manifest>
2 changes: 1 addition & 1 deletion app/src/main/DatabindingAdaptersManifest.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.oppia.android.databinding.adapters">
<uses-sdk android:minSdkVersion="19"
<uses-sdk android:minSdkVersion="21"
android:targetSdkVersion="34" />
</manifest>
2 changes: 1 addition & 1 deletion app/src/main/DatabindingResourcesManifest.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.oppia.android.app.databinding">
<uses-sdk android:minSdkVersion="19"
<uses-sdk android:minSdkVersion="21"
android:targetSdkVersion="34" />
</manifest>
2 changes: 1 addition & 1 deletion app/src/main/RecyclerviewAdaptersManifest.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.oppia.android.app.recyclerview.adapters">
<uses-sdk android:minSdkVersion="19"
<uses-sdk android:minSdkVersion="21"
android:targetSdkVersion="34" />
</manifest>
2 changes: 1 addition & 1 deletion app/src/main/ViewModelManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
<!-- TODO(#1632): Remove manifest -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.oppia.android.app.vm">
<uses-sdk android:minSdkVersion="19"
<uses-sdk android:minSdkVersion="21"
android:targetSdkVersion="34" />
</manifest>
2 changes: 1 addition & 1 deletion app/src/main/ViewModelsManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
<!-- TODO(#1632): Remove manifest -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.oppia.android.app.view.models">
<uses-sdk android:minSdkVersion="19"
<uses-sdk android:minSdkVersion="21"
android:targetSdkVersion="34" />
</manifest>
2 changes: 1 addition & 1 deletion app/src/main/ViewsManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
<!-- TODO(#1632): Remove manifest -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.oppia.android.app.views">
<uses-sdk android:minSdkVersion="19"
<uses-sdk android:minSdkVersion="21"
android:targetSdkVersion="34" />
</manifest>
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import org.oppia.android.app.translation.AppLanguageResourceHandler
import org.oppia.android.util.extensions.getProto
import org.oppia.android.util.logging.CurrentAppScreenNameIntentDecorator.decorateWithScreenName
import org.oppia.android.util.profile.CurrentUserProfileIdIntentDecorator.decorateWithUserProfileId
import org.oppia.android.util.profile.CurrentUserProfileIdIntentDecorator.extractCurrentUserProfileId
import javax.inject.Inject

/** Argument key used to identify [ProfileListFragment] in the backstack. */
Expand Down Expand Up @@ -75,7 +76,7 @@ class AdministratorControlsActivity :
// TODO(#661): Change the default fragment in the right hand side to be EditAccount fragment in the case of multipane controls.
PROFILE_LIST_FRAGMENT
}
val selectedProfileId = args?.selectedProfileId ?: -1
val selectedProfileId = intent?.extractCurrentUserProfileId() ?: ProfileId.getDefaultInstance()

administratorControlsActivityPresenter.handleOnCreate(
extraControlsTitle,
Expand Down Expand Up @@ -107,7 +108,7 @@ class AdministratorControlsActivity :
startActivity(ProfileAndDeviceIdActivity.createIntent(this))
}

override fun loadProfileEdit(profileId: Int, profileName: String) {
override fun loadProfileEdit(profileId: ProfileId, profileName: String) {
lastLoadedFragment = PROFILE_EDIT_FRAGMENT
administratorControlsActivityPresenter.loadProfileEdit(profileId, profileName)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@ import org.oppia.android.app.administratorcontrols.appversion.AppVersionFragment
import org.oppia.android.app.administratorcontrols.learneranalytics.ProfileAndDeviceIdFragment
import org.oppia.android.app.drawer.NavigationDrawerFragment
import org.oppia.android.app.model.AdministratorControlActivityStateBundle
import org.oppia.android.app.model.ProfileId
import org.oppia.android.app.settings.profile.LoadProfileEditDeletionDialogListener
import org.oppia.android.app.settings.profile.ProfileEditFragment
import org.oppia.android.app.settings.profile.ProfileListFragment
import org.oppia.android.app.translation.AppLanguageResourceHandler
import org.oppia.android.databinding.AdministratorControlsActivityBinding
import org.oppia.android.util.extensions.putProto
import org.oppia.android.util.profile.CurrentUserProfileIdIntentDecorator.decorateWithUserProfileId
import javax.inject.Inject

/** The presenter for [AdministratorControlsActivity]. */
Expand All @@ -29,15 +31,15 @@ class AdministratorControlsActivityPresenter @Inject constructor(
private lateinit var binding: AdministratorControlsActivityBinding

private lateinit var lastLoadedFragment: String
private var selectedProfileId: Int = -1
private var selectedProfileId: ProfileId = ProfileId.getDefaultInstance()
private lateinit var extraControlsTitle: String
private var isProfileDeletionDialogVisible: Boolean = false

/** Initializes the [AdministratorControlsActivity] and sets the navigation drawer. */
fun handleOnCreate(
extraControlsTitle: String?,
lastLoadedFragment: String,
selectedProfileId: Int,
selectedProfileId: ProfileId,
isProfileDeletionDialogVisible: Boolean
) {
binding = DataBindingUtil.setContentView(
Expand Down Expand Up @@ -68,7 +70,7 @@ class AdministratorControlsActivityPresenter @Inject constructor(
PROFILE_EDIT_FRAGMENT -> selectedProfileId.let { profileId ->
if (extraControlsTitle != null) {
activity.loadProfileEdit(profileId = profileId, profileName = extraControlsTitle)
if (isProfileDeletionDialogVisible && profileId != 0) {
if (isProfileDeletionDialogVisible && profileId.internalId != 0) {
val fragment = activity.supportFragmentManager.findFragmentById(
R.id.administrator_controls_fragment_multipane_placeholder
)
Expand Down Expand Up @@ -142,13 +144,13 @@ class AdministratorControlsActivityPresenter @Inject constructor(
}

/** Loads the [ProfileEditFragment] when the user clicks on a profile in tablet multipane mode. */
fun loadProfileEdit(profileId: Int, profileName: String) {
fun loadProfileEdit(profileId: ProfileId, profileName: String) {
lastLoadedFragment = PROFILE_EDIT_FRAGMENT
selectedProfileId = profileId
extraControlsTitle = profileName
setExtraControlsTitle(extraControlsTitle)
setMultipaneBackButtonVisibility(View.VISIBLE)
val fragment = ProfileEditFragment.newInstance(profileId, isMultipane)
val fragment = ProfileEditFragment.newInstance(profileId.internalId, isMultipane)
activity.supportFragmentManager.beginTransaction().replace(
R.id.administrator_controls_fragment_multipane_placeholder,
fragment
Expand Down Expand Up @@ -209,9 +211,11 @@ class AdministratorControlsActivityPresenter @Inject constructor(
this@AdministratorControlsActivityPresenter.isProfileDeletionDialogVisible.let {
isProfileDeletionDialogVisible = it
}
selectedProfileId = this@AdministratorControlsActivityPresenter.selectedProfileId
}
.build()
outState.decorateWithUserProfileId(
this@AdministratorControlsActivityPresenter.selectedProfileId
)
outState.putProto(ADMINISTRATOR_CONTROLS_ACTIVITY_STATE_KEY, args)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ class AdministratorControlsFragmentPresenter @Inject constructor(
) {
private lateinit var binding: AdministratorControlsFragmentBinding
private lateinit var linearLayoutManager: LinearLayoutManager
private var internalProfileId: Int = -1
private lateinit var profileId: ProfileId

@Inject
Expand All @@ -56,8 +55,7 @@ class AdministratorControlsFragmentPresenter @Inject constructor(
/* attachToRoot= */ false
)

internalProfileId = activity.intent.extractCurrentUserProfileId().internalId
profileId = ProfileId.newBuilder().setInternalId(internalProfileId).build()
profileId = activity.intent.extractCurrentUserProfileId()
administratorControlsViewModel.setProfileId(profileId)

linearLayoutManager = LinearLayoutManager(activity.applicationContext)
Expand Down
Loading

0 comments on commit f3b0a0e

Please sign in to comment.