Skip to content
Snippets Groups Projects
Commit 5b8fca20 authored by Benoît Harrault's avatar Benoît Harrault
Browse files

Merge branch '1-add-a-first-hello-world-activity' into 'master'

Resolve "Add a first hello world activity"

Closes #1

See merge request !1
parents eab02a57 bd692489
No related branches found
No related tags found
1 merge request!1Resolve "Add a first hello world activity"
Pipeline #822 passed
Showing
with 257 additions and 400 deletions
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/
# Flutter/Dart/Pub related
**/doc/api/
**/ios/Flutter/.last_build_id
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
.packages
.pub-cache/
.pub/
/build/
# Web related
lib/generated_plugin_registrant.dart
# Symbolication related
app.*.symbols
# Obfuscation related
app.*.map.json
# Android Studio will place build artifacts here
/android/app/debug
/android/app/profile
/android/app/release
stages:
- environment
- build
- test
- internal
- alpha
- beta
- production
image: cirrusci/flutter:latest
stages:
- update
- build-debug
- build-release
- deploy
.updateContainerJob:
image: docker:stable
stage: environment
services:
- docker:dind
update:
stage: update
script:
- docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
- docker pull $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG || true
- docker build --cache-from $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG -t $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG .
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
updateContainer:
extends: .updateContainerJob
only:
changes:
- Dockerfile
ensureContainer:
extends: .updateContainerJob
allow_failure: true
before_script:
- "mkdir -p ~/.docker && echo '{\"experimental\": \"enabled\"}' > ~/.docker/config.json"
- docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
# Skip update container `script` if the container already exists
# via https://gitlab.com/gitlab-org/gitlab-ce/issues/26866#note_97609397 -> https://stackoverflow.com/a/52077071/796832
- docker manifest inspect $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG > /dev/null && exit || true
except:
changes:
- Dockerfile
- flutter packages get
- flutter packages upgrade
interruptible: true
.build_job:
image: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
stage: build
before_script:
- chmod +x gradlew
- "export VERSION_CODE=$(($CI_PIPELINE_IID)) && echo $VERSION_CODE"
- "export VERSION_SHA=`echo ${CI_COMMIT_SHA:0:8}` && echo $VERSION_SHA"
android:build-debug:
stage: build-debug
script:
# Flutter local configuration
- echo flutter.sdk=$FLUTTER_PATH > android/local.properties
- echo sdk.dir=$ANDROID_SDK_PATH >> android/local.properties
- echo flutter.buildMode=debug >> android/local.properties
# Android signing
- echo "$ANDROID_DEBUG_KEYSTORE_FILE" | base64 -d > android/app/my.keystore
- echo storeFile=my.keystore > android/key.properties
- echo storePassword=$ANDROID_DEBUG_KEYSTORE_PASSWORD >> android/key.properties
- echo keyAlias=$ANDROID_DEBUG_KEY_ALIAS >> android/key.properties
- echo keyPassword=$ANDROID_DEBUG_KEY_PASSWORD >> android/key.properties
# build flutter app
- flutter build apk --debug
# prepare artifact
- find . -name "*.apk" # where is my apk?
artifacts:
paths:
- app/build/outputs
buildDebug:
extends: .build_job
script:
- bundle exec fastlane buildDebug
- build/app/outputs/apk/debug
expire_in: 1 week
interruptible: true
buildRelease:
extends: .build_job
script:
- bundle exec fastlane buildRelease
environment:
name: production
testDebug:
image: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
stage: test
dependencies:
- buildDebug
script:
- chmod +x gradlew
- bundle exec fastlane test
.promote_job:
image: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
when: manual
dependencies: []
before_script:
- echo You need to add your google_play_api_key.json file for this to work. Please see project's README.md. && false
- chmod +x gradlew
after_script:
- rm -f ~/google_play_api_key.json
publishInternal:
extends: .promote_job
image: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
stage: internal
android:build-release:
stage: build-release
only:
- master
dependencies:
- buildRelease
when: manual
script:
- bundle exec fastlane internal
promoteAlpha:
extends: .promote_job
stage: alpha
- android:build-debug
script:
- bundle exec fastlane promote_internal_to_alpha
promoteBeta:
extends: .promote_job
stage: beta
script:
- bundle exec fastlane promote_alpha_to_beta
# Flutter local configuration
- echo flutter.sdk=$FLUTTER_PATH > android/local.properties
- echo sdk.dir=$ANDROID_SDK_PATH >> android/local.properties
- echo flutter.buildMode=release >> android/local.properties
# Android signing
- echo "$ANDROID_KEYSTORE_FILE" | base64 -d > android/app/my.keystore
- echo storeFile=my.keystore > android/key.properties
- echo storePassword=$ANDROID_KEYSTORE_PASSWORD >> android/key.properties
- echo keyAlias=$ANDROID_KEY_ALIAS >> android/key.properties
- echo keyPassword=$ANDROID_KEY_PASSWORD >> android/key.properties
# build flutter app
- flutter build apk
# prepare artifact
- find . -name "*.apk" # where is my apk?
artifacts:
paths:
- build/app/outputs/apk/release
expire_in: 1 week
interruptible: true
promoteProduction:
extends: .promote_job
stage: production
# We only allow production promotion on master because
# in this way you can protect production scoped secret variables
android:deploy:
stage: deploy
only:
- master
- master
dependencies:
- android:build-release
script:
- bundle exec fastlane promote_beta_to_production
- wget ${REPOSITORY_UPDATE_WEBHOOK}?token=${REPOSITORY_TOKEN}
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.
version:
revision: 5bedb7b1d5698ce2c1c67aaf9afae7b3948b172a
channel: beta
project_type: app
# This Dockerfile creates a static build image for CI
FROM openjdk:8-jdk
# Just matched `app/build.gradle`
ENV ANDROID_COMPILE_SDK "28"
# Just matched `app/build.gradle`
ENV ANDROID_BUILD_TOOLS "28.0.3"
# Version from https://developer.android.com/studio/releases/sdk-tools
ENV ANDROID_SDK_TOOLS "24.4.1"
ENV ANDROID_HOME /android-sdk-linux
ENV PATH="${PATH}:/android-sdk-linux/platform-tools/"
# install OS packages
RUN apt-get --quiet update --yes
RUN apt-get --quiet install --yes wget apt-utils tar unzip lib32stdc++6 lib32z1 build-essential ruby ruby-dev
# We use this for xxd hex->binary
RUN apt-get --quiet install --yes vim-common
# install Android SDK
RUN wget --quiet --output-document=android-sdk.tgz https://dl.google.com/android/android-sdk_r${ANDROID_SDK_TOOLS}-linux.tgz
RUN tar --extract --gzip --file=android-sdk.tgz
RUN echo y | android-sdk-linux/tools/android --silent update sdk --no-ui --all --filter android-${ANDROID_COMPILE_SDK}
RUN echo y | android-sdk-linux/tools/android --silent update sdk --no-ui --all --filter platform-tools
RUN echo y | android-sdk-linux/tools/android --silent update sdk --no-ui --all --filter build-tools-${ANDROID_BUILD_TOOLS}
RUN echo y | android-sdk-linux/tools/android --silent update sdk --no-ui --all --filter extra-android-m2repository
RUN echo y | android-sdk-linux/tools/android --silent update sdk --no-ui --all --filter extra-google-google_play_services
RUN echo y | android-sdk-linux/tools/android --silent update sdk --no-ui --all --filter extra-google-m2repository
# install FastLane
COPY Gemfile.lock .
COPY Gemfile .
RUN gem install bundler -v 1.16.6
RUN bundle install
GEM
remote: https://rubygems.org/
specs:
CFPropertyList (3.0.0)
addressable (2.6.0)
public_suffix (>= 2.0.2, < 4.0)
atomos (0.1.3)
babosa (1.0.2)
claide (1.0.2)
colored (1.2)
colored2 (3.1.2)
commander-fastlane (4.4.6)
highline (~> 1.7.2)
declarative (0.0.10)
declarative-option (0.1.0)
digest-crc (0.4.1)
domain_name (0.5.20180417)
unf (>= 0.0.5, < 1.0.0)
dotenv (2.6.0)
emoji_regex (1.0.1)
excon (0.62.0)
faraday (0.15.4)
multipart-post (>= 1.2, < 3)
faraday-cookie_jar (0.0.6)
faraday (>= 0.7.4)
http-cookie (~> 1.0.0)
faraday_middleware (0.13.1)
faraday (>= 0.7.4, < 1.0)
fastimage (2.1.5)
fastlane (2.116.0)
CFPropertyList (>= 2.3, < 4.0.0)
addressable (>= 2.3, < 3.0.0)
babosa (>= 1.0.2, < 2.0.0)
bundler (>= 1.12.0, < 3.0.0)
colored
commander-fastlane (>= 4.4.6, < 5.0.0)
dotenv (>= 2.1.1, < 3.0.0)
emoji_regex (>= 0.1, < 2.0)
excon (>= 0.45.0, < 1.0.0)
faraday (~> 0.9)
faraday-cookie_jar (~> 0.0.6)
faraday_middleware (~> 0.9)
fastimage (>= 2.1.0, < 3.0.0)
gh_inspector (>= 1.1.2, < 2.0.0)
google-api-client (>= 0.21.2, < 0.24.0)
google-cloud-storage (>= 1.15.0, < 2.0.0)
highline (>= 1.7.2, < 2.0.0)
json (< 3.0.0)
mini_magick (~> 4.5.1)
multi_json
multi_xml (~> 0.5)
multipart-post (~> 2.0.0)
plist (>= 3.1.0, < 4.0.0)
public_suffix (~> 2.0.0)
rubyzip (>= 1.2.2, < 2.0.0)
security (= 0.1.3)
simctl (~> 1.6.3)
slack-notifier (>= 2.0.0, < 3.0.0)
terminal-notifier (>= 1.6.2, < 2.0.0)
terminal-table (>= 1.4.5, < 2.0.0)
tty-screen (>= 0.6.3, < 1.0.0)
tty-spinner (>= 0.8.0, < 1.0.0)
word_wrap (~> 1.0.0)
xcodeproj (>= 1.6.0, < 2.0.0)
xcpretty (~> 0.3.0)
xcpretty-travis-formatter (>= 0.0.3)
gh_inspector (1.1.3)
google-api-client (0.23.9)
addressable (~> 2.5, >= 2.5.1)
googleauth (>= 0.5, < 0.7.0)
httpclient (>= 2.8.1, < 3.0)
mime-types (~> 3.0)
representable (~> 3.0)
retriable (>= 2.0, < 4.0)
signet (~> 0.9)
google-cloud-core (1.3.0)
google-cloud-env (~> 1.0)
google-cloud-env (1.0.5)
faraday (~> 0.11)
google-cloud-storage (1.16.0)
digest-crc (~> 0.4)
google-api-client (~> 0.23)
google-cloud-core (~> 1.2)
googleauth (>= 0.6.2, < 0.10.0)
googleauth (0.6.7)
faraday (~> 0.12)
jwt (>= 1.4, < 3.0)
memoist (~> 0.16)
multi_json (~> 1.11)
os (>= 0.9, < 2.0)
signet (~> 0.7)
highline (1.7.10)
http-cookie (1.0.3)
domain_name (~> 0.5)
httpclient (2.8.3)
json (2.1.0)
jwt (2.1.0)
memoist (0.16.0)
mime-types (3.2.2)
mime-types-data (~> 3.2015)
mime-types-data (3.2018.0812)
mini_magick (4.5.1)
multi_json (1.13.1)
multi_xml (0.6.0)
multipart-post (2.0.0)
nanaimo (0.2.6)
naturally (2.2.0)
os (1.0.0)
plist (3.5.0)
public_suffix (2.0.5)
representable (3.0.4)
declarative (< 0.1.0)
declarative-option (< 0.2.0)
uber (< 0.2.0)
retriable (3.1.2)
rouge (2.0.7)
rubyzip (1.2.2)
security (0.1.3)
signet (0.11.0)
addressable (~> 2.3)
faraday (~> 0.9)
jwt (>= 1.5, < 3.0)
multi_json (~> 1.10)
simctl (1.6.5)
CFPropertyList
naturally
slack-notifier (2.3.2)
terminal-notifier (1.8.0)
terminal-table (1.8.0)
unicode-display_width (~> 1.1, >= 1.1.1)
tty-cursor (0.6.0)
tty-screen (0.6.5)
tty-spinner (0.9.0)
tty-cursor (~> 0.6.0)
uber (0.1.0)
unf (0.1.4)
unf_ext
unf_ext (0.0.7.5)
unicode-display_width (1.4.1)
word_wrap (1.0.0)
xcodeproj (1.8.1)
CFPropertyList (>= 2.3.3, < 4.0)
atomos (~> 0.1.3)
claide (>= 1.0.2, < 2.0)
colored2 (~> 3.1)
nanaimo (~> 0.2.6)
xcpretty (0.3.0)
rouge (~> 2.0.7)
xcpretty-travis-formatter (1.0.0)
xcpretty (~> 0.2, >= 0.0.7)
PLATFORMS
ruby
DEPENDENCIES
fastlane
BUNDLED WITH
1.16.6
# Introduction
# random
This is a template for doing Android development using GitLab and [fastlane](https://fastlane.tools/).
It is based on the tutorial for Android apps in general that can be found [here](https://developer.android.com/training/basics/firstapp/).
If you're learning Android at the same time, you can also follow along that
tutorial and learn how to do everything all at once.
# Reference links
- [GitLab CI Documentation](https://docs.gitlab.com/ee/ci/)
- [Blog post: Android publishing with GitLab and fastlane](https://about.gitlab.com/2019/01/28/android-publishing-with-gitlab-and-fastlane/)
You'll definitely want to read through the blog post since that walks you in detail
through a working production configuration using this model.
# Getting started
First thing is to follow the [Android tutorial](https://developer.android.com/training/basics/firstapp/) and
get Android Studio installed on your machine, so you can do development using
the Android IDE. Other IDE options are possible, but not directly described or
supported here. If you're using your own IDE, it should be fairly straightforward
to convert these instructions to use with your preferred toolchain.
## What's contained in this project
### Android code
The state of this project is as if you followed the first few steps in the linked
[Android tutorial](https://developer.android.com/training/basics/firstapp/) and
have created your project. You're definitely going to want to open up the
project and change the settings to match what you plan to build. In particular,
you're at least going to want to change the following:
- Application Name: "My First App"
- Company Domain: "example.com"
### Fastlane files
It also has fastlane setup per our [blog post](https://about.gitlab.com/2019/01/28/android-publishing-with-gitlab-and-fastlane/) on
getting GitLab CI set up with fastlane. Note that you may want to update your
fastlane bundle to the latest version; if a newer version is available, the pipeline
job output will tell you.
### Dockerfile build environment
In the root there is a Dockerfile which defines a build environment which will be
used to ensure consistent and reliable builds of your Android application using
the correct Android SDK and other details you expect. Feel free to add any
build-time tools or whatever else you need here.
We generate this environment as needed because installing the Android SDK
for every pipeline run would be very slow.
### Gradle configuration
The gradle configuration is exactly as output by Android Studio except for the
version name being updated to
Instead of:
`versionName "1.0"`
It is now set to:
`versionName "1.0-${System.env.VERSION_SHA}"`
You'll want to update this for whatever versioning scheme you prefer.
### Build configuration (`.gitlab-ci.yml`)
The sample project also contains a basic `.gitlab-ci.yml` which will successfully
build the Android application.
Note that for publishing to the test channels or production, you'll need to set
up your secret API key. The stub code is here for that, but please see our
[blog post](https://about.gitlab.com/2019/01/28/android-publishing-with-gitlab-and-fastlane/) for
details on how to set this up completely. In the meantime, publishing steps will fail.
The build script also handles automatic versioning by relying on the CI pipeline
ID to generate a unique, ever increasing number. If you have a different versioning
scheme you may want to change this.
```yaml
- "export VERSION_CODE=$(($CI_PIPELINE_IID)) && echo $VERSION_CODE"
- "export VERSION_SHA=`echo ${CI_COMMIT_SHA:0:8}` && echo $VERSION_SHA"
```
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id="android-template" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="java-gradle" name="Java-Gradle">
<configuration>
<option name="BUILD_FOLDER_PATH" value="$MODULE_DIR$/build" />
<option name="BUILDABLE" value="false" />
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.gradle" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
\ No newline at end of file
gradle-wrapper.jar
/.gradle
/captures/
/gradlew
/gradlew.bat
/local.properties
GeneratedPluginRegistrant.java
# Remember to never publicly share your keystore.
# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
key.properties
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader('UTF-8') { reader ->
localProperties.load(reader)
}
}
def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
}
def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
flutterVersionName = '1.0'
}
apply plugin: 'com.android.application'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android {
compileSdkVersion 30
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "org.benoitharrault.random"
minSdkVersion 16
targetSdkVersion 30
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}
buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig signingConfigs.debug
}
}
}
flutter {
source '../..'
}
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.benoitharrault.random">
<!-- Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.benoitharrault.random">
<application
android:label="random"
android:icon="@mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
<!-- Displays an Android View that continues showing the launch screen
Drawable until Flutter paints its first frame, then this splash
screen fades out. A splash screen is useful to avoid any visual
gap between the end of Android's launch screen and the painting of
Flutter's first frame. -->
<meta-data
android:name="io.flutter.embedding.android.SplashScreenDrawable"
android:resource="@drawable/launch_background"
/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application>
</manifest>
package org.benoitharrault.random;
import io.flutter.embedding.android.FlutterActivity;
public class MainActivity extends FlutterActivity {
}
<?xml version="1.0" encoding="utf-8"?>
<!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="?android:colorBackground" />
<!-- You can insert your own image assets here -->
<!-- <item>
<bitmap
android:gravity="center"
android:src="@mipmap/launch_image" />
</item> -->
</layer-list>
<?xml version="1.0" encoding="utf-8"?>
<!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@android:color/white" />
<!-- You can insert your own image assets here -->
<!-- <item>
<bitmap
android:gravity="center"
android:src="@mipmap/launch_image" />
</item> -->
</layer-list>
android/app/src/main/res/mipmap-hdpi/ic_launcher.png

1.89 KiB

android/app/src/main/res/mipmap-mdpi/ic_launcher.png

1.21 KiB

android/app/src/main/res/mipmap-xhdpi/ic_launcher.png

2.57 KiB

android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png

3.99 KiB

android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png

5.61 KiB

0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment