diff --git a/README.rst b/README.rst index 4f845c4..1e686c3 100644 --- a/README.rst +++ b/README.rst @@ -79,6 +79,53 @@ Customising the Android app Customising the application, such as the logo or the background image, is currently not supported. If you are interested by this feature, please tell us about it in the Tutor `discussion forums `_. +Customising the app configuration (``tutor.yaml``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The Android app reads its configuration from a ``tutor.yaml`` file rendered at build time. +All commonly customised fields are exposed as ``ANDROID_*`` Tutor settings, so you can change +them with ``tutor config save --set =``. For example, to enable Firebase: + +.. code-block:: bash + + tutor config save \ + --set ANDROID_FIREBASE_ENABLED=true \ + --set ANDROID_FIREBASE_PROJECT_ID=my-project \ + --set ANDROID_FIREBASE_API_KEY=AIzaSy... + +The available settings include ``ANDROID_ENVIRONMENT_DISPLAY_NAME``, ``ANDROID_URI_SCHEME``, +``ANDROID_FAQ_URL``, ``ANDROID_OAUTH_CLIENT_ID``, ``ANDROID_PLATFORM_FULL_NAME``, +``ANDROID_THEME_DIRECTORY``, ``ANDROID_TOKEN_TYPE``, the agreement URLs +(``ANDROID_PRIVACY_POLICY_URL``, ``ANDROID_COOKIE_POLICY_URL``, ``ANDROID_DATA_SELL_CONSENT_URL``, +``ANDROID_TOS_URL``, ``ANDROID_EULA_URL``), ``ANDROID_SUPPORTED_LANGUAGES``, the +``ANDROID_DISCOVERY_*`` and ``ANDROID_PROGRAM_*`` groups, ``ANDROID_FIREBASE_*``, +``ANDROID_SEGMENT_IO_*``, ``ANDROID_BRAZE_*``, ``ANDROID_GOOGLE_*``, ``ANDROID_MICROSOFT_*``, +``ANDROID_FACEBOOK_*``, ``ANDROID_BRANCH_*``, and the feature flags +``ANDROID_WHATS_NEW_ENABLED``, ``ANDROID_SOCIAL_AUTH_ENABLED``, +``ANDROID_COURSE_NESTED_LIST_ENABLED`` and ``ANDROID_COURSE_UNIT_PROGRESS_ENABLED``. + +For settings that are not exposed as Tutor variables, your own Tutor plugin can append YAML +to ``tutor.yaml`` via the ``android-tutor-yaml`` patch: + +.. code-block:: python + + from tutor import hooks + + hooks.Filters.ENV_PATCHES.add_item(( + "android-tutor-yaml", + "MY_CUSTOM_KEY: my-value\n", + )) + +The Open edX Android app uses SnakeYAML, which keeps the last value when a key is duplicated. +That means a top-level key written by the patch will **replace** the value emitted earlier in +the file, so use ``ANDROID_*`` settings for partial tweaks within a group (for example +``ANDROID_FIREBASE_ENABLED``) and reserve the patch for adding new keys or for wholesale +replacement of an entire group. + +If neither approach is sufficient, you can replace the rendered ``tutor.yaml`` outright by +editing ``$(tutor config printroot)/env/plugins/android/build/config/tutor.yaml`` before +running ``tutor images build android-app``. + Troubleshooting --------------- diff --git a/changelog.d/20260505_140711_abdul.muqadim_customizable_tutor_yaml.md b/changelog.d/20260505_140711_abdul.muqadim_customizable_tutor_yaml.md new file mode 100644 index 0000000..31c312e --- /dev/null +++ b/changelog.d/20260505_140711_abdul.muqadim_customizable_tutor_yaml.md @@ -0,0 +1,2 @@ + +- [Feature] Make the Android app's `tutor.yaml` fully customisable from Tutor config (#48). All commonly tweaked fields (Firebase, Segment, Braze, Google, Microsoft, Facebook, Branch, agreement URLs, discovery/program settings, feature flags, etc.) are now exposed as `ANDROID_*` settings, and a new `android-tutor-yaml` patch lets plugins append or override any value in the rendered file. (by @Abdul-Muqadim-Arbisoft) diff --git a/tutorandroid/plugin.py b/tutorandroid/plugin.py index 6e1cd59..a669764 100644 --- a/tutorandroid/plugin.py +++ b/tutorandroid/plugin.py @@ -29,6 +29,66 @@ "RELEASE_STORE_PASSWORD": "android store password", "RELEASE_KEY_PASSWORD": "android release key password", "RELEASE_KEY_ALIAS": "android release key alias", + # tutor.yaml: top-level app settings + "ENVIRONMENT_DISPLAY_NAME": "tutor", + "URI_SCHEME": "", + "FAQ_URL": "", + "OAUTH_CLIENT_ID": "android", + "PLATFORM_FULL_NAME": "{{ PLATFORM_NAME }}", + "THEME_DIRECTORY": "openedx", + "TOKEN_TYPE": "JWT", + # Agreement URLs (leave empty to hide the corresponding setting) + "PRIVACY_POLICY_URL": "", + "COOKIE_POLICY_URL": "", + "DATA_SELL_CONSENT_URL": "", + "TOS_URL": "", + "EULA_URL": "", + "SUPPORTED_LANGUAGES": [], + # Discovery + "DISCOVERY_TYPE": "native", + "DISCOVERY_WEBVIEW_BASE_URL": "", + "DISCOVERY_WEBVIEW_COURSE_DETAIL_TEMPLATE": "", + "DISCOVERY_WEBVIEW_PROGRAM_DETAIL_TEMPLATE": "", + # Program + "PROGRAM_TYPE": "native", + "PROGRAM_WEBVIEW_PROGRAM_URL": "", + "PROGRAM_WEBVIEW_PROGRAM_DETAIL_URL_TEMPLATE": "", + # Firebase + "FIREBASE_ENABLED": False, + "FIREBASE_ANALYTICS_SOURCE": "", + "FIREBASE_CLOUD_MESSAGING_ENABLED": False, + "FIREBASE_PROJECT_NUMBER": "", + "FIREBASE_PROJECT_ID": "", + "FIREBASE_APPLICATION_ID": "", + "FIREBASE_API_KEY": "", + # Segment.io + "SEGMENT_IO_ENABLED": False, + "SEGMENT_IO_WRITE_KEY": "", + # Braze + "BRAZE_ENABLED": False, + "BRAZE_PUSH_NOTIFICATIONS_ENABLED": False, + # Social: Google + "GOOGLE_ENABLED": False, + "GOOGLE_CLIENT_ID": "", + # Social: Microsoft + "MICROSOFT_ENABLED": False, + "MICROSOFT_CLIENT_ID": "", + "MICROSOFT_PACKAGE_SIGNATURE": "", + # Social: Facebook + "FACEBOOK_ENABLED": False, + "FACEBOOK_APP_ID": "", + "FACEBOOK_CLIENT_TOKEN": "", + # Branch + "BRANCH_ENABLED": False, + "BRANCH_KEY": "", + "BRANCH_URI_SCHEME": "", + "BRANCH_HOST": "", + "BRANCH_ALTERNATE_HOST": "", + # Feature flags + "WHATS_NEW_ENABLED": False, + "SOCIAL_AUTH_ENABLED": False, + "COURSE_NESTED_LIST_ENABLED": False, + "COURSE_UNIT_PROGRESS_ENABLED": False, }, "unique": { "OAUTH2_SECRET": "{{ 24|random_string }}", diff --git a/tutorandroid/templates/android/build/config/tutor.yaml b/tutorandroid/templates/android/build/config/tutor.yaml index 76a85f1..f3777e1 100644 --- a/tutorandroid/templates/android/build/config/tutor.yaml +++ b/tutorandroid/templates/android/build/config/tutor.yaml @@ -1,83 +1,88 @@ # See docs: https://openedx.atlassian.net/wiki/spaces/LEARNER/pages/48792067/App+Configuration+Flags API_HOST_URL: "{{ "https" if ENABLE_HTTPS else "http" }}://{{ LMS_HOST }}" APPLICATION_ID: "{{ ANDROID_APP_ID }}" -ENVIRONMENT_DISPLAY_NAME: "tutor" -URI_SCHEME: '' +ENVIRONMENT_DISPLAY_NAME: "{{ ANDROID_ENVIRONMENT_DISPLAY_NAME }}" +URI_SCHEME: "{{ ANDROID_URI_SCHEME }}" FEEDBACK_EMAIL_ADDRESS: "{{ CONTACT_EMAIL }}" -FAQ_URL: '' -OAUTH_CLIENT_ID: "android" +FAQ_URL: "{{ ANDROID_FAQ_URL }}" +OAUTH_CLIENT_ID: "{{ ANDROID_OAUTH_CLIENT_ID }}" # Keep empty to hide setting AGREEMENT_URLS: - PRIVACY_POLICY_URL: '' - COOKIE_POLICY_URL: '' - DATA_SELL_CONSENT_URL: '' - TOS_URL: '' - EULA_URL: '' - SUPPORTED_LANGUAGES: [ ] #en is default language + PRIVACY_POLICY_URL: "{{ ANDROID_PRIVACY_POLICY_URL }}" + COOKIE_POLICY_URL: "{{ ANDROID_COOKIE_POLICY_URL }}" + DATA_SELL_CONSENT_URL: "{{ ANDROID_DATA_SELL_CONSENT_URL }}" + TOS_URL: "{{ ANDROID_TOS_URL }}" + EULA_URL: "{{ ANDROID_EULA_URL }}" + SUPPORTED_LANGUAGES: {{ ANDROID_SUPPORTED_LANGUAGES }} #en is default language DISCOVERY: - TYPE: 'native' + TYPE: "{{ ANDROID_DISCOVERY_TYPE }}" WEBVIEW: - BASE_URL: '' - COURSE_DETAIL_TEMPLATE: '' - PROGRAM_DETAIL_TEMPLATE: '' + BASE_URL: "{{ ANDROID_DISCOVERY_WEBVIEW_BASE_URL }}" + COURSE_DETAIL_TEMPLATE: "{{ ANDROID_DISCOVERY_WEBVIEW_COURSE_DETAIL_TEMPLATE }}" + PROGRAM_DETAIL_TEMPLATE: "{{ ANDROID_DISCOVERY_WEBVIEW_PROGRAM_DETAIL_TEMPLATE }}" PROGRAM: - TYPE: 'native' + TYPE: "{{ ANDROID_PROGRAM_TYPE }}" WEBVIEW: - PROGRAM_URL: '' - PROGRAM_DETAIL_URL_TEMPLATE: '' + PROGRAM_URL: "{{ ANDROID_PROGRAM_WEBVIEW_PROGRAM_URL }}" + PROGRAM_DETAIL_URL_TEMPLATE: "{{ ANDROID_PROGRAM_WEBVIEW_PROGRAM_DETAIL_URL_TEMPLATE }}" FIREBASE: - ENABLED: false - ANALYTICS_SOURCE: '' # segment | none - CLOUD_MESSAGING_ENABLED: false - PROJECT_NUMBER: '' - PROJECT_ID: '' - APPLICATION_ID: '' # App ID field from the Firebase console or mobilesdk_app_id from the google-services.json file. - API_KEY: '' + ENABLED: {{ ANDROID_FIREBASE_ENABLED }} + ANALYTICS_SOURCE: "{{ ANDROID_FIREBASE_ANALYTICS_SOURCE }}" # segment | none + CLOUD_MESSAGING_ENABLED: {{ ANDROID_FIREBASE_CLOUD_MESSAGING_ENABLED }} + PROJECT_NUMBER: "{{ ANDROID_FIREBASE_PROJECT_NUMBER }}" + PROJECT_ID: "{{ ANDROID_FIREBASE_PROJECT_ID }}" + APPLICATION_ID: "{{ ANDROID_FIREBASE_APPLICATION_ID }}" # App ID field from the Firebase console or mobilesdk_app_id from the google-services.json file. + API_KEY: "{{ ANDROID_FIREBASE_API_KEY }}" SEGMENT_IO: - ENABLED: false - SEGMENT_IO_WRITE_KEY: '' + ENABLED: {{ ANDROID_SEGMENT_IO_ENABLED }} + SEGMENT_IO_WRITE_KEY: "{{ ANDROID_SEGMENT_IO_WRITE_KEY }}" BRAZE: - ENABLED: false - PUSH_NOTIFICATIONS_ENABLED: false + ENABLED: {{ ANDROID_BRAZE_ENABLED }} + PUSH_NOTIFICATIONS_ENABLED: {{ ANDROID_BRAZE_PUSH_NOTIFICATIONS_ENABLED }} GOOGLE: - ENABLED: false - CLIENT_ID: '' + ENABLED: {{ ANDROID_GOOGLE_ENABLED }} + CLIENT_ID: "{{ ANDROID_GOOGLE_CLIENT_ID }}" MICROSOFT: - ENABLED: false - CLIENT_ID: '' - PACKAGE_SIGNATURE: '' + ENABLED: {{ ANDROID_MICROSOFT_ENABLED }} + CLIENT_ID: "{{ ANDROID_MICROSOFT_CLIENT_ID }}" + PACKAGE_SIGNATURE: "{{ ANDROID_MICROSOFT_PACKAGE_SIGNATURE }}" FACEBOOK: - ENABLED: false - FACEBOOK_APP_ID: '' - CLIENT_TOKEN: '' + ENABLED: {{ ANDROID_FACEBOOK_ENABLED }} + FACEBOOK_APP_ID: "{{ ANDROID_FACEBOOK_APP_ID }}" + CLIENT_TOKEN: "{{ ANDROID_FACEBOOK_CLIENT_TOKEN }}" BRANCH: - ENABLED: false - KEY: '' - URI_SCHEME: '' - HOST: '' - ALTERNATE_HOST: '' + ENABLED: {{ ANDROID_BRANCH_ENABLED }} + KEY: "{{ ANDROID_BRANCH_KEY }}" + URI_SCHEME: "{{ ANDROID_BRANCH_URI_SCHEME }}" + HOST: "{{ ANDROID_BRANCH_HOST }}" + ALTERNATE_HOST: "{{ ANDROID_BRANCH_ALTERNATE_HOST }}" #Platform names -PLATFORM_NAME: "{{ PLATFORM_NAME }}" -PLATFORM_FULL_NAME: "{{ PLATFORM_NAME }}" +PLATFORM_NAME: "{{ PLATFORM_NAME }}" +PLATFORM_FULL_NAME: "{{ ANDROID_PLATFORM_FULL_NAME }}" #App sourceSets dir -THEME_DIRECTORY: "openedx" +THEME_DIRECTORY: "{{ ANDROID_THEME_DIRECTORY }}" #tokenType enum accepts JWT and BEARER only -TOKEN_TYPE: "JWT" +TOKEN_TYPE: "{{ ANDROID_TOKEN_TYPE }}" #feature flag for activating What’s New feature -WHATS_NEW_ENABLED: false +WHATS_NEW_ENABLED: {{ ANDROID_WHATS_NEW_ENABLED }} #feature flag enable Social Login buttons -SOCIAL_AUTH_ENABLED: false +SOCIAL_AUTH_ENABLED: {{ ANDROID_SOCIAL_AUTH_ENABLED }} #Course navigation feature flags -COURSE_NESTED_LIST_ENABLED: false -COURSE_UNIT_PROGRESS_ENABLED: false +COURSE_NESTED_LIST_ENABLED: {{ ANDROID_COURSE_NESTED_LIST_ENABLED }} +COURSE_UNIT_PROGRESS_ENABLED: {{ ANDROID_COURSE_UNIT_PROGRESS_ENABLED }} + +# Custom values appended by other Tutor plugins. SnakeYAML, used by the Open edX +# Android app, takes the last value when keys are duplicated, so this hook can +# also be used to override any of the values defined above. +{{ patch("android-tutor-yaml") }}