feat: upgrade to maple
In Maple, the plugin API is slightly different: the apk file is built and stored in the android-app Docker image, then served by a simple Caddy file server. This makes it easy to distribute the apk to students.
This commit is contained in:
parent
af495f3e7d
commit
e165bf04ea
@ -2,7 +2,7 @@ variables:
|
||||
TUTOR_PLUGIN: android
|
||||
TUTOR_IMAGES: android
|
||||
TUTOR_PYPI_PACKAGE: tutor-android
|
||||
OPENEDX_RELEASE: lilac
|
||||
OPENEDX_RELEASE: maple
|
||||
GITHUB_REPO: overhangio/tutor-android
|
||||
|
||||
include:
|
||||
|
||||
23
README.rst
23
README.rst
@ -13,15 +13,13 @@ Installation
|
||||
Usage
|
||||
-----
|
||||
|
||||
Enable the plugin::
|
||||
Enable the plugin and start the platform::
|
||||
|
||||
tutor plugins enable android
|
||||
tutor local quickstart
|
||||
|
||||
To build the application in debug mode, run::
|
||||
|
||||
tutor android build debug
|
||||
|
||||
The ``.apk`` file will then be available in ``$(tutor config printroot)/data/android``. Transfer it to an Android phone to install the application. You should be able to sign in and view available courses.
|
||||
The ``.apk`` file will then be available for download at http(s)://mobile.LMS_HOST/app.apk. When running locally, this will be: http://mobile.local.overhang.io/app.apk. You can forward this address to your students for download.
|
||||
|
||||
Building a custom Android app
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
@ -38,22 +36,23 @@ Releasing an Android app
|
||||
|
||||
**Note**: this is an untested feature.
|
||||
|
||||
Releasing an Android app on the Play Store requires to build the app in release mode. To do so, edit the ``$TUTOR_ROOT/config.yml`` configuration file and define the following variables::
|
||||
Releasing an Android app on the Play Store requires to build the app in release mode. To do so, modify the following Tutor settings::
|
||||
|
||||
ANDROID_RELEASE_STORE_PASSWORD
|
||||
ANDROID_RELEASE_KEY_PASSWORD
|
||||
ANDROID_RELEASE_KEY_ALIAS
|
||||
tutor config save \
|
||||
--set ANDROID_RELEASE_STORE_PASSWORD=yourstorepassword \
|
||||
--set ANDROID_RELEASE_KEY_PASSWORD=yourreleasekeypassword \
|
||||
--set ANDROID_RELEASE_KEY_ALIAS=yourreleasekeyalias \
|
||||
--set ANDROID_ENABLE_RELEASE_MODE=true
|
||||
|
||||
Then, place your keystore file in ``$(tutor config printroot)/env/plugins/android/apps/app.keystore``. Finally, build the application with::
|
||||
Then, place your keystore file in ``$(tutor config printroot)/env/plugins/android/build/app/config/app.keystore``. Finally, rebuild the image by starting the "android-app" container::
|
||||
|
||||
tutor android build release
|
||||
tutor local start -d android-app
|
||||
|
||||
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 <https://discuss.overhang.io>`_.
|
||||
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
|
||||
2
setup.py
2
setup.py
@ -39,7 +39,7 @@ setup(
|
||||
packages=find_packages(exclude=["tests*"]),
|
||||
include_package_data=True,
|
||||
python_requires=">=3.5",
|
||||
install_requires=["tutor>=12.0.0,<13.0.0"],
|
||||
install_requires=["tutor>=13.0.0,<14.0.0"],
|
||||
entry_points={
|
||||
"tutor.plugin.v0": [
|
||||
"android = tutorandroid.plugin"
|
||||
|
||||
@ -1 +1 @@
|
||||
__version__ = "12.0.1"
|
||||
__version__ = "13.0.0"
|
||||
|
||||
@ -1,51 +0,0 @@
|
||||
import click
|
||||
|
||||
from tutor.commands.context import Context
|
||||
from tutor.commands.local import LocalJobRunner
|
||||
from tutor import config as tutor_config
|
||||
from tutor import env as tutor_env
|
||||
from tutor import fmt
|
||||
from tutor.types import Config
|
||||
|
||||
|
||||
@click.group(help="Build an Android app for your Open edX platform")
|
||||
def android() -> None:
|
||||
pass
|
||||
|
||||
|
||||
@click.command(help="Build the application")
|
||||
@click.argument("mode", type=click.Choice(["debug", "release"]))
|
||||
@click.pass_obj
|
||||
def build(context: Context, mode: str) -> None:
|
||||
config = tutor_config.load(context.root)
|
||||
docker_run(context.root, build_command(config, mode))
|
||||
fmt.echo_info(
|
||||
"The {} APK file is available in {}".format(
|
||||
mode, tutor_env.data_path(context.root, "android")
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def build_command(config: Config, target: str) -> str:
|
||||
gradle_target = {
|
||||
"debug": "assembleProdDebuggable",
|
||||
"release": "assembleProdRelease",
|
||||
}[target]
|
||||
apk_folder = {"debug": "debuggable", "release": "release"}[target]
|
||||
|
||||
command = """
|
||||
sed -i "s/APPLICATION_ID = .*/APPLICATION_ID = \\"{{ LMS_HOST|reverse_host|replace("-", "_") }}\\"/g" constants.gradle
|
||||
./gradlew {gradle_target}
|
||||
cp OpenEdXMobile/build/outputs/apk/prod/{apk_folder}/*.apk /openedx/data/"""
|
||||
command = tutor_env.render_str(config, command)
|
||||
command = command.format(gradle_target=gradle_target, apk_folder=apk_folder)
|
||||
return command
|
||||
|
||||
|
||||
def docker_run(root: str, command: str) -> None:
|
||||
config = tutor_config.load(root)
|
||||
runner = LocalJobRunner(root, config)
|
||||
runner.run_job("android", command)
|
||||
|
||||
|
||||
android.add_command(build)
|
||||
3
tutorandroid/patches/caddyfile
Normal file
3
tutorandroid/patches/caddyfile
Normal file
@ -0,0 +1,3 @@
|
||||
{{ ANDROID_APP_HOST }}{$default_site_port} {
|
||||
import proxy "android-app:8000"
|
||||
}
|
||||
27
tutorandroid/patches/k8s-deployments
Normal file
27
tutorandroid/patches/k8s-deployments
Normal file
@ -0,0 +1,27 @@
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: android-app
|
||||
labels:
|
||||
app.kubernetes.io/name: android-app
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: android-app
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/name: android-app
|
||||
spec:
|
||||
securityContext:
|
||||
runAsUser: 1000
|
||||
runAsGroup: 1000
|
||||
containers:
|
||||
- name: android-app
|
||||
image: {{ ANDROID_APP_DOCKER_IMAGE }}
|
||||
imagePullPolicy: Always
|
||||
ports:
|
||||
- containerPort: 8000
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
12
tutorandroid/patches/k8s-services
Normal file
12
tutorandroid/patches/k8s-services
Normal file
@ -0,0 +1,12 @@
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: android-app
|
||||
spec:
|
||||
type: NodePort
|
||||
ports:
|
||||
- port: 8000
|
||||
protocol: TCP
|
||||
selector:
|
||||
app.kubernetes.io/name: android-app
|
||||
@ -1,5 +0,0 @@
|
||||
android-job:
|
||||
image: {{ ANDROID_DOCKER_IMAGE }}
|
||||
volumes:
|
||||
- "../plugins/android/apps:/openedx/config/"
|
||||
- "../../data/android/:/openedx/data/"
|
||||
6
tutorandroid/patches/local-docker-compose-services
Normal file
6
tutorandroid/patches/local-docker-compose-services
Normal file
@ -0,0 +1,6 @@
|
||||
# Android app
|
||||
android-app:
|
||||
image: {{ ANDROID_APP_DOCKER_IMAGE }}
|
||||
build:
|
||||
context: ../plugins/android/build/app/
|
||||
restart: unless-stopped
|
||||
@ -3,7 +3,6 @@ import os
|
||||
import pkg_resources
|
||||
|
||||
from .__about__ import __version__
|
||||
from .cli import android as android_command
|
||||
|
||||
|
||||
templates = pkg_resources.resource_filename("tutorandroid", "templates")
|
||||
@ -13,7 +12,11 @@ config = {
|
||||
"add": {"OAUTH2_SECRET": "{{ 24|random_string }}"},
|
||||
"defaults": {
|
||||
"VERSION": __version__,
|
||||
"APP_HOST": "mobile.{{ LMS_HOST }}",
|
||||
"APP_VERSION": "2.26.1", # https://github.com/edx/edx-app-android/releases
|
||||
"DOCKER_IMAGE": "{{ DOCKER_REGISTRY }}overhangio/openedx-android:{{ ANDROID_VERSION }}",
|
||||
"APP_DOCKER_IMAGE": "{{ DOCKER_REGISTRY }}overhangio/openedx-android-app:{{ ANDROID_VERSION }}",
|
||||
"ENABLE_RELEASE_MODE": False,
|
||||
"RELEASE_STORE_PASSWORD": "android store password",
|
||||
"RELEASE_KEY_PASSWORD": "android release key password",
|
||||
"RELEASE_KEY_ALIAS": "android release key alias",
|
||||
@ -21,15 +24,15 @@ config = {
|
||||
}
|
||||
|
||||
hooks = {
|
||||
"build-image": {"android": "{{ ANDROID_DOCKER_IMAGE }}"},
|
||||
"build-image": {
|
||||
"android": "{{ ANDROID_DOCKER_IMAGE }}",
|
||||
"android-app": "{{ ANDROID_APP_DOCKER_IMAGE }}",
|
||||
},
|
||||
"remote-image": {"android": "{{ ANDROID_DOCKER_IMAGE }}"},
|
||||
"init": ["lms"],
|
||||
}
|
||||
|
||||
|
||||
command = android_command
|
||||
|
||||
|
||||
def patches():
|
||||
all_patches = {}
|
||||
patches_dir = pkg_resources.resource_filename("tutorandroid", "patches")
|
||||
|
||||
@ -6,35 +6,32 @@ RUN apt update && \
|
||||
apt upgrade -y && \
|
||||
apt install -y wget unzip git openjdk-8-jre openjdk-8-jdk
|
||||
|
||||
RUN mkdir /openedx
|
||||
RUN mkdir /app
|
||||
|
||||
# Install Android SDK
|
||||
# Inspired from https://github.com/LiveXP/docker-android-sdk/blob/master/Dockerfile
|
||||
ENV ANDROID_SDK_VERSION 6200805
|
||||
ENV ANDROID_SDK_PATH /openedx/android-sdk
|
||||
ENV ANDROID_HOME /openedx/android-sdk
|
||||
# Get sdk version from here: https://developer.android.com/studio#command-tools
|
||||
ENV ANDROID_SDK_VERSION 7583922
|
||||
ENV ANDROID_SDK_PATH /app/android-sdk
|
||||
ENV ANDROID_HOME /app/android-sdk
|
||||
RUN mkdir ${ANDROID_HOME}
|
||||
WORKDIR /openedx/android-sdk
|
||||
WORKDIR /app/android-sdk
|
||||
RUN wget https://dl.google.com/android/repository/commandlinetools-linux-${ANDROID_SDK_VERSION}_latest.zip && \
|
||||
unzip commandlinetools-linux-${ANDROID_SDK_VERSION}_latest.zip && \
|
||||
rm commandlinetools-linux-${ANDROID_SDK_VERSION}_latest.zip
|
||||
|
||||
# Accept licenses
|
||||
# https://developer.android.com/studio/command-line/sdkmanager
|
||||
ARG ANDROID_API_LEVEL=28
|
||||
RUN yes | /openedx/android-sdk/tools/bin/sdkmanager --sdk_root=${ANDROID_HOME} --install "platforms;android-$ANDROID_API_LEVEL" 1> /dev/null
|
||||
# Check target version: https://github.com/edx/edx-app-android/blob/master/constants.gradle
|
||||
ARG ANDROID_API_LEVEL=29
|
||||
RUN yes | /app/android-sdk/cmdline-tools/bin/sdkmanager --sdk_root=${ANDROID_HOME} --install "platforms;android-$ANDROID_API_LEVEL" 1> /dev/null
|
||||
|
||||
# Install android app repo
|
||||
ARG ANDROID_APP_REPOSITORY=https://github.com/edx/edx-app-android
|
||||
ARG ANDROID_APP_VERSION=release/2.25.1
|
||||
RUN git clone $ANDROID_APP_REPOSITORY --branch $ANDROID_APP_VERSION /openedx/edx-app-android
|
||||
WORKDIR /openedx/edx-app-android
|
||||
ARG ANDROID_APP_VERSION=release/{{ ANDROID_APP_VERSION }}
|
||||
RUN git clone $ANDROID_APP_REPOSITORY --branch $ANDROID_APP_VERSION /app/edx-app-android
|
||||
WORKDIR /app/edx-app-android
|
||||
|
||||
# Install gradle and all dependencies
|
||||
RUN ./gradlew -v
|
||||
RUN ./gradlew tasks
|
||||
|
||||
# User-customized config
|
||||
COPY ./edx.properties ./OpenEdXMobile/edx.properties
|
||||
RUN mkdir /openedx/config
|
||||
RUN ln -s /openedx/config/gradle.properties ./OpenEdXMobile/gradle.properties
|
||||
|
||||
@ -1 +0,0 @@
|
||||
edx.dir = '/openedx/config'
|
||||
19
tutorandroid/templates/android/build/app/Dockerfile
Normal file
19
tutorandroid/templates/android/build/app/Dockerfile
Normal file
@ -0,0 +1,19 @@
|
||||
#### Build image with app-specific settings
|
||||
FROM {{ ANDROID_DOCKER_IMAGE }} as build
|
||||
|
||||
# User-customized config
|
||||
COPY ./config/edx.properties ./OpenEdXMobile/default_config/edx.properties
|
||||
COPY ./config/tutor.yaml ./OpenEdXMobile/default_config/tutor.yaml
|
||||
{% if ANDROID_ENABLE_RELEASE_MODE %}
|
||||
# Add release settings
|
||||
COPY ./config/gradle.properties ./gradle.properties.tutor
|
||||
RUN cat ./gradle.properties.tutor >> ./gradle.properties
|
||||
{% endif %}
|
||||
|
||||
RUN sed -i "s/APPLICATION_ID = .*/APPLICATION_ID = \"{{ LMS_HOST|reverse_host|replace("-", "_") }}\"/g" constants.gradle
|
||||
RUN ./gradlew assembleProd{{ "Release" if ANDROID_ENABLE_RELEASE_MODE else "Debuggable" }}
|
||||
|
||||
#### File server to serve apk file
|
||||
FROM docker.io/caddy:2.4.3-alpine as production
|
||||
COPY --from=build /app/edx-app-android/OpenEdXMobile/build/outputs/apk/prod/{{ "release" if ANDROID_ENABLE_RELEASE_MODE else "debuggable" }}/edx-{{ "release" if ANDROID_ENABLE_RELEASE_MODE else "debuggable" }}-{{ ANDROID_APP_VERSION }}.apk /srv/app.apk
|
||||
CMD caddy file-server --listen=:8000 --root=/srv
|
||||
@ -1,4 +1,4 @@
|
||||
RELEASE_STORE_FILE=/openedx/config/app.keystore
|
||||
RELEASE_STORE_FILE=/app/edx-app-android/OpenEdXMobile/app.keystore
|
||||
RELEASE_STORE_PASSWORD={{ ANDROID_RELEASE_STORE_PASSWORD }}
|
||||
RELEASE_KEY_PASSWORD={{ ANDROID_RELEASE_KEY_PASSWORD }}
|
||||
RELEASE_KEY_ALIAS={{ ANDROID_RELEASE_KEY_ALIAS }}
|
||||
Loading…
x
Reference in New Issue
Block a user