Commit 1a044daf authored by ZingBallyhoo's avatar ZingBallyhoo

Add Gitlab CI and revise project structure

parent efc835c6
......@@ -4,5 +4,4 @@ bin
# Prepare to install Java, skip the accept licence dialog
- apt-get install debconf
- echo debconf shared/accepted-oracle-license-v1-1 select true | debconf-set-selections
- echo debconf shared/accepted-oracle-license-v1-1 seen true | debconf-set-selections
- dpkg --add-architecture i386
- apt-get update
# P4A dependencies
- apt-get install -y build-essential ccache git zlib1g-dev python2.7 python2.7-dev libncurses5:i386 libstdc++6:i386 zlib1g:i386 openjdk-7-jdk unzip ant ccache
- apt-get update -qy
- apt-get install -y python-dev python-pip
# Debug things
- python -v
- which python
- pip -V
# P4A dependencies
- pip install colorama appdirs sh jinja2 six cython --upgrade
- cd $CI_PROJECT_DIR/gitlab-ci
- python ./
# If nothing in bin dir, then the build has failed
- cd $CI_PROJECT_DIR/demos/kitchen_sink
- if [ ! "$(ls -A ./bin)" ]; then exit 1; fi
- cd bin
# Rename apk in format {android_arch}-{git_branch}-{git_commit_hash}
type: build
- $CI_PROJECT_DIR/demos/kitchen_sink/bin/$CI_BUILD_NAME-$CI_BUILD_REF_NAME-${CI_BUILD_REF:0:8}.apk
- echo "Building KitchenSink for armeabi"
- cd $CI_PROJECT_DIR/gitlab-ci
# Install API
- python ./ --api 19
- cd $CI_PROJECT_DIR/demos/kitchen_sink
# Build vars
- export APP_ANDROID_ARCH=armeabi
- export APP_ANDROID_API=19
# Build
- buildozer android_new debug
type: build
- $CI_PROJECT_DIR/demos/kitchen_sink/bin/$CI_BUILD_NAME-$CI_BUILD_REF_NAME-${CI_BUILD_REF:0:8}.apk
- echo "Building KitchenSink for armeabi-v7a"
- cd $CI_PROJECT_DIR/gitlab-ci
# Install API
- python ./ --api 21
- cd $CI_PROJECT_DIR/demos/kitchen_sink
# Build vars
- export APP_ANDROID_ARCH=armeabi-v7a
- export APP_ANDROID_API=21
# Build
- buildozer android_new debug
type: build
- $CI_PROJECT_DIR/demos/kitchen_sink/bin/$CI_BUILD_NAME-$CI_BUILD_REF_NAME-${CI_BUILD_REF:0:8}.apk
- echo "Building KitchenSink for arm64-v8a"
- cd $CI_PROJECT_DIR/gitlab-ci
# Install API
- python ./ --api 21
- cd $CI_PROJECT_DIR/demos/kitchen_sink
# Build vars
- export APP_ANDROID_ARCH=arm64-v8a
- export APP_ANDROID_API=21
- buildozer android_new debug
type: build
- $CI_PROJECT_DIR/demos/kitchen_sink/bin/$CI_BUILD_NAME-$CI_BUILD_REF_NAME-${CI_BUILD_REF:0:8}.apk
- echo "Building KitchenSink for x86"
- cd $CI_PROJECT_DIR/gitlab-ci
# Install API
- python ./ --api 21
- cd $CI_PROJECT_DIR/demos/kitchen_sink
# Build vars
- export APP_ANDROID_ARCH=x86
- export APP_ANDROID_API=21
# Build
- buildozer android_new debug
\ No newline at end of file
# (str) Title of your application
title = KivyMD Kitchen Sink
# (str) Package name = kitchen_sink
# (str) Package domain (needed for android/ios packaging)
package.domain = org.kivymd
# (str) Source code where the live
source.dir = .
# (list) Source files to include (let empty to include all the files)
source.include_exts = py,png,jpg,kv,atlas
# (list) List of inclusions using pattern matching
#source.include_patterns = assets/*,images/*.png
# (list) Source files to exclude (let empty to not exclude anything)
#source.exclude_exts = spec
# (list) List of directory to exclude (let empty to not exclude anything)
source.exclude_dirs = bin
# (list) List of exclusions using pattern matching
source.exclude_patterns = buildozer.spec
# (str) Application versioning (method 1)
# version = 0.1
# (str) Application versioning (method 2)
version.regex = __version__ = ['\"]([^'\"]*)['\"]
version.filename = %(source.dir)s/../../kivymd/
# (list) Application requirements
# comma seperated e.g. requirements = sqlite3,kivy
requirements = kivy==master, kivymd, hostpython2
# (str) The directory in which python-for-android should look for your own build recipes (if any)
p4a.local_recipes = %(source.dir)s/../../gitlab-ci/p4a-recipes/
# (str) Custom source folders for requirements
# Sets custom source for any requirements with recipes
requirements.source.kivymd = ../../
# (list) Garden requirements
garden_requirements = recycleview
# (str) Presplash of the application
presplash.filename = %(source.dir)s/../../kivymd/images/kivymd_logo.png
# (str) Icon of the application
icon.filename = %(source.dir)s/../../kivymd/images/kivymd_logo.png
# (str) Supported orientation (one of landscape, portrait or all)
orientation = all
# (list) List of service to declare
# OSX Specific
# author = © Copyright Info
# Android specific
# (bool) Indicate if the application should be fullscreen or not
fullscreen = 1
# (list) Permissions
#android.permissions = INTERNET
# (int) Android API to use
android.api = 19
# (int) Minimum API required
#android.minapi = 9
# (int) Android SDK version to use
#android.sdk = 20
# (str) Android NDK version to use
android.ndk = 10e
# (bool) Use --private data storage (True) or --dir public storage (False)
#android.private_storage = True
# (str) Android NDK directory (if empty, it will be automatically downloaded.)
#android.ndk_path =
# (str) Android SDK directory (if empty, it will be automatically downloaded.)
#android.sdk_path =
# (str) ANT directory (if empty, it will be automatically downloaded.)
#android.ant_path =
# (str) python-for-android git clone directory (if empty, it will be automatically cloned from github)
#android.p4a_dir =
#android.p4a_dir = /media/zingballyhoo/Media/Code/Repos/python-for-android
# (str) Filename to the hook for p4a
#p4a.hook =
p4a.force-build = True
# (list) python-for-android whitelist
#android.p4a_whitelist =
# (bool) If True, then skip trying to update the Android sdk
# This can be useful to avoid excess Internet downloads or save time
# when an update is due and you just want to test/build your package
android.skip_update = True
# (str) Bootstrap to use for android builds (android_new only)
# android.bootstrap = sdl2
# (str) Android entry point, default is ok for Kivy-based app
#android.entrypoint =
# (list) List of Java .jar files to add to the libs so that pyjnius can access
# their classes. Don't add jars that you do not need, since extra jars can slow
# down the build process. Allows wildcards matching, for example:
# OUYA-ODK/libs/*.jar
#android.add_jars = foo.jar,bar.jar,path/to/more/*.jar
# (list) List of Java files to add to the android project (can be java or a
# directory containing the files)
#android.add_src =
# (str) python-for-android branch to use, if not master, useful to try
# not yet merged features.
#android.branch = master
# (str) OUYA Console category. Should be one of GAME or APP
# If you leave this blank, OUYA support will not be enabled
#android.ouya.category = GAME
# (str) Filename of OUYA Console icon. It must be a 732x412 png image.
#android.ouya.icon.filename = %(source.dir)s/data/ouya_icon.png
# (str) XML file to include as an intent filters in <activity> tag
#android.manifest.intent_filters =
# (list) Android additionnal libraries to copy into libs/armeabi
#android.add_libs_armeabi = libs/android/*.so
#android.add_libs_armeabi_v7a = libs/android-v7/*.so
#android.add_libs_x86 = libs/android-x86/*.so
#android.add_libs_mips = libs/android-mips/*.so
# (bool) Indicate whether the screen should stay on
# Don't forget to add the WAKE_LOCK permission if you set this to True
#android.wakelock = False
# (list) Android application meta-data to set (key=value format)
#android.meta_data =
# (list) Android library project to add (will be added in the
# automatically.)
#android.library_references =
# (str) Android logcat filters to use
#android.logcat_filters = *:S python:D
# (bool) Copy library instead of making a
#android.copy_libs = 1
# (str) The Android arch to build for, choices: armeabi-v7a, arm64-v8a, x86
android.arch = armeabi
# iOS specific
# (str) Path to a custom kivy-ios folder
#ios.kivy_ios_dir = ../kivy-ios
# (str) Name of the certificate to use for signing the debug version
# Get a list of available identities: buildozer ios list_identities
#ios.codesign.debug = "iPhone Developer: <lastname> <firstname> (<hexstring>)"
# (str) Name of the certificate to use for signing the release version
#ios.codesign.release = %(ios.codesign.debug)s
# (int) Log level (0 = error only, 1 = info, 2 = debug (with command output))
log_level = 2
# (int) Display warning if buildozer is run as root (0 = False, 1 = True)
warn_on_root = 0
# (str) Path to build artifact storage, absolute or relative to spec file
# build_dir = ./.buildozer
# (str) Path to build output (i.e. .apk, .ipa) storage
# bin_dir = ./bin
# -----------------------------------------------------------------------------
# List as sections
# You can define all the "list" as [section:key].
# Each line will be considered as a option to the list.
# Let's take [app] / source.exclude_patterns.
# Instead of doing:
#source.exclude_patterns = license,data/audio/*.wav,data/images/original/*
# This can be translated into:
# -----------------------------------------------------------------------------
# Profiles
# You can extend section / key with a profile
# For example, you want to deploy a demo version of your application without
# HD content. You could first change the title to add "(demo)" in the name
# and extend the excluded directories to remove the HD content.
#title = My Application (demo)
# Then, invoke the command line with the "demo" profile:
#buildozer --profile demo android debug
......@@ -866,6 +866,7 @@ class KitchenSink(App):
theme_cls = ThemeManager()
nav_drawer = ObjectProperty()
previous_date = ObjectProperty()
title = "KivyMD Kitchen Sink"
menu_items = [
{'viewclass': 'MDMenuItem',
These files are here to help with building with Python-for-android Gitlab CI
\ No newline at end of file
from buildozer import Buildozer, urlretrieve
from import TargetAndroid
import os
from optparse import OptionParser
# Designed to be used on Gitlab CI
# This file ensures that Build Tools 19.1 is installed
# This file will also install an android api version if an android api is passed in with "--api"
# 19.1 is used because it is the only build tool version I can get to work properly (minimum required by p4a also)
parser = OptionParser()
parser.add_option("--api", dest="api",
help="Android API to install", default=None)
(options, args) = parser.parse_args()
class FixedTargetAndroid(TargetAndroid):
def android_ndk_version(self):
return "10e"
class NoOutputBuildozer(Buildozer):
def set_target(self, target):
'''Set the target to use (one of buildozer.targets, such as "android")
self.targetname = target
m = __import__('buildozer.targets.{0}'.format(target),
fromlist=['buildozer']) = m.get_target(self)
def download(self, url, filename, cwd=None):
def report_hook(index, blksize, size):
url = url + filename
if cwd:
filename = os.path.join(cwd, filename)
if self.file_exists(filename):
self.debug('Downloading {0}'.format(url))
urlretrieve(url, filename, report_hook)
return filename
buildozer = NoOutputBuildozer(target='android')
buildozer.log_level = 0
# Ensure directories exist
buildozer.mkdir(os.path.join(buildozer.global_platform_dir, buildozer.targetname, 'platform'))
target = FixedTargetAndroid(buildozer)
def run_expect(cmd):
from pexpect import EOF
java_tool_options = os.environ.get('JAVA_TOOL_OPTIONS', '')
child = target.buildozer.cmd_expect(cmd, cwd=target.buildozer.global_platform_dir,
'JAVA_TOOL_OPTIONS': java_tool_options + ' -Dfile.encoding=UTF-8'
while True:
index = child.expect([EOF, u'[y/n]: '])
if index == 0:
plat_dir = buildozer.global_platform_dir
if not options.api:
for i in range(2):
run_expect(plat_dir + "/android-sdk-20/tools/android update sdk -u -a -t platform-tools,tools")
run_expect(plat_dir + "/android-sdk-20/tools/android update sdk -u -a -t build-tools-19.1.0")
run_expect(plat_dir + "/android-sdk-20/tools/android update sdk -u -a -t android-{}".format(options.api))
from os import environ
import sh
from pythonforandroid.logger import shprint, info_main, info
from pythonforandroid.toolchain import PythonRecipe
from pythonforandroid.util import ensure_dir
class KivyMDRecipe(PythonRecipe):
# This recipe installs KivyMD into the android dist from source
depends = ['kivy']
site_packages_name = 'kivymd'
call_hostpython_via_targetpython = False
def should_build(self, arch):
return True
def unpack(self, arch):
info_main('Unpacking {} for {}'.format(, arch))
build_dir = self.get_build_container_dir(arch)
user_dir = environ.get('P4A_{}_DIR'.format(
if user_dir is not None:
info("Installing KivyMD development versoion (from source)")
shprint(sh.rm, '-rf', build_dir)
shprint(sh.mkdir, '-p', build_dir)
shprint(sh.rmdir, build_dir)
ensure_dir(build_dir + "/kivymd")
shprint(sh.cp, user_dir + '/', self.get_build_dir(arch) + "/")
shprint(sh.cp, '-a', user_dir + "/kivymd", self.get_build_dir(arch) + "/kivymd")
recipe = KivyMDRecipe()
# -*- coding: utf-8 -*-
import os
from kivy import Logger
__version_info__ = (0, 1, 2)
__version__ = '.'.join(map(str, __version_info__))
path = os.path.dirname(__file__)
fonts_path = os.path.join(path, "fonts/")
images_path = os.path.join(path, 'images/')"KivyMD: KivyMD version: {}".format(__version__))
\ No newline at end of file
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
import re
from distutils.core import setup
VERSION_FILE = "kivymd/"
ver_file_data = open(VERSION_FILE, "rt").read()
ver_regex = r"^__version__ = ['\"]([^'\"]*)['\"]"
ver_reg_search =, ver_file_data, re.M)
if ver_reg_search:
version =
raise ValueError("Unable to find version string in {}.".format(VERSION_FILE))
description='Set of widgets for Kivy inspired by Google\'s Material '
author='Andrés Rodríguez',
'kivymd': ['images/*.png', 'images/*.jpg', 'images/*.atlas',
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment